File size: 6,518 Bytes
c3fc9c2 d3b64d7 c3fc9c2 a047e89 c3fc9c2 d3b64d7 c3fc9c2 026493b c3fc9c2 d3b64d7 ddc92c4 c3fc9c2 026493b c3fc9c2 ddc92c4 c3fc9c2 026493b c3fc9c2 026493b c3fc9c2 026493b c3fc9c2 d3b64d7 c3fc9c2 d3b64d7 c3fc9c2 026493b 79e3a41 c3fc9c2 c0450f1 026493b d3b64d7 026493b c0450f1 c3fc9c2 c0450f1 e1ef946 d3b64d7 e1ef946 d3b64d7 c0450f1 d3b64d7 c0450f1 c3fc9c2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
import streamlit as st
import pandas as pd
import numpy as np
import time
from streamlit.components import v1 as components
from src.utils import complete_test, categorize_df
def complete_backtest():
@st.cache_data
def load_data():
# Load data
limits = pd.read_csv('data/yahoo_limits.csv')
return limits
limits = load_data()
st.markdown(
"""
# Algorithmic Trading Dashboard
## Evaluate Strategy
"""
)
stock_list = st.selectbox("Select Stock list", ['Nifty 50', 'Nifty Next 50', 'Nifty 100', 'Nifty 200'], index=0)
period_list = ['1d', '5d', '1mo', '3mo', '6mo', '1y', '2y', '5y', '10y', 'ytd', 'max']
c1, c2 = st.columns(2)
with c1:
# Select strategy
strategy = st.selectbox("Select Strategy", ['Order Block', 'Order Block with EMA', 'Structure trading'], index=2)
with c2:
# Swing High/Low window size
swing_hl = st.number_input("Swing High/Low Window Size", min_value=1, value=10,
help = "Minimum window size for finding swing highs and lows.")
c1, c2 = st.columns(2)
with c1:
# Select interval
interval = st.selectbox("Select Interval", limits['interval'].tolist(), index=3)
with c2:
# Update period options based on interval
limit = limits[limits['interval'] == interval]['limit'].values[0]
idx = period_list.index(limit)
period_options = period_list[:idx + 1] + ['max']
period = st.selectbox("Select Period", period_options, index=2)
# EMA parameters if "Order Block with EMA" is selected
if strategy == "Order Block with EMA":
c1, c2, c3 = st.columns([2, 2, 1.5])
with c1:
ema1 = st.number_input("Fast EMA Length", min_value=1, value=9,
help = "Length of Fast moving Exponential Moving Average.")
with c2:
ema2 = st.number_input("Slow EMA Length", min_value=1, value=21,
help = "Length of Slow moving Exponential Moving Average.")
with c3:
close_on_crossover = st.checkbox("Close trade on EMA crossover", value=False)
else:
ema1, ema2, close_on_crossover = None, None, None
with st.expander("Advanced options"):
c1, c2, c3 = st.columns([2, 2, 1])
with c1:
initial_cash = st.number_input("Initial Cash [₹]", min_value=10000, value=10000)
with c2:
commission = st.number_input("Commission [%]", value = 0, min_value=-10, max_value=10,
help="Commission is the commission ratio. E.g. if your broker's "
"commission is 1% of trade value, set commission to 1.")
with c3:
multiprocess = st.checkbox("Multiprocess", value=True,
help="Use multiple CPUs (if available) to parallelize the run. "
"Run time is inversely proportional to no of CPUs available.")
# Button to run the analysis
if st.button("Run"):
start = time.time()
results = complete_test(stock_list, strategy, period, interval, multiprocess,
swing_hl=swing_hl, ema1=ema1, ema2=ema2,
close_on_crossover=close_on_crossover, cash=initial_cash,
commission=commission/100)
results['Select'] = False
st.session_state.categorized_results = categorize_df(results, 'Sector', 'Return [%]')
st.success(f"Analysis finished in {round(time.time()-start, 2)} seconds")
if "categorized_results" in st.session_state:
# st.write("⬇️ Select a row in index column to get detailed information of the respective stock run.")
st.markdown(f"""
---
### :orange[{stock_list} stocks backtest result by using {strategy} strategy]
⬇️ Select rows in 'Select' column to get backtest plots of the selected stocks.
""")
cols = ['Select', 'Stock', 'Sector', 'Start', 'End', 'Return [%]', 'Equity Final [₹]', 'Buy & Hold Return [%]', '# Trades', 'Win Rate [%]', 'Best Trade [%]', 'Worst Trade [%]', 'Avg. Trade [%]']
st.session_state.categorized_results_dict = {}
st.session_state.selected_stocks = {}
for category, df in st.session_state.categorized_results.items():
mean = round(df['Return [%]'].mean(), 2)
color = "green" if mean > 0 else "red"
with st.expander(f"{str(category).upper()} :{color}[Average return rate: {mean} %]"):
st.session_state.categorized_results_dict[category] = (
st.data_editor(df,
column_config={
'Select': st.column_config.CheckboxColumn(
'Select',
default=False
)
},
hide_index=True, column_order=cols,
# on_select="rerun", selection_mode="single-row"
))
st.session_state.selected_stocks[category] = (
np.where(st.session_state.categorized_results_dict[category]['Select']))[0]
for selected_rows in st.session_state.selected_stocks.values():
if len(selected_rows) > 0:
st.toast("Scroll to the bottom of page to view backtest plots.", icon=":material/vertical_align_bottom:")
st.markdown(f"""
---
### :orange[Selected stocks backtest plots by using {strategy} strategy]
""")
break
# for selected_rows in st.session_state.selected_stocks.values():
# for row in selected_rows:
# ticker = st.session_state.results['Stock'].values[row]
# plot = st.session_state.results['plot'].values[row]
# color = "green" if st.session_state.results['Return [%]'].values[row] > 0 else "red"
# with st.expander(f":{color}[{ticker} backtest plot] 📊"):
# components.html(plot, height=900)
complete_backtest() |