zman35 commited on
Commit
9026711
ยท
verified ยท
1 Parent(s): 36f047e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -228
app.py CHANGED
@@ -132,210 +132,39 @@ def equity_curve_plot(df, label="Equity Curve"):
132
  fig.update_layout(title=f"๐Ÿ“ˆ {label}", xaxis_title="Week", yaxis_title="Balance ($)", height=400)
133
  return fig
134
 
135
- import os
136
- import gradio as gr
137
- import pandas as pd
138
- import numpy as np
139
- import plotly.graph_objs as go
140
- import plotly.express as px
141
-
142
- os.environ["GRADIO_ANALYTICS_ENABLED"] = "False"
143
- try:
144
- gr.analytics_enabled = False
145
- except:
146
- pass
147
-
148
- # === STRATEGY PRESETS ===
149
- def get_strategy_presets():
150
- return {
151
- "Aggressive Prop Trader": {
152
- "starting_balance": 2500, "trades_min": 5, "trades_max": 10, "weeks": 12,
153
- "tp1_prob": 0.25, "tp2_prob": 0.4, "tp1_r": 1.2, "tp2_r": 2.4,
154
- "base_risk_pct": 0.015, "profit_target": None,
155
- "fatigue": 0.0, "trump_vol": 0.0,
156
- "description": "High-frequency, high-risk with strong upside potential."
157
- },
158
- "Conservative Swing Trader": {
159
- "starting_balance": 2500, "trades_min": 2, "trades_max": 5, "weeks": 12,
160
- "tp1_prob": 0.35, "tp2_prob": 0.25, "tp1_r": 0.9, "tp2_r": 1.8,
161
- "base_risk_pct": 0.01, "profit_target": None,
162
- "fatigue": 0.0, "trump_vol": 0.0,
163
- "description": "Lower frequency, prioritizes preservation and steady returns."
164
- },
165
- "Momentum Scalper": {
166
- "starting_balance": 2500, "trades_min": 4, "trades_max": 8, "weeks": 12,
167
- "tp1_prob": 0.3, "tp2_prob": 0.35, "tp1_r": 1.0, "tp2_r": 2.2,
168
- "base_risk_pct": 0.012, "profit_target": None,
169
- "fatigue": 0.0, "trump_vol": 0.0,
170
- "description": "Intraday momentum strategy for fast-paced trading windows."
171
- },
172
- "Swing Sniper": {
173
- "starting_balance": 2500, "trades_min": 2, "trades_max": 4, "weeks": 12,
174
- "tp1_prob": 0.2, "tp2_prob": 0.5, "tp1_r": 1.1, "tp2_r": 3.0,
175
- "base_risk_pct": 0.008, "profit_target": None,
176
- "fatigue": 0.0, "trump_vol": 0.0,
177
- "description": "Selective entries with high RR setups. Less frequent."
178
- },
179
- "Intraday Prop Mode": {
180
- "starting_balance": 2500, "trades_min": 3, "trades_max": 7, "weeks": 12,
181
- "tp1_prob": 0.3, "tp2_prob": 0.3, "tp1_r": 1.0, "tp2_r": 2.0,
182
- "base_risk_pct": 0.02, "profit_target": None,
183
- "fatigue": 0.0, "trump_vol": 0.0,
184
- "description": "Intraday consistency with a balanced reward profile."
185
- }
186
- }
187
-
188
- strategy_presets = get_strategy_presets()
189
-
190
- # === CORE SIMULATION ===
191
- def simulate_tp_strategy_full(starting_balance, trades_min, trades_max, weeks,
192
- tp1_prob, tp2_prob, tp1_r, tp2_r, base_risk_pct,
193
- profit_target=None, fatigue=0.0, trump_vol=0.0):
194
- if tp1_prob + tp2_prob >= 1.0:
195
- return pd.DataFrame(), {"Error": "Invalid probability config. TP1 + TP2 must be < 1.0"}
196
-
197
- sl_prob = 1.0 - tp1_prob - tp2_prob
198
- balance, peak, drawdown = starting_balance, starting_balance, 0
199
- tp1_hits = tp2_hits = sl_hits = 0
200
- max_win_streak = max_loss_streak = cur_win_streak = cur_loss_streak = 0
201
- fatigue_multiplier = 1.0 - fatigue * 0.4
202
- trump_vol_factor = np.random.normal(1.0, 0.2 * trump_vol)
203
- log = []
204
-
205
- for week in range(1, weeks + 1):
206
- if profit_target and balance >= profit_target: break
207
- week_start = balance
208
- num_trades = np.random.randint(trades_min, trades_max + 1)
209
-
210
- for _ in range(num_trades):
211
- risk_amount = balance * base_risk_pct * np.random.uniform(0.9, 1.1)
212
- risk_amount *= trump_vol_factor
213
- if fatigue > 0.6 and cur_loss_streak >= 3 and np.random.rand() < fatigue * 0.25:
214
- outcome = "SL"
215
- else:
216
- outcome = np.random.choice(["TP1", "TP2", "SL"], p=[tp1_prob, tp2_prob, sl_prob])
217
-
218
- if outcome == "TP1":
219
- balance += risk_amount * tp1_r * fatigue_multiplier
220
- tp1_hits += 1
221
- cur_win_streak += 1
222
- cur_loss_streak = 0
223
- elif outcome == "TP2":
224
- balance += risk_amount * tp2_r * fatigue_multiplier
225
- tp2_hits += 1
226
- cur_win_streak += 1
227
- cur_loss_streak = 0
228
- else:
229
- balance -= risk_amount
230
- sl_hits += 1
231
- cur_loss_streak += 1
232
- cur_win_streak = 0
233
-
234
- max_win_streak = max(max_win_streak, cur_win_streak)
235
- max_loss_streak = max(max_loss_streak, cur_loss_streak)
236
- peak = max(peak, balance)
237
- drawdown = max(drawdown, (peak - balance) / peak * 100)
238
-
239
- log.append({
240
- "Week": week, "Start Balance": round(week_start, 2),
241
- "End Balance": round(balance, 2),
242
- "Weekly Return (%)": round((balance - week_start) / week_start * 100, 2)
243
- })
244
-
245
- df = pd.DataFrame(log)
246
- returns = df["End Balance"].pct_change().dropna()
247
- sharpe = returns.mean() / returns.std() * np.sqrt(52) if returns.std() > 0 else 0
248
- score = balance / (1 + drawdown)
249
- summary = {
250
- "Final Balance": round(balance, 2),
251
- "TP1 Hits": tp1_hits,
252
- "TP2 Hits": tp2_hits,
253
- "SL Hits": sl_hits,
254
- "Max Drawdown %": round(drawdown, 2),
255
- "Max Win Streak": max_win_streak,
256
- "Max Loss Streak": max_loss_streak,
257
- "Sharpe Ratio": round(sharpe, 2),
258
- "EdgeCast Score": round(score, 2)
259
- }
260
- return df, summary
261
-
262
- # === VISUALIZATION ===
263
- def equity_curve_plot(df, label="Equity Curve"):
264
- fig = go.Figure()
265
- fig.add_trace(go.Scatter(x=df["Week"], y=df["End Balance"], mode="lines+markers", name=label))
266
- fig.update_layout(title=f"๐Ÿ“ˆ {label}", xaxis_title="Week", yaxis_title="Balance ($)", height=400)
267
- return fig
268
-
269
- def generate_histogram(metric="EdgeCast Score", runs=100):
270
  all_metrics = []
271
  for name, config in strategy_presets.items():
272
- for _ in range(runs):
273
- _, summary = simulate_tp_strategy_full(
274
- config["starting_balance"], config["trades_min"], config["trades_max"], config["weeks"],
275
- config["tp1_prob"], config["tp2_prob"], config["tp1_r"], config["tp2_r"],
276
- config["base_risk_pct"], config["profit_target"], config["fatigue"], config["trump_vol"]
277
- )
278
- if metric in summary:
279
- all_metrics.append({
280
- "Strategy": name,
281
- metric: summary[metric]
282
- })
283
 
284
  df = pd.DataFrame(all_metrics)
285
 
286
- fig = px.histogram(
 
287
  df,
288
- x=metric,
 
289
  color="Strategy",
290
- marginal="box",
291
- opacity=0.75,
292
- barmode="overlay",
293
- nbins=30,
294
- title=f"๐Ÿ“Š Distribution of {metric} Across Strategies"
295
  )
296
 
297
  fig.update_layout(
298
- xaxis_title=metric,
299
- yaxis_title="Count",
300
- bargap=0.1,
301
  height=500
302
  )
303
-
304
- return fig
305
-
306
-
307
- def histogram_viewer_ui(metric):
308
- return generate_histogram(metric)
309
-
310
- # === ANALYSIS TOOLS ===
311
- def analytics_dashboard(rank_by="EdgeCast Score"):
312
- results = []
313
- for name, config in strategy_presets.items():
314
- _, summary = simulate_tp_strategy_full(**{k: v for k, v in config.items() if k != "description"})
315
- summary["Strategy"] = name
316
- results.append(summary)
317
- df = pd.DataFrame(results)
318
- winner_vals = {
319
- "Final Balance": df["Final Balance"].max(),
320
- "Sharpe Ratio": df["Sharpe Ratio"].max(),
321
- "EdgeCast Score": df["EdgeCast Score"].max(),
322
- "Max Drawdown %": df["Max Drawdown %"].min()
323
- }
324
- df = df.sort_values(rank_by, ascending=(rank_by == "Max Drawdown %")).reset_index(drop=True)
325
- df.insert(0, "๐Ÿ… Rank", [f"#{i+1}" for i in df.index])
326
- for col in winner_vals:
327
- df[col] = df[col].apply(lambda x: f"{round(x,2)} ๐Ÿ†" if x == winner_vals[col] else f"{round(x,2)}")
328
- return df[["๐Ÿ… Rank", "Strategy", "Final Balance", "Sharpe Ratio", "EdgeCast Score", "Max Drawdown %"]]
329
-
330
- def show_descriptions():
331
- return pd.DataFrame([{"Strategy": name, "Description": cfg["description"]} for name, cfg in strategy_presets.items()])
332
-
333
- def generate_risk_matrix():
334
- names = list(strategy_presets.keys())
335
- scores = {n: simulate_tp_strategy_full(**{k: v for k, v in cfg.items() if k != "description"})[1]["EdgeCast Score"] for n, cfg in strategy_presets.items()}
336
- matrix = np.array([[abs(scores[a] - scores[b]) for b in names] for a in names])
337
- fig = px.imshow(matrix, x=names, y=names, text_auto=".2f", color_continuous_scale="RdYlGn_r", labels={"color": "ฮ” Score"})
338
- fig.update_layout(title="๐Ÿง  Risk Matrix (Score ฮ”)", height=600)
339
  return fig
340
 
341
  # === STRATEGY RUNNERS ===
@@ -375,41 +204,6 @@ def dual_manual_battle(
375
  fig.update_layout(title="โš”๏ธ Manual Strategy Battle", xaxis_title="Week", yaxis_title="Balance")
376
  return df_summary, fig
377
 
378
- def get_manual_battle_interface():
379
- return gr.Interface(
380
- fn=dual_manual_battle,
381
- inputs=[
382
- # A Config
383
- gr.Slider(100, 20000, 2500, label="A: Start Balance"),
384
- gr.Slider(1, 10, 3, label="A: Trades Min"),
385
- gr.Slider(1, 15, 7, label="A: Trades Max"),
386
- gr.Slider(1, 52, 12, label="A: Weeks"),
387
- gr.Slider(0, 1, 0.3, step=0.05, label="A: TP1 %"),
388
- gr.Slider(0, 1, 0.3, step=0.05, label="A: TP2 %"),
389
- gr.Slider(0.1, 5.0, 1.0, step=0.1, label="A: TP1 R"),
390
- gr.Slider(0.1, 20.0, 2.0, step=0.1, label="A: TP2 R"),
391
- gr.Slider(0.001, 0.05, 0.01, step=0.001, label="A: Risk %"),
392
- gr.Slider(0, 100000, 0, step=500, label="A: Profit Target"),
393
- gr.Slider(0, 1, 0.0, step=0.1, label="A: Fatigue"),
394
- gr.Slider(0, 1, 0.0, step=0.1, label="A: Trump Volatility"),
395
- # B Config
396
- gr.Slider(100, 20000, 2500, label="B: Start Balance"),
397
- gr.Slider(1, 10, 3, label="B: Trades Min"),
398
- gr.Slider(1, 15, 7, label="B: Trades Max"),
399
- gr.Slider(1, 52, 12, label="B: Weeks"),
400
- gr.Slider(0, 1, 0.3, step=0.05, label="B: TP1 %"),
401
- gr.Slider(0, 1, 0.3, step=0.05, label="B: TP2 %"),
402
- gr.Slider(0.1, 5.0, 1.0, step=0.1, label="B: TP1 R"),
403
- gr.Slider(0.1, 20.0, 2.0, step=0.1, label="B: TP2 R"),
404
- gr.Slider(0.001, 0.05, 0.01, step=0.001, label="B: Risk %"),
405
- gr.Slider(0, 100000, 0, step=500, label="B: Profit Target"),
406
- gr.Slider(0, 1, 0.0, step=0.1, label="B: Fatigue"),
407
- gr.Slider(0, 1, 0.0, step=0.1, label="B: Trump Volatility")
408
- ],
409
- outputs=["dataframe", gr.Plot()],
410
- title="๐Ÿงช Manual Strategy Battle"
411
- )
412
-
413
  # === LAUNCH INTERFACE ===
414
  app = gr.TabbedInterface(
415
  interface_list=[
@@ -452,7 +246,7 @@ app = gr.TabbedInterface(
452
 
453
  # ๐Ÿ“Š Line Graph Viewer Tab
454
  gr.Interface(
455
- fn=histogram_viewer_ui,
456
  inputs=gr.Dropdown(
457
  choices=["Final Balance", "Sharpe Ratio", "EdgeCast Score", "Max Drawdown %"],
458
  label="Select Metric"
 
132
  fig.update_layout(title=f"๐Ÿ“ˆ {label}", xaxis_title="Week", yaxis_title="Balance ($)", height=400)
133
  return fig
134
 
135
+ # === LINE GRAPH ===
136
+ def line_graph_viewer_ui(metric="Final Balance"):
137
+ # Generate data for the line graph based on the selected metric
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  all_metrics = []
139
  for name, config in strategy_presets.items():
140
+ _, summary = simulate_tp_strategy_full(
141
+ config["starting_balance"], config["trades_min"], config["trades_max"], config["weeks"],
142
+ config["tp1_prob"], config["tp2_prob"], config["tp1_r"], config["tp2_r"],
143
+ config["base_risk_pct"], config["profit_target"], config["fatigue"], config["trump_vol"]
144
+ )
145
+ if metric in summary:
146
+ all_metrics.append({
147
+ "Strategy": name,
148
+ metric: summary[metric]
149
+ })
 
150
 
151
  df = pd.DataFrame(all_metrics)
152
 
153
+ # Generate a line graph of the selected metric
154
+ fig = px.line(
155
  df,
156
+ x="Strategy",
157
+ y=metric,
158
  color="Strategy",
159
+ title=f"๐Ÿ“Š Line Graph of {metric}",
160
+ labels={metric: f"{metric}"}
 
 
 
161
  )
162
 
163
  fig.update_layout(
164
+ xaxis_title="Strategy",
165
+ yaxis_title=metric,
 
166
  height=500
167
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  return fig
169
 
170
  # === STRATEGY RUNNERS ===
 
204
  fig.update_layout(title="โš”๏ธ Manual Strategy Battle", xaxis_title="Week", yaxis_title="Balance")
205
  return df_summary, fig
206
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  # === LAUNCH INTERFACE ===
208
  app = gr.TabbedInterface(
209
  interface_list=[
 
246
 
247
  # ๐Ÿ“Š Line Graph Viewer Tab
248
  gr.Interface(
249
+ fn=line_graph_viewer_ui,
250
  inputs=gr.Dropdown(
251
  choices=["Final Balance", "Sharpe Ratio", "EdgeCast Score", "Max Drawdown %"],
252
  label="Select Metric"