kishan-1721 commited on
Commit
1297711
·
verified ·
1 Parent(s): 3e9ac43

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +555 -38
src/streamlit_app.py CHANGED
@@ -1,40 +1,557 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
1
+ import os
2
+ import sys
 
3
  import streamlit as st
4
+ import pandas as pd
5
+ import numpy as np
6
+ from io import BytesIO
7
+ import uuid
8
+
9
+ from huggingface_hub import snapshot_download
10
+
11
+ # Download files from the private space
12
+ private_repo = "kishan-1721/my_private_app" # Replace with your private space's repo ID
13
+ cache_dir = "/data/private_space_cache" # Updated to use writable /data directory
14
+ snapshot_download(
15
+ repo_id=private_repo,
16
+ repo_type="space",
17
+ local_dir=cache_dir,
18
+ token=os.getenv("HF_TOKEN") # Assumes HF_TOKEN is set as a secret
19
+ )
20
+
21
+ # Add the downloaded files to the Python path
22
+ sys.path.append(cache_dir)
23
+
24
+ # --- Streamlit Page Configuration ---
25
+ st.set_page_config(page_title="Stock Market Analyzer", layout="wide")
26
+
27
+ # --- Main Application ---
28
+ def main():
29
+ st.title("Stock Market Analyzer")
30
+
31
+ with st.container():
32
+ col1, col2, col3, col4, col5, col6 = st.columns(6)
33
+ with col1:
34
+ global sideways_threshold
35
+ sideways_threshold = st.slider("Sideways Threshold", min_value=0.0, max_value=2.0, value=0.0, step=0.01, format="%.2f") / 100
36
+ with col2:
37
+ global buffer
38
+ buffer = st.slider("Buffer", min_value=0.0, max_value=2.0, value=0.0, step=0.01, format="%.2f") / 100
39
+ with col3:
40
+ global intra_sl_value
41
+ intra_sl_value = st.slider("Intra SL Value", min_value=0.0, max_value=10.0, value=1.5, step=0.1, format="%.1f") / 100
42
+ with col4:
43
+ global target_sl
44
+ target_sl = st.slider("Target SL Value", min_value=0.0, max_value=15.0, value=0.0, step=0.1, format="%.1f") / 100
45
+ with col5:
46
+ global trail_offset
47
+ trail_offset = st.slider("Trailing SL %", min_value=0.0, max_value=10.0, value=3.0, step=0.1, format="%.1f") / 100
48
+ with col6:
49
+ global max_loss_sl
50
+ max_loss_sl = st.slider("MaxLoss SL Value", min_value=0.0, max_value=10.0, value=3.0, step=0.1, format="%.1f") / 100
51
+
52
+ with st.container():
53
+ col1, col2, col4, col3 = st.columns([1,1,1,2])
54
+
55
+ with col1:
56
+ Trailing_Value = st.radio(
57
+ "Set your Trailing Value ?",
58
+ ["Close", "High - Low"],
59
+ index=1
60
+ )
61
+
62
+ Exchange = st.radio(
63
+ "Select your Exchange ?",
64
+ ["Indian", "Crypto"],
65
+ index=0
66
+ )
67
+
68
+ with col2:
69
+ global brokerages
70
+ brokerages = st.number_input(label="Brokerages",step=0.01,value=0.2644 ,format="%.4f")
71
+
72
+ global interest_rate
73
+ interest_rate = st.number_input(label="Funding Cost Per Day",step=0.01,value=0.04 ,format="%.4f")
74
+
75
+ if intra_sl_value <= 0.0:
76
+ st.text("IntraBar is Set to Previous Top - Bottom")
77
+ if target_sl <= 0.0:
78
+ st.text("No Target is Set")
79
+ if trail_offset <= 0.0:
80
+ st.text("No Trailing Stop-loss")
81
+
82
+ with col4:
83
+ global MTF_Exposure
84
+ MTF_Exposure = st.slider("MTF Exposure", min_value=2.00, max_value=8.00, value=3.00, step=0.1, format="%.2f")
85
+
86
+ selected_script = st.radio(
87
+ "Select Your Script",
88
+ ["Old", "New Maxloss 5%"],
89
+ index=0
90
+ )
91
+
92
+ with col3:
93
+ # File uploader
94
+ uploaded_file = st.file_uploader("Upload your CSV file", type=["csv"])
95
+
96
+ if selected_script == "Old":
97
+ from main4 import get_buy_signal, parse_date, get_sell_signal, year_wise_analysis, calculate_yearly_returns, calculate_mtf_returns, crypto_year_wise_analysis, crypto_calculate_mtf_returns, crypto_calculate_yearly_returns, find_sequences, generate_trade_signals
98
+ else:
99
+ from main6 import get_buy_signal, parse_date, get_sell_signal, year_wise_analysis, calculate_yearly_returns, calculate_mtf_returns, crypto_year_wise_analysis, crypto_calculate_mtf_returns, crypto_calculate_yearly_returns, find_sequences, generate_trade_signals
100
+
101
+ # st.divider()
102
+ if uploaded_file is not None:
103
+ df = pd.read_csv(uploaded_file)
104
+ try:
105
+ df = df[['Date','Open','High', 'Low', 'Close']]
106
+ except:
107
+ df = df[['Date','Open','High', 'Low', 'Price']]
108
+
109
+ if st.button("Start Analysis"):
110
+ # Data preprocessing
111
+ df.columns = df.columns.str.strip()
112
+ df['Date'] = parse_date(df['Date'])
113
+ df.sort_values('Date', inplace=True)
114
+
115
+ if 'Price' in df.columns:
116
+ df = df.rename(columns={'Price': 'Close'})
117
+ df['%Change'] = df['Close'].pct_change().fillna(0) * 100
118
+ df["Direction"] = df["%Change"].apply(lambda x: "📈" if x > 0 else "📉")
119
+ df['Side Ways'] = df['%Change'].apply(lambda x: abs(x / 100) < sideways_threshold)
120
+
121
+ # Generate signals and trades
122
+ # result = generate_trade_signals(df, trail_offset, target_sl, Trailing_Value)
123
+
124
+ if selected_script == "Old":
125
+ result = generate_trade_signals(df, trail_offset, target_sl, Trailing_Value, buffer, intra_sl_value)
126
+ else:
127
+ result = generate_trade_signals(df, trail_offset, target_sl, Trailing_Value, buffer, intra_sl_value, max_loss_sl)
128
+
129
+ final_df = result[1]
130
+ final_df['Gap Loss 2%'] = final_df.apply(lambda x: True if x['Gap_UP_Down Trade'] == True and x['Profit %'] < -2 else False, axis=1)
131
+ final_df['Gap Exit'] = np.where(final_df['Gap_UP_Down Trade'].shift(-1).eq(True), True, False)
132
+ final_df['Gap Exit Loss % 2'] = np.where(final_df['Gap_UP_Down Trade'].shift(-1).eq(True) & (final_df['Profit %'] < -2), True, False)
133
+
134
+ col1, col2 = st.columns(2)
135
+
136
+ # with col1:
137
+ # st.subheader("📶 Processed Signal Data", divider=True)
138
+ # st.dataframe(final_df)
139
+
140
+ df = df.assign(Year=df['Date'].dt.year)
141
+ final_df = final_df.assign(Year=final_df['Entry Date'].dt.year)
142
+
143
+ if Exchange == 'Indian':
144
+
145
+ ################################################### Performing Analysis ###################################################
146
+
147
+ system_returns_no_compound, system_yearly_no_compound = calculate_yearly_returns(df,final_df, False, brokerages)
148
+
149
+ system_returns_with_compound, system_yearly_with_compound = calculate_yearly_returns(df,final_df, True, brokerages)
150
+
151
+ system_mtf_no_compound, system_mtf_yearly_no_compound = calculate_mtf_returns(df,final_df, MTF_Exposure, False, brokerages)
152
+
153
+ system_mtf_with_compound, system_mtf_yearly_with_compound = calculate_mtf_returns(df,final_df, MTF_Exposure, True, brokerages)
154
+
155
+ ################################################### BUY Trade Performing Analysis ###################################################
156
+
157
+ buy_trades_df = final_df[final_df['Trade Type'] == 'BUY']
158
+
159
+ buy_trades_no_compound, buy_trades_yearly_no_compound = calculate_yearly_returns(df,buy_trades_df, False, brokerages)
160
+
161
+ buy_trades_compound, buy_trades_yearly_compound = calculate_yearly_returns(df,buy_trades_df, True, brokerages)
162
+
163
+ buy_trades_mtf_no_compound, buy_trades_mtf_yearly_no_compound = calculate_mtf_returns(df,buy_trades_df, MTF_Exposure, False, brokerages)
164
+
165
+ buy_trades_mtf_returns_compound, buy_trades_mtf_yearly_compound = calculate_mtf_returns(df,buy_trades_df, MTF_Exposure, True, brokerages)
166
+
167
+ else:
168
+ ################################################### Crypto Performing Analysis ###################################################
169
+
170
+ ################################################### Performing Analysis ###################################################
171
+
172
+ system_returns_no_compound, system_yearly_no_compound = crypto_calculate_yearly_returns(df,final_df, False, brokerages)
173
+
174
+ system_returns_with_compound, system_yearly_with_compound = crypto_calculate_yearly_returns(df,final_df, True, brokerages)
175
+
176
+ system_mtf_no_compound, system_mtf_yearly_no_compound = crypto_calculate_mtf_returns(df,final_df, MTF_Exposure, False, brokerages, interest_rate)
177
+
178
+ system_mtf_with_compound, system_mtf_yearly_with_compound = crypto_calculate_mtf_returns(df,final_df, MTF_Exposure, True, brokerages, interest_rate)
179
+
180
+ ################################################### BUY Trade Performing Analysis ###################################################
181
+
182
+ buy_trades_df = final_df[final_df['Trade Type'] == 'BUY']
183
+
184
+ buy_trades_no_compound, buy_trades_yearly_no_compound = crypto_calculate_yearly_returns(df,buy_trades_df, False, brokerages)
185
+
186
+ buy_trades_compound, buy_trades_yearly_compound = crypto_calculate_yearly_returns(df,buy_trades_df, True, brokerages)
187
+
188
+ buy_trades_mtf_no_compound, buy_trades_mtf_yearly_no_compound = crypto_calculate_mtf_returns(df,buy_trades_df, MTF_Exposure, False, brokerages, interest_rate)
189
+
190
+ buy_trades_mtf_returns_compound, buy_trades_mtf_yearly_compound = crypto_calculate_mtf_returns(df,buy_trades_df, MTF_Exposure, True, brokerages, interest_rate)
191
+
192
+ # system_yearly_analysis = year_wise_analysis(df, system_returns_no_compound)
193
+ # System_Gain_Com = year_wise_analysis(df, system_returns_with_compound)
194
+ # year_analysis_ = year_wise_analysis(df, system_mtf_with_compound)
195
+
196
+ System_Gain_Com = system_mtf_yearly_no_compound
197
+ # year_analysis_ = system_mtf_yearly_with_compound
198
+
199
+ initial_investment_amount = 100000
200
+
201
+ with col1:
202
+ st.subheader("📆 Year-Wise Performance", divider=True)
203
+ st.dataframe(system_yearly_no_compound)
204
+
205
+ with col2:
206
+ st.subheader("📶 Compounding Year-Wise Performance", divider=True)
207
+ st.dataframe(System_Gain_Com)
208
+
209
+
210
+ pcol1, pcol2, pcol3 = st.columns(3)
211
+
212
+ with pcol1:
213
+ st.subheader("📊 Performance Overview", divider=True)
214
+
215
+ container = st.container(border=True)
216
+ container.text(f"Average Trades : {round(system_yearly_no_compound['Total_Trades'].mean(), 0)}")
217
+ container.text(f"Average BUY Trades : {round(system_yearly_no_compound['Total BUY Trades'].mean(), 0)}")
218
+ container.text(f"Average SELL Trades : {round(system_yearly_no_compound['Total SELL Trades'].mean(), 0)}")
219
+
220
+ container = st.container(border=True)
221
+ container.text(f"Start Price {system_yearly_no_compound['Start_Price'].iloc[0]}, End Price : {system_yearly_no_compound['End_Price'].iloc[-1]}")
222
+ container.text(f"Average Index Gain %: {round(system_yearly_no_compound['Index Gain'].sum() / len(system_yearly_no_compound), 2)}")
223
+ container.text(f"Index CAGR = {round(((system_yearly_no_compound['End_Price'].iloc[-1] / system_yearly_no_compound['Start_Price'].iloc[0]) ** (1 / len(system_yearly_no_compound)) - 1) * 100, 2) } ")
224
+
225
+ # container.text(f"Average System Gain %: {round(system_yearly_no_compound['System Gain'].sum() / len(system_yearly_no_compound), 2)}")
226
+ # container.text(f"Difference: {round(system_yearly_no_compound['Difference'].sum() / len(system_yearly_no_compound) , 2) }")
227
+
228
+ with pcol2:
229
+ st.subheader("📊 Trade Overview", divider=True)
230
+
231
+ container = st.container(border=True)
232
+ container.text(f"Total Years : {len(system_yearly_no_compound)}")
233
+ container.text(f"Total Trades: {len(final_df)}")
234
+ container.text(f"Profitable Trades {round(len(final_df[final_df['Profit'] > 0]))}")
235
+ container.text(f"Total Target Hit: {len(final_df[final_df['Exit Condition'] == 'Target Hit'])}")
236
+ container.text(f"Total Trailing Hit: {len(final_df[final_df['Exit Condition'] == 'Trailing Hit'])}")
237
+ container.text(f"Total IntraBar Hit: {len(final_df[final_df['Exit Condition'] == 'IntraBar Hit'])}")
238
+ container.text(f"High - Low Average: {round(final_df['change %'].mean(), 2)}")
239
+ # container.text(f"High - Low Average Number new: {round(np.percentile(final_df['change %'], 60), 2)}")
240
+ container.text(f"% Winning Ratio {round((len(final_df[final_df['Profit'] > 0]) / len(final_df)) * 100, 2)} %")
241
+
242
+ with pcol3:
243
+ st.subheader("📊 Gap Up & Down Overview", divider=True)
244
+
245
+ container = st.container(border=True)
246
+ container.text(f"Total Gap_UP_Down Trades: {final_df['Gap_UP_Down Trade'].sum()}")
247
+ container.text(f"Total Gap_UP_Down Exit Trades: {final_df['Gap Exit'].sum()}")
248
+ container.text(f"Loss More than 2 % in Gap_UP_Down Trades: {final_df['Gap Loss 2%'].sum()}")
249
+ container.text(f"Loss More than 2 % in Gap_UP_Down Exit Trades: {final_df['Gap Exit Loss % 2'].sum()}")
250
+
251
+
252
+ ################################## Risk Reward Ratio ##################################
253
+ container = st.container(border=True)
254
+
255
+ p_trades = len(final_df[final_df['Profit'] > 0])
256
+ N_trades = len(final_df[final_df['Profit'] < 0])
257
+
258
+ p_profit_ = final_df[final_df['Profit'] > 0]['Profit'].sum()
259
+ N_profit_ = final_df[final_df['Profit'] < 0]['Profit'].sum()
260
+
261
+ p_profit_avg = final_df[final_df['Profit'] > 0]['Profit %'].mean()
262
+ N_profit_avg = final_df[final_df['Profit'] < 0]['Profit %'].mean()
263
+
264
+ # container.text(f" (p_profit = {p_profit_} / p_trades = {p_trades}) / (N_profit_ = {N_profit_} / N_trades = {N_trades})")
265
+
266
+ ratio = abs((p_profit_ / p_trades) / ( N_profit_ / N_trades))
267
+
268
+ container.text(f"% Risk Reward Ratio: {round(ratio, 3 )} %")
269
+ container.text(f"% Profit Avg: {round(p_profit_avg, 4 )} %")
270
+ container.text(f"% Loss Avg: {round(N_profit_avg, 4 )} ")
271
+
272
+ if Exchange != 'Indian':
273
+ container.text(f"Max Holding Days: {System_Gain_Com['HOLDING DAYS'].max()}")
274
+
275
+
276
+ st.divider()
277
+ ################################################### Performance Analysis ###################################################
278
+
279
+ pcol1, pcol2, pcol3 = st.columns(3)
280
+
281
+ with pcol1:
282
+ st.subheader("📈 System Performance", divider=True)
283
+
284
+ total_profit_ = round(system_yearly_no_compound['Final Profit After All'].sum(), 2)
285
+ total_profit_AVG = round(system_yearly_no_compound['System Gain'].sum() / len(system_yearly_no_compound), 2)
286
+
287
+ buy_profit = round(buy_trades_yearly_no_compound['Final Profit After All'].sum(), 2)
288
+ buy_profit_AVG = round(buy_trades_yearly_no_compound['System Gain'].sum() / len(buy_trades_yearly_no_compound), 2)
289
+
290
+ sell_profit = round(total_profit_ - buy_profit, 2)
291
+ sell_profit_avg = round(total_profit_AVG - buy_profit_AVG, 2)
292
+
293
+ container = st.container(border=True)
294
+ container.write(f"**Total Profit : {total_profit_} (AVG : {total_profit_AVG} %)**")
295
+ container.write(f"**Buy Profit : {buy_profit} (AVG : {buy_profit_AVG} %)**")
296
+ container.write(f"**SELL Profit : {sell_profit} (AVG : {sell_profit_avg} %)**")
297
+ container.text(f"Total Years : {len(system_yearly_no_compound)}")
298
+
299
+ # container.write(f"**Total BUY Profit : {round(system_yearly_no_compound['BUY_Profit'].sum(), 2)} ({round((system_yearly_no_compound['BUY_Profit'].sum() * 100)/system_yearly_no_compound['Profit'].sum(), 2)} %) (AVG : {round(system_yearly_no_compound['BUY_Gain'].mean(), 2)} %)**")
300
+ # container.write(f"**Total SELL Profit : {round(system_yearly_no_compound['SELL_Profit'].sum(), 2)} ({round((system_yearly_no_compound['SELL_Profit'].sum() * 100)/system_yearly_no_compound['Profit'].sum(), 2)} %)**")
301
+
302
+ container.markdown("---")
303
+ ten_years = system_yearly_no_compound.tail(10)
304
+ container.write(f"**Last 10 Years AVG %: {round(ten_years['System Gain'].sum() / len(ten_years), 2)}**")
305
+ # container.text(f"Last 10 Years Only BUY AVG % : {round(ten_years['BUY_Gain'].mean(), 2)}")
306
+
307
+ ten_years = buy_trades_yearly_no_compound.tail(10)
308
+ container.write(f"**Buy System Last 10 Years AVG %: {round(ten_years['System Gain'].sum() / len(ten_years), 2)}**")
309
+
310
+ container.markdown("---")
311
+ five_years = system_yearly_no_compound.tail(5)
312
+ container.write(f"**Last 5 Years AVG %: {round(five_years['System Gain'].sum() / len(five_years), 2)}**")
313
+ # container.text(f"Last 5 Years Only BUY AVG % : {round(five_years['BUY_Gain'].mean(), 2)}")
314
+
315
+ five_years = buy_trades_yearly_no_compound.tail(5)
316
+ container.write(f"**Buy System Last 5 Years AVG %: {round(five_years['System Gain'].sum() / len(five_years), 2)}**")
317
+
318
+ container.markdown("---")
319
+ three_years = system_yearly_no_compound.tail(3)
320
+ container.write(f"**Last 3 Years AVG %: {round(three_years['System Gain'].sum() / len(three_years), 2)}**")
321
+ # container.text(f"Last 5 Years Only BUY AVG % : {round(five_years['BUY_Gain'].mean(), 2)}")
322
+
323
+ three_years = buy_trades_yearly_no_compound.tail(3)
324
+ container.write(f"**Buy System Last 3 Years AVG %: {round(three_years['System Gain'].sum() / len(three_years), 2)}**")
325
+
326
+ container.markdown("---")
327
+ two_years = system_yearly_no_compound.tail(2)
328
+ container.write(f"**Last 2 Years AVG %: {round(two_years['System Gain'].sum() / len(two_years), 2)}**")
329
+ # container.text(f"Last 5 Years Only BUY AVG % : {round(five_years['BUY_Gain'].mean(), 2)}")
330
+
331
+ two_years = buy_trades_yearly_no_compound.tail(2)
332
+ container.write(f"**Buy System Last 2 Years AVG %: {round(two_years['System Gain'].sum() / len(two_years), 2)}**")
333
+
334
+ container.markdown("---")
335
+ one_years = system_yearly_no_compound.tail(1)
336
+ container.write(f"**Last 1 Years AVG %: {round(one_years['System Gain'].sum() / len(one_years), 2)}**")
337
+ # container.text(f"Last 5 Years Only BUY AVG % : {round(five_years['BUY_Gain'].mean(), 2)}")
338
+
339
+ one_years = buy_trades_yearly_no_compound.tail(1)
340
+ container.write(f"**Buy System Last 1 Years AVG %: {round(one_years['System Gain'].sum() / len(one_years), 2)}**")
341
+
342
+ with pcol2:
343
+ st.subheader("📈 Compounding Performance", divider=True)
344
+
345
+ compund_system_cagr = round((((((system_yearly_with_compound['Final Profit After All'].sum()) + 100000) / 100000 ) ** (1 / len(system_yearly_with_compound))) -1 ) * 100 , 2)
346
+ buy_compund_system_cagr = round((((((buy_trades_yearly_compound['Final Profit After All'].sum()) + 100000) / 100000) ** (1 / len(buy_trades_yearly_compound))) -1 ) * 100 , 2)
347
+
348
+ container = st.container(border=True)
349
+ container.write(f"**Total Profit : {round(system_yearly_with_compound['Final Profit After All'].sum(), 2)} (AVG : {round(system_yearly_with_compound['System Gain'].sum() / len(system_yearly_with_compound), 2)} %) (C:{compund_system_cagr} %)**")
350
+ container.write(f"**Buy Profit : {round(buy_trades_yearly_compound['Final Profit After All'].sum(), 2)} (AVG : {round(buy_trades_yearly_compound['System Gain'].sum() / len(buy_trades_yearly_compound), 2)} %) (C:{buy_compund_system_cagr} %)**")
351
+ container.write(f"Initial Investment : {initial_investment_amount}")
352
+
353
+ # container.write(f"**Total BUY Profit : {round(system_yearly_with_compound['BUY_Profit'].sum(), 2)} ({round((system_yearly_with_compound['BUY_Profit'].sum() * 100)/system_yearly_with_compound['Profit'].sum(), 2)} %) (AVG : {round(system_yearly_with_compound['BUY_Gain'].mean(), 2)} %)**")
354
+ # container.write(f"**Total SELL Profit : {round(system_yearly_with_compound['SELL_Profit'].sum(), 2)} ({round((system_yearly_with_compound['SELL_Profit'].sum() * 100)/system_yearly_with_compound['Profit'].sum(), 2)} %)**")
355
+
356
+ container.markdown("---")
357
+ ten_years = system_yearly_with_compound.tail(10)
358
+ container.write(f"**Last 10 Years AVG %: {round(ten_years['System Gain'].sum() / len(ten_years), 2)}**")
359
+ # container.text(f"Last 10 Years Only BUY AVG % : {round(ten_years['BUY_Gain'].mean(), 2)}")
360
+
361
+ ten_years = buy_trades_yearly_compound.tail(10)
362
+ container.write(f"**Buy System Last 10 Years AVG %: {round(ten_years['System Gain'].sum() / len(ten_years), 2)}**")
363
+
364
+ container.markdown("---")
365
+ five_years = system_yearly_with_compound.tail(5)
366
+ container.write(f"**Last 5 Years AVG %: {round(five_years['System Gain'].sum() / len(five_years), 2)}**")
367
+ # container.text(f"Last 5 Years Only BUY AVG % : {round(five_years['BUY_Gain'].mean(), 2)}")
368
+
369
+ five_years = buy_trades_yearly_compound.tail(5)
370
+ container.write(f"**Buy System Last 5 Years AVG %: {round(five_years['System Gain'].sum() / len(five_years), 2)}**")
371
+
372
+ container.markdown("---")
373
+ three_years = system_yearly_with_compound.tail(3)
374
+ container.write(f"**Last 3 Years AVG %: {round(three_years['System Gain'].sum() / len(three_years), 2)}**")
375
+ # container.text(f"Last 5 Years Only BUY AVG % : {round(five_years['BUY_Gain'].mean(), 2)}")
376
+
377
+ three_years = buy_trades_yearly_compound.tail(3)
378
+ container.write(f"**Buy System Last 3 Years AVG %: {round(three_years['System Gain'].sum() / len(three_years), 2)}**")
379
+
380
+ container.markdown("---")
381
+ two_years = system_yearly_with_compound.tail(2)
382
+ container.write(f"**Last 2 Years AVG %: {round(two_years['System Gain'].sum() / len(two_years), 2)}**")
383
+ # container.text(f"Last 5 Years Only BUY AVG % : {round(five_years['BUY_Gain'].mean(), 2)}")
384
+
385
+ two_years = buy_trades_yearly_compound.tail(2)
386
+ container.write(f"**Buy System Last 2 Years AVG %: {round(two_years['System Gain'].sum() / len(two_years), 2)}**")
387
+
388
+ container.markdown("---")
389
+ one_years = system_yearly_with_compound.tail(1)
390
+ container.write(f"**Last 1 Years AVG %: {round(one_years['System Gain'].sum() / len(one_years), 2)}**")
391
+ # container.text(f"Last 5 Years Only BUY AVG % : {round(five_years['BUY_Gain'].mean(), 2)}")
392
+
393
+ one_years = buy_trades_yearly_compound.tail(1)
394
+ container.write(f"**Buy System Last 1 Years AVG %: {round(one_years['System Gain'].sum() / len(one_years), 2)}**")
395
+
396
+ with pcol3:
397
+ st.subheader("📈 MTF Compounding Gain", divider=True)
398
+
399
+ mtf_investment = initial_investment_amount / MTF_Exposure
400
+
401
+ compund_system_cagr = round((((((system_mtf_yearly_with_compound['Final Profit After All'].sum()) + mtf_investment) / mtf_investment) ** (1 / len(system_mtf_yearly_with_compound))) -1 ) * 100 , 2)
402
+ buy_compund_system_cagr = round((((((buy_trades_mtf_yearly_compound['Final Profit After All'].sum()) + mtf_investment) / mtf_investment) ** (1 / len(buy_trades_mtf_yearly_compound))) -1 ) * 100 , 2)
403
+
404
+ container = st.container(border=True)
405
+ container.write(f"**Total Profit : {round(system_mtf_yearly_with_compound['Final Profit After All'].sum(), 2)} (AVG : {round(system_mtf_yearly_with_compound['System Gain'].sum() / len(system_mtf_yearly_with_compound), 2)} %) (C:{compund_system_cagr} %)**")
406
+ container.write(f"**Buy Profit : {round(buy_trades_mtf_yearly_compound['Final Profit After All'].sum(), 2)} (AVG : {round(buy_trades_mtf_yearly_compound['System Gain'].sum() / len(buy_trades_mtf_yearly_compound), 2)} %) (C:{buy_compund_system_cagr} %)**")
407
+ container.write(f"Initial Investment : {mtf_investment}")
408
+
409
+ # container.write(f"**Total BUY Profit : {round(system_mtf_yearly_with_compound['BUY_Profit'].sum(), 2)} ({round((system_mtf_yearly_with_compound['BUY_Profit'].sum() * 100)/system_mtf_yearly_with_compound['Profit'].sum(), 2)} %) (AVG : {round(system_mtf_yearly_with_compound['BUY_Gain'].mean(), 2)} %)**")
410
+ # container.write(f"**Total SELL Profit : {round(system_mtf_yearly_with_compound['SELL_Profit'].sum(), 2)} ({round((system_mtf_yearly_with_compound['SELL_Profit'].sum() * 100)/system_mtf_yearly_with_compound['Profit'].sum(), 2)} %)**")
411
+
412
+ container.markdown("---")
413
+ ten_years = system_mtf_yearly_with_compound.tail(10)
414
+ container.write(f"**Last 10 Years AVG %: {round(ten_years['System Gain'].sum() / len(ten_years), 2)}**")
415
+ # container.text(f"Last 10 Years Only BUY AVG % : {round(ten_years['BUY_Gain'].mean(), 2)}")
416
+
417
+ ten_years = buy_trades_mtf_yearly_compound.tail(10)
418
+ container.write(f"**Buy System Last 10 Years AVG %: {round(ten_years['System Gain'].sum() / len(ten_years), 2)}**")
419
+
420
+ container.markdown("---")
421
+ five_years = system_mtf_yearly_with_compound.tail(5)
422
+ container.write(f"**Last 5 Years AVG %: {round(five_years['System Gain'].sum() / len(five_years), 2)}**")
423
+ # container.text(f"Last 5 Years Only BUY AVG % : {round(five_years['BUY_Gain'].mean(), 2)}")
424
+
425
+ five_years = buy_trades_mtf_yearly_compound.tail(5)
426
+ container.write(f"**Buy System Last 5 Years AVG %: {round(five_years['System Gain'].sum() / len(five_years), 2)}**")
427
+
428
+ container.markdown("---")
429
+ three_years = system_mtf_yearly_with_compound.tail(3)
430
+ container.write(f"**Last 3 Years AVG %: {round(three_years['System Gain'].sum() / len(three_years), 2)}**")
431
+ # container.text(f"Last 5 Years Only BUY AVG % : {round(five_years['BUY_Gain'].mean(), 2)}")
432
+
433
+ three_years = buy_trades_mtf_yearly_compound.tail(3)
434
+ container.write(f"**Buy System Last 3 Years AVG %: {round(three_years['System Gain'].sum() / len(three_years), 2)}**")
435
+
436
+ container.markdown("---")
437
+ two_years = system_mtf_yearly_with_compound.tail(2)
438
+ container.write(f"**Last 2 Years AVG %: {round(two_years['System Gain'].sum() / len(two_years), 2)}**")
439
+ # container.text(f"Last 5 Years Only BUY AVG % : {round(five_years['BUY_Gain'].mean(), 2)}")
440
+
441
+ two_years = buy_trades_mtf_yearly_compound.tail(2)
442
+ container.write(f"**Buy System Last 2 Years AVG %: {round(two_years['System Gain'].sum() / len(two_years), 2)}**")
443
+
444
+ container.markdown("---")
445
+ one_years = system_mtf_yearly_with_compound.tail(1)
446
+ container.write(f"**Last 1 Years AVG %: {round(one_years['System Gain'].sum() / len(one_years), 2)}**")
447
+ # container.text(f"Last 5 Years Only BUY AVG % : {round(five_years['BUY_Gain'].mean(), 2)}")
448
+
449
+ one_years = buy_trades_mtf_yearly_compound.tail(1)
450
+ container.write(f"**Buy System Last 1 Years AVG %: {round(one_years['System Gain'].sum() / len(one_years), 2)}**")
451
+
452
+ temp = final_df[['Entry Date', 'Trade Type', 'Gap_UP_Down Trade', 'GAP_P', 'Entry Price', 'Exit Date', 'Exit Condition', 'Exit Price', 'Profit', 'Profit %', 'Gap Loss 2%','Year']]
453
+ temp.rename(columns={'Trade Type' : 'Trade', 'Gap_UP_Down Trade' : 'GAP', 'Entry Price' : 'Entry', 'Exit Price' : 'Exit', 'Gap Loss 2%' : 'Gap Loss %'}, inplace = True)
454
+
455
+ # Filter out rows where '% Profit' is NaN and sort by 'Entry Date'
456
+ def max_Profit_loss(final_df):
457
+ filtered_df = final_df[final_df['Profit %'].notna()].sort_values('Entry Date')
458
+
459
+ # Define conditions for profit and loss sequences
460
+ profit_condition = lambda row: row['Profit %'] >= 0
461
+ loss_condition = lambda row: row['Profit %'] <= 0
462
+
463
+ # Find profit and loss sequences
464
+ profit_sequences = find_sequences(filtered_df, profit_condition)
465
+ loss_sequences = find_sequences(filtered_df, loss_condition)
466
+
467
+ # Convert sequences to DataFrames
468
+ profit_df = pd.DataFrame(profit_sequences)
469
+ loss_df = pd.DataFrame(loss_sequences)
470
+
471
+ # Get top 20 sequences
472
+ # Top 20 profit sequences (highest total % profit)
473
+ top_profit_df = profit_df.sort_values('Total %', ascending=False).head(20)
474
+ # Top 20 loss sequences (most negative total % loss)
475
+ top_loss_df = loss_df.sort_values('Total %', ascending=True).head(20)
476
+
477
+ # Add 'Type' column to distinguish between profit and loss
478
+ top_profit_df['Type'] = 'Profit'
479
+ top_loss_df['Type'] = 'Loss'
480
+
481
+ top_profit_df.reset_index(drop=True, inplace=True)
482
+ top_loss_df.reset_index(drop=True, inplace=True)
483
+
484
+ data = {
485
+ 'Year_L': top_loss_df['Start Date'].apply(lambda x: x.year),
486
+ # 'End Date_Loss': top_loss_df['End Date'],
487
+ '%_Loss': top_loss_df['Total %'],
488
+
489
+ 'Year_P': top_profit_df['Start Date'].apply(lambda x: x.year),
490
+ # 'End Date_Profit': top_profit_df['End Date'],
491
+ '%_Profit': top_profit_df['Total %']
492
+ }
493
+ return pd.DataFrame(data)
494
+
495
+ st.divider()
496
+
497
+ st.subheader("Detail Analysis of Maximum Profit 📈 and Loss 📉", divider=True)
498
+ pcol1, pcol2, pcol3 = st.columns([1,1,2])
499
+
500
+ with pcol1:
501
+ st.text("General Analysis")
502
+ profit_loss_all = max_Profit_loss(final_df)
503
+ st.dataframe(profit_loss_all)
504
+
505
+ with pcol2:
506
+ st.text("Only in BUY Trades")
507
+ profit_loss_all_BUY = max_Profit_loss(buy_trades_df)
508
+ st.dataframe(profit_loss_all_BUY)
509
+
510
+ with pcol3:
511
+ st.text("Gap Up & Down Loss 📉")
512
+ st.dataframe(final_df[final_df['Gap Exit Loss % 2'] == True].reset_index())
513
+
514
+ # Save to Excel
515
+ excel_buffer = BytesIO()
516
+ with pd.ExcelWriter(excel_buffer, engine='openpyxl') as writer:
517
+ final_df.to_excel(writer, sheet_name='Trades Analysis', index=False)
518
+ # temp.to_excel(writer, sheet_name='Full Analysis', index=False)
519
+ system_returns_no_compound.to_excel(writer, sheet_name='System Analysis', index=False)
520
+ system_yearly_no_compound.to_excel(writer, sheet_name='System Yearly', index=False)
521
+
522
+ profit_loss_all.to_excel(writer, sheet_name='Profit-Loss Analysis', index=False)
523
+
524
+ system_returns_with_compound.to_excel(writer, sheet_name='System Compounding', index=False)
525
+ system_yearly_with_compound.to_excel(writer, sheet_name='System Compounding Yearly', index=False)
526
+
527
+ system_mtf_no_compound.to_excel(writer, sheet_name='MTF System Analysis', index=False)
528
+ system_mtf_yearly_no_compound.to_excel(writer, sheet_name='MTF System Yearly', index=False)
529
+
530
+ system_mtf_with_compound.to_excel(writer, sheet_name='CMP MTF System', index=False)
531
+ system_mtf_yearly_with_compound.to_excel(writer, sheet_name='CMP MTF Yearly', index=False)
532
+
533
+ buy_trades_no_compound.to_excel(writer, sheet_name='BUY Analysis', index=False)
534
+ buy_trades_yearly_no_compound.to_excel(writer, sheet_name='BUY Yearly', index=False)
535
+
536
+ buy_trades_compound.to_excel(writer, sheet_name='BUY Compound', index=False)
537
+ buy_trades_yearly_compound.to_excel(writer, sheet_name='BUY Compound Yearly', index=False)
538
+
539
+ buy_trades_mtf_no_compound.to_excel(writer, sheet_name='BUY MTF', index=False)
540
+ buy_trades_mtf_yearly_no_compound.to_excel(writer, sheet_name='BUY MTF Yearly', index=False)
541
+
542
+ buy_trades_mtf_returns_compound.to_excel(writer, sheet_name='BUY MTF CMP', index=False)
543
+ buy_trades_mtf_yearly_compound.to_excel(writer, sheet_name='BUY MTF CMP Yearly', index=False)
544
+
545
+
546
+ file_name_ = f"{uploaded_file.name} Trailing {trail_offset} Target {target_sl}"
547
+
548
+ excel_buffer.seek(0)
549
+ st.download_button(
550
+ label="Download Excel File",
551
+ data=excel_buffer,
552
+ file_name=f"Analysis of {file_name_}.xlsx",
553
+ mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
554
+ )
555
 
556
+ if __name__ == "__main__":
557
+ main()