zman35 commited on
Commit
7aba869
Β·
verified Β·
1 Parent(s): bcbbaf8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +235 -59
app.py CHANGED
@@ -1,64 +1,240 @@
1
  import gradio as gr
2
- from huggingface_hub import InferenceClient
3
-
4
- """
5
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
6
- """
7
- client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
8
-
9
-
10
- def respond(
11
- message,
12
- history: list[tuple[str, str]],
13
- system_message,
14
- max_tokens,
15
- temperature,
16
- top_p,
17
- ):
18
- messages = [{"role": "system", "content": system_message}]
19
-
20
- for val in history:
21
- if val[0]:
22
- messages.append({"role": "user", "content": val[0]})
23
- if val[1]:
24
- messages.append({"role": "assistant", "content": val[1]})
25
-
26
- messages.append({"role": "user", "content": message})
27
-
28
- response = ""
29
-
30
- for message in client.chat_completion(
31
- messages,
32
- max_tokens=max_tokens,
33
- stream=True,
34
- temperature=temperature,
35
- top_p=top_p,
36
- ):
37
- token = message.choices[0].delta.content
38
-
39
- response += token
40
- yield response
41
-
42
-
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- demo = gr.ChatInterface(
47
- respond,
48
- additional_inputs=[
49
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
50
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
51
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
52
- gr.Slider(
53
- minimum=0.1,
54
- maximum=1.0,
55
- value=0.95,
56
- step=0.05,
57
- label="Top-p (nucleus sampling)",
58
- ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  ],
 
 
60
  )
61
 
 
 
 
 
 
 
 
 
62
 
63
- if __name__ == "__main__":
64
- demo.launch()
 
1
  import gradio as gr
2
+ import pandas as pd
3
+ import matplotlib.pyplot as plt
4
+ import numpy as np
5
+
6
+ # πŸ“Œ Strategy Presets
7
+ strategy_presets = {
8
+ "Aggressive Prop Trader": {
9
+ "starting_balance": 2500, "trades_min": 5, "trades_max": 10, "weeks": 12,
10
+ "tp1_prob": 0.25, "tp2_prob": 0.4, "tp1_r": 1.2, "tp2_r": 2.4, "base_risk_pct": 0.015, "profit_target": None
11
+ },
12
+ "Conservative Swing Trader": {
13
+ "starting_balance": 2500, "trades_min": 2, "trades_max": 5, "weeks": 12,
14
+ "tp1_prob": 0.35, "tp2_prob": 0.25, "tp1_r": 0.9, "tp2_r": 1.8, "base_risk_pct": 0.01, "profit_target": None
15
+ },
16
+ "Momentum Scalper": {
17
+ "starting_balance": 2500, "trades_min": 4, "trades_max": 8, "weeks": 12,
18
+ "tp1_prob": 0.3, "tp2_prob": 0.35, "tp1_r": 1.0, "tp2_r": 2.2, "base_risk_pct": 0.012, "profit_target": None
19
+ },
20
+ "Swing Sniper": {
21
+ "starting_balance": 2500, "trades_min": 2, "trades_max": 4, "weeks": 12,
22
+ "tp1_prob": 0.2, "tp2_prob": 0.5, "tp1_r": 1.1, "tp2_r": 3.0, "base_risk_pct": 0.008, "profit_target": None
23
+ },
24
+ "Intraday Prop Mode": {
25
+ "starting_balance": 2500, "trades_min": 3, "trades_max": 7, "weeks": 12,
26
+ "tp1_prob": 0.3, "tp2_prob": 0.3, "tp1_r": 1.0, "tp2_r": 2.0, "base_risk_pct": 0.02, "profit_target": None
27
+ }
28
+ }
29
+
30
+ # πŸ” Simulation Function
31
+ def get_scaled_risk_pct(balance, base_risk_pct):
32
+ if balance < 5000: return base_risk_pct
33
+ elif balance < 10000: return base_risk_pct * 0.75
34
+ elif balance < 20000: return base_risk_pct * 0.5
35
+ else: return base_risk_pct * 0.25
36
+
37
+ def simulate_tp_strategy_full(starting_balance, trades_min, trades_max, weeks,
38
+ tp1_prob, tp2_prob, tp1_r, tp2_r, base_risk_pct,
39
+ profit_target=None):
40
+ sl_prob = 1.0 - tp1_prob - tp2_prob
41
+ balance = starting_balance
42
+ peak = balance
43
+ drawdown = 0
44
+ tp1_hits = tp2_hits = sl_hits = 0
45
+ max_win_streak = max_loss_streak = 0
46
+ cur_win_streak = cur_loss_streak = 0
47
+ log = []
48
+
49
+ for week in range(1, weeks + 1):
50
+ if profit_target and balance >= profit_target:
51
+ break
52
+ week_start = balance
53
+ num_trades = np.random.randint(trades_min, trades_max + 1)
54
+ for _ in range(num_trades):
55
+ risk_pct = get_scaled_risk_pct(balance, base_risk_pct)
56
+ risk_amount = balance * risk_pct
57
+ outcome = np.random.choice(["TP1", "TP2", "SL"], p=[tp1_prob, tp2_prob, sl_prob])
58
+ if outcome == "TP1":
59
+ balance += risk_amount * tp1_r
60
+ tp1_hits += 1
61
+ cur_win_streak += 1
62
+ cur_loss_streak = 0
63
+ elif outcome == "TP2":
64
+ balance += risk_amount * tp2_r
65
+ tp2_hits += 1
66
+ cur_win_streak += 1
67
+ cur_loss_streak = 0
68
+ else:
69
+ balance -= risk_amount
70
+ sl_hits += 1
71
+ cur_loss_streak += 1
72
+ cur_win_streak = 0
73
+ max_win_streak = max(max_win_streak, cur_win_streak)
74
+ max_loss_streak = max(max_loss_streak, cur_loss_streak)
75
+ peak = max(peak, balance)
76
+ drawdown = max(drawdown, (peak - balance) / peak * 100)
77
+ weekly_return = (balance - week_start) / week_start * 100
78
+ log.append({
79
+ "Week": week,
80
+ "Start Balance": round(week_start, 2),
81
+ "End Balance": round(balance, 2),
82
+ "Weekly Return (%)": round(weekly_return, 2)
83
+ })
84
+
85
+ summary = {
86
+ "Final Balance": round(balance, 2),
87
+ "TP1 Hits": tp1_hits,
88
+ "TP2 Hits": tp2_hits,
89
+ "SL Hits": sl_hits,
90
+ "Max Drawdown %": round(drawdown, 2),
91
+ "Max Win Streak": max_win_streak,
92
+ "Max Loss Streak": max_loss_streak
93
+ }
94
+
95
+ return pd.DataFrame(log), summary
96
+
97
+ # πŸ§ͺ Manual Strategy Interface
98
+ def run_manual_simulation(starting_balance, trades_min, trades_max, weeks, tp1_prob, tp2_prob,
99
+ tp1_r, tp2_r, base_risk_pct, profit_target):
100
+ df, summary = simulate_tp_strategy_full(starting_balance, trades_min, trades_max, weeks,
101
+ tp1_prob, tp2_prob, tp1_r, tp2_r, base_risk_pct, profit_target)
102
+ returns = df['End Balance'].pct_change().dropna()
103
+ volatility = returns.std() * np.sqrt(52)
104
+ sharpe_ratio = returns.mean() / returns.std() * np.sqrt(52) if returns.std() > 0 else 0
105
+ peak = df['End Balance'].cummax()
106
+ dd = (peak - df['End Balance']) / peak
107
+ max_dd = dd.max() * 100 if not dd.empty else 0
108
+ final_balance = df['End Balance'].iloc[-1] if not df.empty else starting_balance
109
+ score = final_balance / (1 + max_dd)
110
+
111
+ summary.update({
112
+ "Volatility % (Annual)": round(volatility * 100, 2),
113
+ "Sharpe Ratio": round(sharpe_ratio, 2),
114
+ "EdgeCast Score": round(score, 2)
115
+ })
116
+
117
+ return df, summary
118
+
119
+ # βš”οΈ Battle Mode
120
+ def battle_strategies(style1, style2):
121
+ p1 = strategy_presets[style1]
122
+ p2 = strategy_presets[style2]
123
+ df1, s1 = simulate_tp_strategy_full(**p1)
124
+ df2, s2 = simulate_tp_strategy_full(**p2)
125
+
126
+ def enrich_summary(df, summary):
127
+ returns = df['End Balance'].pct_change().dropna()
128
+ volatility = returns.std() * np.sqrt(52)
129
+ sharpe_ratio = returns.mean() / returns.std() * np.sqrt(52) if returns.std() > 0 else 0
130
+ peak_balance = df['End Balance'].cummax()
131
+ drawdowns = (peak_balance - df['End Balance']) / peak_balance
132
+ max_drawdown = drawdowns.max() * 100 if not drawdowns.empty else 0
133
+ final_balance = df['End Balance'].iloc[-1] if not df.empty else df['End Balance'].iloc[0]
134
+ edgecast_score = final_balance / (1 + max_drawdown)
135
+ summary["Volatility (Annualized)"] = round(volatility * 100, 2)
136
+ summary["Sharpe Ratio"] = round(sharpe_ratio, 2)
137
+ summary["Max Drawdown %"] = round(max_drawdown, 2)
138
+ summary["EdgeCast Score"] = round(edgecast_score, 2)
139
+ return summary
140
+
141
+ s1 = enrich_summary(df1, s1)
142
+ s2 = enrich_summary(df2, s2)
143
+
144
+ def badge(score):
145
+ if score >= 30000: return "πŸ’Ž Elite"
146
+ elif score >= 20000: return "πŸ₯‡ Pro"
147
+ elif score >= 10000: return "πŸ“ˆ Growing"
148
+ else: return "🟑 Developing"
149
+
150
+ badge1 = badge(s1["EdgeCast Score"])
151
+ badge2 = badge(s2["EdgeCast Score"])
152
+
153
+ plt.figure(figsize=(9, 5))
154
+ plt.plot(df1['Week'], df1['End Balance'], label=f"{style1} ({badge1})", marker='o')
155
+ plt.plot(df2['Week'], df2['End Balance'], label=f"{style2} ({badge2})", marker='o')
156
+ plt.title(f"πŸ₯Š Strategy Battle – {style1} vs {style2}")
157
+ plt.xlabel("Week")
158
+ plt.ylabel("Account Balance")
159
+ plt.grid(True)
160
+ plt.legend()
161
+ plt.tight_layout()
162
+ plot_path = "/tmp/battle_chart.png"
163
+ plt.savefig(plot_path)
164
+ plt.close()
165
+
166
+ df_compare = pd.DataFrame({
167
+ "Metric": list(s1.keys()) + ["Badge"],
168
+ style1: list(s1.values()) + [badge1],
169
+ style2: list(s2.values()) + [badge2]
170
+ })
171
+
172
+ return df_compare, plot_path
173
+
174
+ # πŸ“Š Leaderboard Tab
175
+ def analytics_dashboard():
176
+ leaderboard = []
177
+ for name, config in strategy_presets.items():
178
+ df, summary = simulate_tp_strategy_full(**config)
179
+ returns = df['End Balance'].pct_change().dropna()
180
+ volatility = returns.std() * np.sqrt(52)
181
+ sharpe = returns.mean() / returns.std() * np.sqrt(52) if returns.std() > 0 else 0
182
+ peak = df['End Balance'].cummax()
183
+ dd = (peak - df['End Balance']) / peak
184
+ max_dd = dd.max() * 100 if not dd.empty else 0
185
+ final = df['End Balance'].iloc[-1] if not df.empty else config['starting_balance']
186
+ score = final / (1 + max_dd)
187
+ leaderboard.append({
188
+ "Strategy": name,
189
+ "Final Balance": round(final, 2),
190
+ "Max DD %": round(max_dd, 2),
191
+ "Sharpe": round(sharpe, 2),
192
+ "EdgeCast Score": round(score, 2)
193
+ })
194
+ return pd.DataFrame(leaderboard).sort_values("EdgeCast Score", ascending=False).reset_index(drop=True)
195
+
196
+ # πŸŽ›οΈ Gradio Interface Tabs
197
+ preset_tab = gr.Interface(
198
+ fn=lambda style: simulate_tp_strategy_full(**strategy_presets[style]),
199
+ inputs=gr.Dropdown(choices=list(strategy_presets.keys()), label="Choose Preset Strategy"),
200
+ outputs=["dataframe", "json"],
201
+ title="🎯 Preset Mode",
202
+ )
203
+
204
+ manual_tab = gr.Interface(
205
+ fn=run_manual_simulation,
206
+ inputs=[
207
+ gr.Slider(100, 20000, 2500, label="Start Balance"),
208
+ gr.Slider(1, 10, 3, label="Trades Min"),
209
+ gr.Slider(1, 15, 7, label="Trades Max"),
210
+ gr.Slider(1, 52, 12, label="Weeks"),
211
+ gr.Slider(0, 1, 0.3, step=0.05, label="TP1 %"),
212
+ gr.Slider(0, 1, 0.3, step=0.05, label="TP2 %"),
213
+ gr.Slider(0.1, 3, 1.0, step=0.1, label="TP1 R"),
214
+ gr.Slider(0.1, 5, 2.0, step=0.1, label="TP2 R"),
215
+ gr.Slider(0.001, 0.05, 0.01, step=0.001, label="Risk %"),
216
+ gr.Slider(0, 100000, 0, step=500, label="Profit Target πŸ’°")
217
+ ],
218
+ outputs=["dataframe", "json"],
219
+ title="πŸ› οΈ Manual Config",
220
+ )
221
+
222
+ battle_tab = gr.Interface(
223
+ fn=battle_strategies,
224
+ inputs=[
225
+ gr.Dropdown(choices=list(strategy_presets.keys()), label="Strategy 1"),
226
+ gr.Dropdown(choices=list(strategy_presets.keys()), label="Strategy 2"),
227
  ],
228
+ outputs=["dataframe", gr.Image()],
229
+ title="πŸ₯Š Battle Mode"
230
  )
231
 
232
+ analytics_tab = gr.Interface(fn=analytics_dashboard, inputs=[], outputs="dataframe", title="πŸ“Š Analytics")
233
+
234
+ # 🧠 Multi-tab UI
235
+ gr.TabbedInterface(
236
+ interface_list=[preset_tab, manual_tab, battle_tab, analytics_tab],
237
+ tab_names=["🎯 Preset", "πŸ› οΈ Manual", "πŸ₯Š Battle", "πŸ“Š Analytics"],
238
+ title="EdgeCast – Strategy Simulation Suite"
239
+ ).launch()
240