zman35 commited on
Commit
b2fc8cf
Β·
verified Β·
1 Parent(s): 3e25330

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +181 -129
app.py CHANGED
@@ -7,8 +7,10 @@ import plotly.express as px
7
 
8
  # Disable Gradio analytics
9
  os.environ["GRADIO_ANALYTICS_ENABLED"] = "False"
10
- try: gr.analytics_enabled = False
11
- except: pass
 
 
12
 
13
  # Strategy Presets
14
  strategy_presets = {
@@ -53,161 +55,211 @@ def get_scaled_risk_pct(balance, base_risk_pct):
53
  def simulate_tp_strategy_full(starting_balance, trades_min, trades_max, weeks,
54
  tp1_prob, tp2_prob, tp1_r, tp2_r, base_risk_pct,
55
  profit_target=None):
56
- try:
57
- sl_prob = 1.0 - tp1_prob - tp2_prob
58
- balance = starting_balance
59
- peak = balance
60
- drawdown = 0
61
- tp1_hits = tp2_hits = sl_hits = 0
62
- max_win_streak = max_loss_streak = 0
63
- cur_win_streak = cur_loss_streak = 0
64
- log = []
65
-
66
- for week in range(1, weeks + 1):
67
- if profit_target and balance >= profit_target: break
68
- week_start = balance
69
- num_trades = np.random.randint(trades_min, trades_max + 1)
70
- for _ in range(num_trades):
71
- risk_pct = get_scaled_risk_pct(balance, base_risk_pct)
72
- risk_amount = balance * risk_pct
73
- outcome = np.random.choice(["TP1", "TP2", "SL"], p=[tp1_prob, tp2_prob, sl_prob])
74
- if outcome == "TP1":
75
- balance += risk_amount * tp1_r
76
- tp1_hits += 1
77
- cur_win_streak += 1
78
- cur_loss_streak = 0
79
- elif outcome == "TP2":
80
- balance += risk_amount * tp2_r
81
- tp2_hits += 1
82
- cur_win_streak += 1
83
- cur_loss_streak = 0
84
- else:
85
- balance -= risk_amount
86
- sl_hits += 1
87
- cur_loss_streak += 1
88
- cur_win_streak = 0
89
- max_win_streak = max(max_win_streak, cur_win_streak)
90
- max_loss_streak = max(max_loss_streak, cur_loss_streak)
91
- peak = max(peak, balance)
92
- drawdown = max(drawdown, (peak - balance) / peak * 100)
93
- weekly_return = (balance - week_start) / week_start * 100
94
- log.append({
95
- "Week": week,
96
- "Start Balance": round(week_start, 2),
97
- "End Balance": round(balance, 2),
98
- "Weekly Return (%)": round(weekly_return, 2)
99
- })
100
-
101
- df = pd.DataFrame(log)
102
- returns = df["End Balance"].pct_change().dropna()
103
- volatility = returns.std() * np.sqrt(52)
104
- sharpe = returns.mean() / volatility * np.sqrt(52) if volatility > 0 else 0
105
- score = balance / (1 + drawdown)
106
-
107
- summary = {
108
- "Final Balance": round(balance, 2),
109
- "TP1 Hits": tp1_hits,
110
- "TP2 Hits": tp2_hits,
111
- "SL Hits": sl_hits,
112
- "Max Drawdown %": round(drawdown, 2),
113
- "Max Win Streak": max_win_streak,
114
- "Max Loss Streak": max_loss_streak,
115
- "Sharpe Ratio": round(sharpe, 2),
116
- "EdgeCast Score": round(score, 2)
117
- }
118
- return df, summary
119
- except Exception as e:
120
- return pd.DataFrame(), {"Error": str(e)}
121
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  def run_preset_strategy(style):
123
  config = strategy_presets[style]
124
- df, summary = simulate_tp_strategy_full(**{k: config[k] for k in config if k not in ["description"]})
 
 
 
 
125
  return df, summary, config["description"]
126
 
 
127
  def battle_strategies(style1, style2):
128
  df1, s1 = simulate_tp_strategy_full(**strategy_presets[style1])
129
  df2, s2 = simulate_tp_strategy_full(**strategy_presets[style2])
130
  s1["Strategy"] = style1
131
  s2["Strategy"] = style2
132
  df_compare = pd.DataFrame([s1, s2])
133
- winner = df_compare.loc[df_compare["EdgeCast Score"].idxmax(), "Strategy"]
 
 
 
 
 
134
 
 
 
 
 
 
 
 
 
135
  fig = go.Figure()
136
- fig.add_trace(go.Scatter(x=df1["Week"], y=df1["End Balance"], name=f"{style1} (Sharpe: {s1['Sharpe Ratio']})"))
137
- fig.add_trace(go.Scatter(x=df2["Week"], y=df2["End Balance"], name=f"{style2} (Sharpe: {s2['Sharpe Ratio']})"))
138
- fig.update_layout(title=f"Strategy Battle – Sharpe Comparison", xaxis_title="Week", yaxis_title="Balance")
 
139
 
140
- df_compare["πŸ† Winner"] = df_compare["Strategy"] == winner
141
- return df_compare, fig
142
 
 
143
  def analytics_dashboard():
144
  rows = []
145
  for name, config in strategy_presets.items():
146
  _, s = simulate_tp_strategy_full(**config)
147
  s["Strategy"] = name
148
  rows.append(s)
149
- return pd.DataFrame(rows).sort_values("EdgeCast Score", ascending=False).reset_index(drop=True)
 
150
 
 
151
  def show_descriptions():
152
- return pd.DataFrame([
153
- {"Strategy": k, "Description": v["description"]}
154
- for k, v in strategy_presets.items()
155
- ])
156
-
157
  def generate_risk_matrix():
158
- strategies = list(strategy_presets.keys())
159
  scores = {}
160
- for strat in strategies:
161
- _, s = simulate_tp_strategy_full(**strategy_presets[strat])
162
- scores[strat] = s["EdgeCast Score"]
163
- matrix = np.zeros((len(strategies), len(strategies)))
164
- for i, a in enumerate(strategies):
165
- for j, b in enumerate(strategies):
166
- matrix[i, j] = abs(scores[a] - scores[b])
167
- fig = px.imshow(matrix, x=strategies, y=strategies, color_continuous_scale="RdYlGn_r",
168
- text_auto=".2f", labels=dict(color="Ξ” Score"))
169
- fig.update_traces(hovertemplate="Ξ” = %{z:.2f} between %{x} and %{y}")
170
- fig.update_layout(title="🧠 Risk Matrix (Ξ” Score Heatmap)", height=500)
 
 
 
 
 
 
 
171
  return fig
172
 
173
- # πŸš€ Launch App
174
- gr.TabbedInterface(
175
  interface_list=[
176
- gr.Interface(fn=run_preset_strategy,
177
- inputs=gr.Dropdown(choices=list(strategy_presets.keys()), label="Select Strategy"),
178
- outputs=["dataframe", "json", "text"],
179
- title="🎯 Preset Mode"),
180
-
181
- gr.Interface(fn=simulate_tp_strategy_full,
182
- inputs=[
183
- gr.Slider(100, 20000, 2500, label="Start Balance"),
184
- gr.Slider(1, 10, 3, label="Trades Min"),
185
- gr.Slider(1, 15, 7, label="Trades Max"),
186
- gr.Slider(1, 52, 12, label="Weeks"),
187
- gr.Slider(0, 1, 0.3, step=0.05, label="TP1 %"),
188
- gr.Slider(0, 1, 0.3, step=0.05, label="TP2 %"),
189
- gr.Slider(0.1, 20.0, 1.0, step=0.1, label="TP1 R (Risk:Reward)"),
190
- gr.Slider(0.1, 20.0, 2.0, step=0.1, label="TP2 R (Risk:Reward)"),
191
- gr.Slider(0.001, 0.05, 0.01, step=0.001, label="Risk %"),
192
- gr.Slider(0, 100000, 0, step=500, label="Profit Target πŸ’°")
193
- ],
194
- outputs=["dataframe", "json"],
195
- title="πŸ› οΈ Manual Config"),
196
-
197
- gr.Interface(fn=battle_strategies,
198
- inputs=[
199
- gr.Dropdown(choices=list(strategy_presets.keys()), label="Strategy 1"),
200
- gr.Dropdown(choices=list(strategy_presets.keys()), label="Strategy 2")
201
- ],
202
- outputs=["dataframe", gr.Plot()],
203
- title="πŸ₯Š Battle Mode"),
204
-
205
- gr.Interface(fn=analytics_dashboard, inputs=[], outputs="dataframe", title="πŸ“Š Analytics"),
206
-
207
- gr.Interface(fn=show_descriptions, inputs=[], outputs="dataframe", title="πŸ“˜ Descriptions"),
208
-
209
- gr.Interface(fn=generate_risk_matrix, inputs=[], outputs=gr.Plot(), title="πŸ”¬ Risk Matrix")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  ],
211
  tab_names=["Preset", "Manual", "Battle", "Analytics", "Descriptions", "Risk Matrix"],
212
  title="EdgeCast – Strategy Simulation Suite"
213
- ).launch()
 
 
 
 
7
 
8
  # Disable Gradio analytics
9
  os.environ["GRADIO_ANALYTICS_ENABLED"] = "False"
10
+ try:
11
+ gr.analytics_enabled = False
12
+ except:
13
+ pass
14
 
15
  # Strategy Presets
16
  strategy_presets = {
 
55
  def simulate_tp_strategy_full(starting_balance, trades_min, trades_max, weeks,
56
  tp1_prob, tp2_prob, tp1_r, tp2_r, base_risk_pct,
57
  profit_target=None):
58
+ sl_prob = 1.0 - tp1_prob - tp2_prob
59
+ balance = starting_balance
60
+ peak = balance
61
+ drawdown = 0
62
+ tp1_hits = tp2_hits = sl_hits = 0
63
+ max_win_streak = max_loss_streak = 0
64
+ cur_win_streak = cur_loss_streak = 0
65
+ log = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
+ for week in range(1, weeks + 1):
68
+ if profit_target and balance >= profit_target: break
69
+ week_start = balance
70
+ num_trades = np.random.randint(trades_min, trades_max + 1)
71
+ for _ in range(num_trades):
72
+ risk_pct = get_scaled_risk_pct(balance, base_risk_pct)
73
+ risk_amount = balance * risk_pct
74
+ outcome = np.random.choice(["TP1", "TP2", "SL"], p=[tp1_prob, tp2_prob, sl_prob])
75
+ if outcome == "TP1":
76
+ balance += risk_amount * tp1_r
77
+ tp1_hits += 1
78
+ cur_win_streak += 1
79
+ cur_loss_streak = 0
80
+ elif outcome == "TP2":
81
+ balance += risk_amount * tp2_r
82
+ tp2_hits += 1
83
+ cur_win_streak += 1
84
+ cur_loss_streak = 0
85
+ else:
86
+ balance -= risk_amount
87
+ sl_hits += 1
88
+ cur_loss_streak += 1
89
+ cur_win_streak = 0
90
+ max_win_streak = max(max_win_streak, cur_win_streak)
91
+ max_loss_streak = max(max_loss_streak, cur_loss_streak)
92
+ peak = max(peak, balance)
93
+ drawdown = max(drawdown, (peak - balance) / peak * 100)
94
+ weekly_return = (balance - week_start) / week_start * 100
95
+ log.append({"Week": week, "Start Balance": round(week_start, 2),
96
+ "End Balance": round(balance, 2), "Weekly Return (%)": round(weekly_return, 2)})
97
+
98
+ df = pd.DataFrame(log)
99
+ returns = df["End Balance"].pct_change().dropna()
100
+ volatility = returns.std() * np.sqrt(52)
101
+ sharpe_ratio = returns.mean() / returns.std() * np.sqrt(52) if returns.std() > 0 else 0
102
+ score = balance / (1 + drawdown)
103
+
104
+ summary = {
105
+ "Final Balance": round(balance, 2),
106
+ "TP1 Hits": tp1_hits,
107
+ "TP2 Hits": tp2_hits,
108
+ "SL Hits": sl_hits,
109
+ "Max Drawdown %": round(drawdown, 2),
110
+ "Max Win Streak": max_win_streak,
111
+ "Max Loss Streak": max_loss_streak,
112
+ "Sharpe Ratio": round(sharpe_ratio, 2),
113
+ "EdgeCast Score": round(score, 2)
114
+ }
115
+ return df, summary
116
+ # Run preset from dropdown
117
  def run_preset_strategy(style):
118
  config = strategy_presets[style]
119
+ df, summary = simulate_tp_strategy_full(
120
+ config["starting_balance"], config["trades_min"], config["trades_max"],
121
+ config["weeks"], config["tp1_prob"], config["tp2_prob"],
122
+ config["tp1_r"], config["tp2_r"], config["base_risk_pct"], config["profit_target"]
123
+ )
124
  return df, summary, config["description"]
125
 
126
+ # Battle mode comparison
127
  def battle_strategies(style1, style2):
128
  df1, s1 = simulate_tp_strategy_full(**strategy_presets[style1])
129
  df2, s2 = simulate_tp_strategy_full(**strategy_presets[style2])
130
  s1["Strategy"] = style1
131
  s2["Strategy"] = style2
132
  df_compare = pd.DataFrame([s1, s2])
133
+ df_compare = df_compare[["Strategy"] + [col for col in s1 if col != "Strategy"]]
134
+
135
+ # Determine winners
136
+ edgecast_winner = df_compare.loc[df_compare["EdgeCast Score"].idxmax(), "Strategy"]
137
+ sharpe_winner = df_compare.loc[df_compare["Sharpe Ratio"].idxmax(), "Strategy"]
138
+ pnl_winner = df_compare.loc[df_compare["Final Balance"].idxmax(), "Strategy"]
139
 
140
+ # Bold + highlight the winners
141
+ def highlight(row):
142
+ style = []
143
+ if row["Strategy"] == edgecast_winner: style.append("background-color: #d4edda; font-weight: bold")
144
+ else: style.append("")
145
+ return style * len(row)
146
+
147
+ # Chart
148
  fig = go.Figure()
149
+ fig.add_trace(go.Scatter(x=df1["Week"], y=df1["End Balance"], name=f"{style1}"))
150
+ fig.add_trace(go.Scatter(x=df2["Week"], y=df2["End Balance"], name=f"{style2}"))
151
+ fig.update_layout(title=f"πŸ“Š Battle – πŸ† {edgecast_winner} (Best EdgeCast Score)",
152
+ xaxis_title="Week", yaxis_title="Balance")
153
 
154
+ return df_compare.style.apply(highlight, axis=1), fig
 
155
 
156
+ # Analytics leaderboard
157
  def analytics_dashboard():
158
  rows = []
159
  for name, config in strategy_presets.items():
160
  _, s = simulate_tp_strategy_full(**config)
161
  s["Strategy"] = name
162
  rows.append(s)
163
+ df = pd.DataFrame(rows)
164
+ return df.sort_values("EdgeCast Score", ascending=False).reset_index(drop=True)
165
 
166
+ # Show strategy descriptions
167
  def show_descriptions():
168
+ descs = [{"Strategy": k, "Description": v["description"]} for k, v in strategy_presets.items()]
169
+ return pd.DataFrame(descs)
170
+ # Risk Matrix Heatmap tab
 
 
171
  def generate_risk_matrix():
172
+ strat_names = list(strategy_presets.keys())
173
  scores = {}
174
+ for name in strat_names:
175
+ _, s = simulate_tp_strategy_full(**strategy_presets[name])
176
+ scores[name] = s["EdgeCast Score"]
177
+
178
+ heatmap_data = np.zeros((len(strat_names), len(strat_names)))
179
+ for i, a in enumerate(strat_names):
180
+ for j, b in enumerate(strat_names):
181
+ heatmap_data[i, j] = abs(scores[a] - scores[b])
182
+
183
+ fig = px.imshow(
184
+ heatmap_data,
185
+ x=strat_names,
186
+ y=strat_names,
187
+ color_continuous_scale="RdYlGn_r",
188
+ labels=dict(color="Score Ξ”"),
189
+ title="🧠 Risk Matrix – Strategy Divergence"
190
+ )
191
+ fig.update_traces(hovertemplate="From %{y} β†’ %{x}: Ξ”=%{z}<extra></extra>")
192
  return fig
193
 
194
+ # Build the app
195
+ app = gr.TabbedInterface(
196
  interface_list=[
197
+
198
+ # Preset Tab
199
+ gr.Interface(
200
+ fn=run_preset_strategy,
201
+ inputs=gr.Dropdown(choices=list(strategy_presets.keys()), label="Select Strategy"),
202
+ outputs=["dataframe", "json", "text"],
203
+ title="🎯 Preset Mode"
204
+ ),
205
+
206
+ # Manual Tab with 20:1 RR
207
+ gr.Interface(
208
+ fn=simulate_tp_strategy_full,
209
+ inputs=[
210
+ gr.Slider(100, 20000, 2500, label="Start Balance"),
211
+ gr.Slider(1, 10, 3, label="Trades Min"),
212
+ gr.Slider(1, 15, 7, label="Trades Max"),
213
+ gr.Slider(1, 52, 12, label="Weeks"),
214
+ gr.Slider(0, 1, 0.3, step=0.05, label="TP1 %"),
215
+ gr.Slider(0, 1, 0.3, step=0.05, label="TP2 %"),
216
+ gr.Slider(0.1, 20.0, 1.0, step=0.1, label="TP1 R"),
217
+ gr.Slider(0.1, 40.0, 2.0, step=0.1, label="TP2 R"),
218
+ gr.Slider(0.001, 0.05, 0.01, step=0.001, label="Risk %"),
219
+ gr.Slider(0, 100000, 0, step=500, label="Profit Target πŸ’°")
220
+ ],
221
+ outputs=["dataframe", "json"],
222
+ title="πŸ› οΈ Manual Config"
223
+ ),
224
+
225
+ # Battle Tab
226
+ gr.Interface(
227
+ fn=battle_strategies,
228
+ inputs=[
229
+ gr.Dropdown(choices=list(strategy_presets.keys()), label="Strategy 1"),
230
+ gr.Dropdown(choices=list(strategy_presets.keys()), label="Strategy 2")
231
+ ],
232
+ outputs=["dataframe", gr.Plot()],
233
+ title="πŸ₯Š Battle Mode"
234
+ ),
235
+
236
+ # Analytics Leaderboard Tab
237
+ gr.Interface(
238
+ fn=analytics_dashboard,
239
+ inputs=[],
240
+ outputs="dataframe",
241
+ title="πŸ“Š Analytics Leaderboard"
242
+ ),
243
+
244
+ # Strategy Descriptions Tab
245
+ gr.Interface(
246
+ fn=show_descriptions,
247
+ inputs=[],
248
+ outputs="dataframe",
249
+ title="πŸ“˜ Strategy Descriptions"
250
+ ),
251
+
252
+ # Risk Matrix Tab
253
+ gr.Interface(
254
+ fn=generate_risk_matrix,
255
+ inputs=[],
256
+ outputs=gr.Plot(),
257
+ title="πŸ”¬ Risk Matrix"
258
+ )
259
  ],
260
  tab_names=["Preset", "Manual", "Battle", "Analytics", "Descriptions", "Risk Matrix"],
261
  title="EdgeCast – Strategy Simulation Suite"
262
+ )
263
+
264
+ # πŸš€ Launch the app
265
+ app.launch()