algo_returns / app.py
tttarun's picture
Create app.py
a22c27d verified
raw
history blame
6.63 kB
import gradio as gr
import pandas as pd
import numpy as np
from NSEDownload import stocks
from time import sleep
## Get 10 year data from NSE
def get_data(symb):
l = []
year = 2015
for i in range(0,10,5):
year = i + year
df = stocks.get_data(stock_symbol=symb, start_date=f'1-1-{year}', end_date=f'1-1-{year+5}')
df.reset_index(drop=False,inplace=True)
# print(df.head())
l.append(df)
sleep(15)
dff = pd.concat(l,ignore_index=True)
dff.to_csv(f'{symb}.csv',index=False,encoding='utf-8')
return
# Calculate profit/loss based on stock price movement after condition is met
def calculate_profit_loss(stock_data):
buy_sell_actions = []
for i in range(len(stock_data)):
if stock_data['condition'].iloc[i] == 1: # Trigger condition met
buy_price = stock_data['Open Price'].iloc[i+1] # Buy on the next day's open price
monitored_prices = stock_data.iloc[i+1:i+9] # Monitor the next 8 days
sell_price = None
for j in range(len(monitored_prices)):
no_trigger = 0
open_price = monitored_prices['Open Price'].iloc[j]
close_price = monitored_prices['Close Price'].iloc[j]
change_percent = (close_price - buy_price) / buy_price * 100
# Check for the +2%, +3%, +5%, +8% thresholds and set stop loss
if change_percent >= 8:
sell_price = close_price
break
elif change_percent >= 5:
sell_price = max(sell_price or 0, close_price)
if change_percent <= 5:
break
elif change_percent >= 3:
sell_price = max(sell_price or 0, close_price)
if change_percent <= 3:
break
elif change_percent >= 2:
sell_price = max(sell_price or 0, close_price)
if change_percent <= 2:
break
# Stop-loss at -3%
elif change_percent <= -3:
sell_price = close_price
break
# If no triggers happen, sell at the 8th day's closing price
if sell_price is None:
sell_price = monitored_prices['Close Price'].iloc[-1]
no_trigger = 1
# Calculate profit/loss percentage
profit_loss_percent = (sell_price - buy_price) / buy_price * 100
buy_sell_actions.append({
'Buy Date': stock_data['Date'].iloc[i+1],
'Sell Date': monitored_prices['Date'].iloc[j] if sell_price != monitored_prices['Close Price'].iloc[-1] else monitored_prices['Date'].iloc[-1],
'Buy Price': buy_price,
'Sell Price': sell_price,
'Profit/Loss (%)': profit_loss_percent,
'No trigger': no_trigger
})
return pd.DataFrame(buy_sell_actions)
# Example function to simulate loading and processing stock data
def get_stock_data(stock_name):
get_data(stock_name)
stock_data = pd.read_csv(f'{stock_name}.csv')
# Ensure the 'Date' column is in datetime format
stock_data['Date'] = pd.to_datetime(stock_data['Date'])
# Sort data by date
stock_data = stock_data.sort_values(by='Date')
# Calculate daily RSI
def calculate_rsi(data, window):
delta = data['Close Price'].diff(1)
# print(delta)
gain = np.where(delta > 0, delta, 0)
loss = np.where(delta < 0, -delta, 0)
avg_gain = pd.Series(gain).rolling(window=window).mean()
avg_loss = pd.Series(loss).rolling(window=window).mean()
rs = avg_gain / avg_loss
rsi = 100 - (100 / (1 + rs))
return rsi
# Add a new column 'Daily RSI' for 14-day RSI
stock_data['Daily RSI'] = calculate_rsi(stock_data, window=14)
# Function to calculate sliding weekly RSI
def calculate_sliding_weekly_rsi(data):
global weekly_rsi
weekly_rsi = []
for i in range(7):
stock_data1 = stock_data.iloc[i::7].reset_index(drop=True)
stock_data1['weekly RSI'] = calculate_rsi(stock_data1, window=14)
weekly_rsi.append(stock_data1)
stock_data2 = pd.concat(weekly_rsi,ignore_index=True)
stock_data.drop_duplicates(subset=['Date'],keep='first',inplace=True)
stock_data2 = stock_data2.sort_values(by='Date')
return stock_data2
# Calculate sliding weekly RSI
stock_data = calculate_sliding_weekly_rsi(stock_data)
stock_data.reset_index(drop=True,inplace=True)
## Applying the condition
for i in range(30, len(stock_data)):
prev_30_days_rsi = stock_data['Daily RSI'][i-30:i]
if all(prev_30_days_rsi < 65) and 65 <= stock_data['Daily RSI'].iloc[i] <= 70:
stock_data.at[i, 'condition'] = 1
fstock = stock_data[stock_data['condition']==1].reset_index(drop=True)
profit_data = calculate_profit_loss(stock_data)
# Returning two dataframes: One for the full stock data, another for RSI values
return fstock, profit_data
# Function to save CSV file and return its path
def save_to_csv(stock_name):
fstock, profit_data = get_stock_data(stock_name)
csv_file_path = f'{stock_name}.csv'
return fstock, profit_data, csv_file_path
# Create the Gradio interface
with gr.Blocks() as demo:
gr.Markdown(
"""
<h1 style="text-align: center; color: #4CAF50;">Stock Analysis Interface</h1>
<p style="text-align: center;">Enter a stock Symbol and Calculate the algo returns.</p>
"""
)
with gr.Row():
with gr.Column():
stock_input = gr.Textbox(label="Enter Stock Symbol", placeholder="e.g., CANBK", lines=1)
submit_button = gr.Button("Submit", variant="primary")
with gr.Column():
gr.Markdown("<h3 style='text-align: center;'>Output</h3>")
output_stock_data = gr.DataFrame(label="Dates where Conditions met", interactive=False)
output_rsi_data = gr.DataFrame(label="Profit and Loss Statement", interactive=False)
csv_download = gr.File(label="Download CSV")
# When the button is clicked, show the two dataframes and provide a downloadable CSV
submit_button.click(save_to_csv, inputs=stock_input, outputs=[output_stock_data, output_rsi_data, csv_download])
# Launch the Gradio interface
demo.launch()