Deep_Stock_Analyzer_ / src /streamlit_app.py
kishan-1721's picture
Update src/streamlit_app.py
b219881 verified
import os
import sys
import streamlit as st
import pandas as pd
import numpy as np
from io import BytesIO
import uuid
from huggingface_hub import snapshot_download
# Download files from the private space
private_repo = "kishan-1721/my_private_app" # Replace with your private space's repo ID
cache_dir = "/data/private_space_cache" # Updated to use writable /data directory
snapshot_download(
repo_id=private_repo,
repo_type="space",
local_dir=cache_dir,
token=os.getenv("HF_TOKEN") # Assumes HF_TOKEN is set as a secret
)
# Add the downloaded files to the Python path
sys.path.append(cache_dir)
# --- Streamlit Page Configuration ---
st.set_page_config(page_title="Deep Stock Analyzer", layout="wide")
# Function to calculate streaks for a given DataFrame
def calculate_streaks(df):
df['is_profit'] = df['Profit'] > 0
df['streak_group'] = (df['is_profit'] != df['is_profit'].shift()).cumsum()
streaks = df.groupby(['streak_group', 'is_profit']).apply(lambda x: pd.Series({
'start_index': x.index[0],
'end_index': x.index[-1],
'start_date': x['Entry Date'].iloc[0],
'end_date': x['Exit Date'].iloc[-1],
'num_trades': len(x),
'total_profit': x['Profit'].sum(),
'total_percent_profit': x['% Profit'].sum() # Added to calculate sum of % Profit
}))
return streaks
# --- Main Application ---
def main():
st.title("Deep Stock Analyzer")
# Settings
with st.container():
col1, col2, col3, col4, col5, col6 = st.columns(6)
with col1:
global sideways_threshold
sideways_threshold = st.slider("Sideways Threshold", min_value=0.0, max_value=2.0, value=0.00, step=0.01, format="%.2f") / 100
with col2:
global buffer
buffer = st.slider("Buffer", min_value=0.0, max_value=2.0, value=0.0, step=0.01, format="%.2f") / 100
with col3:
global intra_sl_value
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
with col4:
global interest_rate
interest_rate = st.number_input(label="Funding Cost Per Day",step=0.01,value=0.04 ,format="%.4f")
# genre = st.radio(
# "Want to find out Best Configuration ?",
# ["YES", "NO"],
# # index=1 # Set "NO" as the default, uncomment if needed
# )
with col5:
Trailing_Value = st.radio(
"Set your Trailing Value ?",
["Close", "High - Low"],
index=0
)
with col6:
selected_script = st.radio(
"Select Your Script",
["Old", "New Maxloss 5%"],
index=0
)
with st.container():
col1, col2, col3, col4, col5 = st.columns([1,1,1,1,2])
with col1:
global brokerages
brokerages = st.number_input(label="Brokerages",step=0.01,value=0.2644 ,format="%.4f")
with col2:
global MTF_Exposure
MTF_Exposure = st.slider("MTF Exposure", min_value=2.00, max_value=8.00, value=3.00, step=0.1, format="%.2f")
with col3:
Exchange = st.radio(
"Select your Exchange ?",
["Indian", "Crypto"],
index=0
)
if intra_sl_value <= 0.0:
st.text("IntraBar is Set to Previous Top - Bottom")
with col4:
global max_loss_sl
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
with col5:
# File uploader
uploaded_file = st.file_uploader("Upload your CSV file", type=["csv"])
if selected_script == "Old":
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
else:
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
if uploaded_file is not None:
df = pd.read_csv(uploaded_file)
try:
df = df[['Date','Open','High', 'Low', 'Close']]
except:
df = df[['Date','Open','High', 'Low', 'Price']]
if st.button("Start Analysis"):
# Data preprocessing
df.columns = df.columns.str.strip()
df['Date'] = parse_date(df['Date'])
df.sort_values('Date', inplace=True)
if 'Price' in df.columns:
df = df.rename(columns={'Price': 'Close'})
df['%Change'] = df['Close'].pct_change().fillna(0) * 100
df["Direction"] = df["%Change"].apply(lambda x: "πŸ“ˆ" if x > 0 else "πŸ“‰")
df['Side Ways'] = df['%Change'].apply(lambda x: abs(x / 100) < sideways_threshold)
# Define ranges for trailOffset and target_SL to test
trailOffset_values = [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06]
if Exchange == 'Crypto':
target_SL_values = [0.0 , 0.02, 0.04, 0.06, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15]
# target_SL_values = [0.0 , 0.02, 0.04, 0.06, 0.08]
else:
target_SL_values = [0.0 , 0.02, 0.04, 0.06, 0.08]
initial_investment_main = 100000
mtf_investment = initial_investment_main / MTF_Exposure
# Function to calculate Compound Annual Growth Rate (CAGR)
def calculate_cagr(total_profit, initial_investment, num_years):
"""Calculate CAGR given total profit, initial investment, and number of years."""
if num_years == 0:
return 0
return round(((((total_profit + initial_investment) / initial_investment) ** (1 / num_years)) - 1) * 100, 2)
# Initialize lists to store analysis results for all trades and BUY trades
all_year_analysis = []
all_year_analysis_BUY = []
# Iterate over all combinations of trailOffset and target_SL
for trailOffset in trailOffset_values:
for target_SL in target_SL_values:
# Generate trade signals with current parameters
if selected_script == "Old":
result = generate_trade_signals(df, trailOffset, target_SL, Trailing_Value, buffer, intra_sl_value)
else:
result = generate_trade_signals(df, trailOffset, target_SL, Trailing_Value, buffer, intra_sl_value, max_loss_sl)
final_df = result[1] # Extract trades DataFrame from result
# Calculate percentage profit for each trade
final_df['% Profit'] = final_df['Profit'] / final_df['Entry Price'] * 100
# Assign 'Year' column based on date fields
df = df.assign(Year=df['Date'].dt.year)
final_df = final_df.assign(Year=final_df['Entry Date'].dt.year)
total_years = final_df['Year'].unique()
# Filter trades to get only BUY trades
buy_trades_df = final_df[final_df['Trade Type'] == 'BUY']
# Calculate Multi-Time Frame (MTF) returns with compounding
if Exchange == 'Indian':
system_mtf_with_compound, system_mtf_yearly_with_compound = calculate_mtf_returns(
df, final_df, MTF_Exposure, True, brokerages
)
buy_trades_mtf_returns_compound, buy_trades_mtf_yearly_compound = calculate_mtf_returns(
df, buy_trades_df, MTF_Exposure, True, brokerages
)
else:
system_mtf_with_compound, system_mtf_yearly_with_compound = crypto_calculate_mtf_returns(
df, final_df, MTF_Exposure, True, brokerages, interest_rate
)
buy_trades_mtf_returns_compound, buy_trades_mtf_yearly_compound = crypto_calculate_mtf_returns(
df, buy_trades_df, MTF_Exposure, True, brokerages, interest_rate
)
################################## Risk Reward Ratio ##################################
def risk_reward(df):
p_trades = len(df[df['Profit'] > 0])
N_trades = len(df[df['Profit'] <= 0])
p_profit_ = df[df['Profit'] > 0]['Profit'].sum()
N_profit_ = df[df['Profit'] <= 0]['Profit'].sum()
ratio_risk_reward = round(abs((p_profit_ / p_trades) / ( N_profit_ / N_trades)), 3)
return ratio_risk_reward
# Add parameter values to yearly results
system_mtf_yearly_with_compound['trailOffset'] = trailOffset * 100
system_mtf_yearly_with_compound['target_SL'] = target_SL * 100
system_mtf_yearly_with_compound['Winning Ratio'] = round((len(system_mtf_with_compound[system_mtf_with_compound['Profit'] > 0]) / len(system_mtf_with_compound)) * 100, 2)
system_mtf_yearly_with_compound['Risk/Reward Ratio'] = risk_reward(system_mtf_with_compound)
buy_trades_mtf_yearly_compound['trailOffset'] = trailOffset * 100
buy_trades_mtf_yearly_compound['target_SL'] = target_SL * 100
buy_trades_mtf_yearly_compound['Winning Ratio'] = round((len(buy_trades_mtf_returns_compound[buy_trades_mtf_returns_compound['Profit'] > 0]) / len(buy_trades_mtf_returns_compound)) * 100, 2)
buy_trades_mtf_yearly_compound['Risk/Reward Ratio'] = risk_reward(buy_trades_mtf_returns_compound)
# Calculate CAGR for overall system
total_profit_system = system_mtf_yearly_with_compound['Final Profit After All'].sum()
num_years_system = len(system_mtf_yearly_with_compound)
system_cagr = calculate_cagr(total_profit_system, mtf_investment, num_years_system)
system_mtf_yearly_with_compound['CAGR'] = system_cagr
system_mtf_yearly_with_compound['Last 10'] = system_mtf_yearly_with_compound.tail(10)['System Gain'].mean()
system_mtf_yearly_with_compound['Last 5'] = system_mtf_yearly_with_compound.tail(5)['System Gain'].mean()
system_mtf_yearly_with_compound['Last 3'] = system_mtf_yearly_with_compound.tail(3)['System Gain'].mean()
system_mtf_yearly_with_compound['Last 2'] = system_mtf_yearly_with_compound.tail(2)['System Gain'].mean()
system_mtf_yearly_with_compound['Last 1'] = system_mtf_yearly_with_compound.tail(1)['System Gain'].mean()
# Calculate CAGR for BUY trades
total_profit_buy = buy_trades_mtf_yearly_compound['Final Profit After All'].sum()
num_years_buy = len(buy_trades_mtf_yearly_compound)
buy_cagr = calculate_cagr(total_profit_buy, mtf_investment, num_years_buy)
buy_trades_mtf_yearly_compound['CAGR'] = buy_cagr
buy_trades_mtf_yearly_compound['Last 10'] = buy_trades_mtf_yearly_compound.tail(10)['System Gain'].mean()
buy_trades_mtf_yearly_compound['Last 5'] = buy_trades_mtf_yearly_compound.tail(5)['System Gain'].mean()
buy_trades_mtf_yearly_compound['Last 3'] = buy_trades_mtf_yearly_compound.tail(3)['System Gain'].mean()
buy_trades_mtf_yearly_compound['Last 2'] = buy_trades_mtf_yearly_compound.tail(2)['System Gain'].mean()
buy_trades_mtf_yearly_compound['Last 1'] = buy_trades_mtf_yearly_compound.tail(1)['System Gain'].mean()
# Store results
all_year_analysis.append(system_mtf_yearly_with_compound)
all_year_analysis_BUY.append(buy_trades_mtf_yearly_compound)
# Combine all yearly results into single DataFrames
final_year_analysis = pd.concat(all_year_analysis, ignore_index=True)
final_year_analysis_BUY = pd.concat(all_year_analysis_BUY, ignore_index=True)
# Define columns to keep in the final output
selected_columns = [
'trailOffset', 'target_SL', 'Year', 'Start_Price', 'End_Price', 'System Gain','Last 10','Last 5','Last 3',
'Last 2','Last 1','CAGR', 'Index Gain', 'Difference', 'Final Profit After All', 'Winning Ratio','Risk/Reward Ratio',
'Total_Trades', 'Total BUY Trades', 'Total SELL Trades'
]
# Filter DataFrames to selected columns
final_year_analysis = final_year_analysis[selected_columns]
final_year_analysis_BUY = final_year_analysis_BUY[selected_columns]
# Aggregate results by trailOffset and target_SL
result = final_year_analysis.groupby(['trailOffset', 'target_SL']).agg({
'Final Profit After All': 'sum', # Total profit across years
'CAGR': 'mean', # CAGR (same for each year in a combination)
'System Gain': 'mean', # Average yearly system gain
'Last 10' : 'mean',
'Last 5' : 'mean',
'Last 3' : 'mean',
'Last 2' : 'mean',
'Last 1' : 'mean',
'Winning Ratio' : 'mean', # Winning Ratio
'Risk/Reward Ratio' : 'mean',
'Total_Trades': 'mean', # Average trades per year
'Total BUY Trades': 'mean', # Average BUY trades per year
'Total SELL Trades': 'mean' # Average SELL trades per year
}).reset_index()
result_BUY = final_year_analysis_BUY.groupby(['trailOffset', 'target_SL']).agg({
'Final Profit After All': 'sum',
'CAGR': 'mean',
'System Gain': 'mean',
'Last 10' : 'mean',
'Last 5' : 'mean',
'Last 3' : 'mean',
'Last 2' : 'mean',
'Last 1' : 'mean',
'Winning Ratio' : 'mean', # Winning Ratio
'Risk/Reward Ratio' : 'mean',
'Total_Trades': 'mean',
'Total BUY Trades': 'mean',
'Total SELL Trades': 'mean'
}).reset_index()
# Convert trade count columns to integers after rounding
trade_count_columns = ['Total_Trades', 'Total BUY Trades', 'Total SELL Trades']
result[trade_count_columns] = result[trade_count_columns].round().astype(int)
result = result.sort_values("CAGR", ascending = False).reset_index(drop = True)
result_BUY[trade_count_columns] = result_BUY[trade_count_columns].round().astype(int)
result_BUY = result_BUY.sort_values("CAGR", ascending = False).reset_index(drop = True)
rename_columns = {'trailOffset' : 'Trailing SL', 'target_SL' : 'Target', 'Total_Trades':'Avg_Trades', 'Total BUY Trades': 'Avg BUY Trades', 'Total SELL Trades': 'Avg SELL Trades'}
result.rename(columns=rename_columns, inplace= True)
result_BUY.rename(columns=rename_columns, inplace= True)
# Display results in Streamlit
st.write(f"Total Years : {len(total_years)}")
st.write(f"High - Low Average: {round(final_df['change %'].mean(), 2)}")
st.write(f"Initial Investment : {mtf_investment}")
st.subheader("πŸ“ˆ System Best Combination Performance", divider=True)
st.dataframe(result)
st.subheader("πŸ“ˆ Buy System Best Combination Performance", divider=True)
st.dataframe(result_BUY)
if __name__ == "__main__":
main()