Spaces:
Sleeping
Sleeping
File size: 8,801 Bytes
6892254 4e7b07f 6892254 1d08af5 6892254 cd6bc6e 1d08af5 8062c88 4e7b07f 8062c88 4e7b07f 1d08af5 6892254 8062c88 1d08af5 8062c88 6892254 0edd5a6 8062c88 4e7b07f d0d1f85 3d8dc02 6892254 3d8dc02 4e7b07f 6892254 1d08af5 3d8dc02 1d08af5 3d8dc02 1d08af5 3d8dc02 1d08af5 3d8dc02 4e7b07f 3d8dc02 4e7b07f 3d8dc02 4e7b07f 3d8dc02 4e7b07f 3d8dc02 4e7b07f 1d08af5 3d8dc02 1d08af5 4e7b07f 3d8dc02 4e7b07f 8062c88 4e7b07f 3d8dc02 4e7b07f 1d08af5 3d8dc02 6892254 3d8dc02 1d08af5 0edd5a6 1d08af5 3d8dc02 |
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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
import yfinance as yf
import talib
import pandas as pd
import streamlit as st
import plotly.graph_objects as go
# Set page configuration
st.set_page_config(layout="wide")
# Define pattern functions
pattern_funcs = [
("Two Crows", talib.CDL2CROWS),
("Three Black Crows", talib.CDL3BLACKCROWS),
("Three Inside Up/Down", talib.CDL3INSIDE),
("Three-Line Strike", talib.CDL3LINESTRIKE),
("Three Outside Up/Down", talib.CDL3OUTSIDE),
("Three Stars In The South", talib.CDL3STARSINSOUTH),
("Three Advancing White Soldiers", talib.CDL3WHITESOLDIERS),
("Abandoned Baby", talib.CDLABANDONEDBABY),
("Advance Block", talib.CDLADVANCEBLOCK),
("Belt-hold", talib.CDLBELTHOLD),
("Breakaway", talib.CDLBREAKAWAY),
("Closing Marubozu", talib.CDLCLOSINGMARUBOZU),
("Concealing Baby Swallow", talib.CDLCONCEALBABYSWALL),
("Counterattack", talib.CDLCOUNTERATTACK),
("Dark Cloud Cover", talib.CDLDARKCLOUDCOVER),
("Doji", talib.CDLDOJI),
("Doji Star", talib.CDLDOJISTAR),
("Dragonfly Doji", talib.CDLDRAGONFLYDOJI),
("Engulfing Pattern", talib.CDLENGULFING),
("Evening Doji Star", talib.CDLEVENINGDOJISTAR),
("Evening Star", talib.CDLEVENINGSTAR),
("Up/Down-gap side-by-side white lines", talib.CDLGAPSIDESIDEWHITE),
("Gravestone Doji", talib.CDLGRAVESTONEDOJI),
("Hammer", talib.CDLHAMMER),
("Hanging Man", talib.CDLHANGINGMAN),
("Harami Pattern", talib.CDLHARAMI),
("Harami Cross Pattern", talib.CDLHARAMICROSS),
("High-Wave Candle", talib.CDLHIGHWAVE),
("Hikkake Pattern", talib.CDLHIKKAKE),
("Modified Hikkake Pattern", talib.CDLHIKKAKEMOD),
("Homing Pigeon", talib.CDLHOMINGPIGEON),
("Identical Three Crows", talib.CDLIDENTICAL3CROWS),
("In-Neck Pattern", talib.CDLINNECK),
("Inverted Hammer", talib.CDLINVERTEDHAMMER),
("Kicking", talib.CDLKICKING),
("Kicking - bull/bear determined by the longer marubozu", talib.CDLKICKINGBYLENGTH),
("Ladder Bottom", talib.CDLLADDERBOTTOM),
("Long Legged Doji", talib.CDLLONGLEGGEDDOJI),
("Long Line Candle", talib.CDLLONGLINE),
("Marubozu", talib.CDLMARUBOZU),
("Matching Low", talib.CDLMATCHINGLOW),
("Mat Hold", talib.CDLMATHOLD),
("Morning Doji Star", talib.CDLMORNINGDOJISTAR),
("Morning Star", talib.CDLMORNINGSTAR),
("On-Neck Pattern", talib.CDLONNECK),
("Piercing Pattern", talib.CDLPIERCING),
("Rickshaw Man", talib.CDLRICKSHAWMAN),
("Rising/Falling Three Methods", talib.CDLRISEFALL3METHODS),
("Separating Lines", talib.CDLSEPARATINGLINES),
("Shooting Star", talib.CDLSHOOTINGSTAR),
("Short Line Candle", talib.CDLSHORTLINE),
("Spinning Top", talib.CDLSPINNINGTOP),
("Stalled Pattern", talib.CDLSTALLEDPATTERN),
("Stick Sandwich", talib.CDLSTICKSANDWICH),
("Takuri (Dragonfly Doji with very long lower shadow)", talib.CDLTAKURI),
("Tasuki Gap", talib.CDLTASUKIGAP),
("Thrusting Pattern", talib.CDLTHRUSTING),
("Tristar Pattern", talib.CDLTRISTAR),
("Unique 3 River", talib.CDLUNIQUE3RIVER),
("Upside Gap Two Crows", talib.CDLUPSIDEGAP2CROWS),
("Upside/Downside Gap Three Methods", talib.CDLXSIDEGAP3METHODS)
]
# Streamlit app setup
st.title('Automatic Candlestick Pattern Detection')
st.write("""
This tool automatically detects 60+ candlestick patterns in stock or crypto price data.
* You can input the stock ticker (e.g. 'AAPL') or crypto pair (e.g. 'BTC-USD'), start date, and end date in the sidebar menu to analyze.
* The tool will fetch the historical data and highlight detected patterns on the charts.
* The charts display the asset price data along with vertical lines indicating where patterns were found.
* If no patterns are detected, the chart for that pattern will not be included.
""")
# Sidebar for input parameters
with st.sidebar.expander("Input Parameters", expanded=True):
symbol = st.text_input('Enter Asset Symbol', 'BTC-USD', help="Input the ticker symbol for the stock or crypto pair.")
start_date = st.date_input('Start Date', pd.to_datetime('2023-06-01'), help="Select the start date for the analysis.")
end_date = st.date_input('End Date', pd.to_datetime(pd.Timestamp.now().date() + pd.Timedelta(days=1)), help="Select the end date for the analysis.")
# Moving averages inside an expander, closed by default
with st.sidebar.expander("Moving Average Parameters", expanded=False):
ma_short_period = st.number_input('Short-term Moving Average Period', min_value=1, value=20, help="Set the period for the short-term moving average.")
ma_long_period = st.number_input('Long-term Moving Average Period', min_value=1, value=50, help="Set the period for the long-term moving average.")
# Place the Run Analysis button above the candlestick pattern checkboxes
if st.sidebar.button('Run Analysis'):
run_analysis = True
else:
run_analysis = False
# Candlestick patterns selection inside an expander, open by default
with st.sidebar.expander("Candlestick Patterns", expanded=True):
selected_patterns = {name: st.checkbox(name, value=True) for name, func in pattern_funcs}
if run_analysis:
# Fetch data with yfinance adjustments
data = yf.download(symbol, start=start_date, end=end_date, auto_adjust=False)
if isinstance(data.columns, pd.MultiIndex):
data.columns = data.columns.get_level_values(0)
if not data.empty:
# Calculate moving averages based on user input with NaN handling
data[f'MA{ma_short_period}'] = talib.SMA(data['Close'], timeperiod=ma_short_period)
data[f'MA{ma_long_period}'] = talib.SMA(data['Close'], timeperiod=ma_long_period)
for pattern_name, pattern_func in pattern_funcs:
if selected_patterns[pattern_name]:
# Calculate pattern with TALib and handle potential NaNs
data[pattern_name] = pattern_func(data['Open'], data['High'], data['Low'], data['Close'])
pattern_dates = data[data[pattern_name].notna() & (data[pattern_name] != 0)].index
if len(pattern_dates) == 0:
st.write(f"No {pattern_name} patterns detected for {symbol} in the selected date range.")
continue
# Create Plotly figure
fig = go.Figure()
# Candlestick chart
fig.add_trace(go.Candlestick(
x=data.index,
open=data['Open'],
high=data['High'],
low=data['Low'],
close=data['Close'],
name='Candlesticks',
yaxis='y2'
))
# Short-term moving average
fig.add_trace(go.Scatter(
x=data.index,
y=data[f'MA{ma_short_period}'],
mode='lines',
line=dict(color='blue', width=1.5),
name=f'{ma_short_period}-day MA',
yaxis='y2'
))
# Long-term moving average
fig.add_trace(go.Scatter(
x=data.index,
y=data[f'MA{ma_long_period}'],
mode='lines',
line=dict(color='orange', width=1.5),
name=f'{ma_long_period}-day MA',
yaxis='y2'
))
# Volume bars
fig.add_trace(go.Bar(
x=data.index,
y=data['Volume'],
name='Volume',
yaxis='y',
marker=dict(color='grey'),
opacity=0.5
))
# Add vertical lines for pattern detection
for date in pattern_dates:
fig.add_vline(x=date, line=dict(color='red', width=2, dash='dash'), name=pattern_name)
# Update layout
fig.update_layout(
title=f"{symbol} Price and {pattern_name} Pattern Detection",
xaxis_title="Date",
yaxis=dict(title='Volume'),
yaxis2=dict(title='Price', overlaying='y', side='right'),
legend_title="Legend",
xaxis_rangeslider_visible=False,
template='plotly_white',
height=600
)
st.plotly_chart(fig, use_container_width=True)
else:
st.error(f"No data found for {symbol} in the given date range ({start_date} to {end_date}).")
# Hide the Streamlit style
hide_streamlit_style = """
<style>
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
</style>
"""
st.markdown(hide_streamlit_style, unsafe_allow_html=True) |