Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -2,7 +2,9 @@
|
|
| 2 |
TALib + mplfinance + Gradio
|
| 3 |
- Clean dashboard layout
|
| 4 |
- Pattern names without CDL
|
| 5 |
-
-
|
|
|
|
|
|
|
| 6 |
"""
|
| 7 |
|
| 8 |
import yfinance as yf
|
|
@@ -21,7 +23,15 @@ from typing import Optional, List
|
|
| 21 |
|
| 22 |
TALIB_PATTERNS = sorted([n for n in dir(talib) if n.startswith("CDL")])
|
| 23 |
PATTERN_DISPLAY_MAP = {n.replace("CDL", ""): n for n in TALIB_PATTERNS}
|
| 24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
|
| 26 |
# =====================================================
|
| 27 |
# Data utilities
|
|
@@ -88,8 +98,6 @@ def clean_ohlc(df: pd.DataFrame) -> pd.DataFrame:
|
|
| 88 |
def find_candlestick_patterns(df, talib_pattern):
|
| 89 |
func = getattr(talib, talib_pattern)
|
| 90 |
|
| 91 |
-
df = clean_ohlc(df)
|
| 92 |
-
|
| 93 |
o, h, l, c = (
|
| 94 |
df["Open"].values,
|
| 95 |
df["High"].values,
|
|
@@ -107,8 +115,9 @@ def find_candlestick_patterns(df, talib_pattern):
|
|
| 107 |
bull[s > 0] = df.loc[s > 0, "Low"] * 0.98
|
| 108 |
apds.append(
|
| 109 |
mpf.make_addplot(
|
| 110 |
-
bull, type="scatter",
|
| 111 |
-
|
|
|
|
| 112 |
)
|
| 113 |
)
|
| 114 |
|
|
@@ -117,53 +126,48 @@ def find_candlestick_patterns(df, talib_pattern):
|
|
| 117 |
bear[s < 0] = df.loc[s < 0, "High"] * 1.02
|
| 118 |
apds.append(
|
| 119 |
mpf.make_addplot(
|
| 120 |
-
bear, type="scatter",
|
| 121 |
-
|
|
|
|
| 122 |
)
|
| 123 |
)
|
| 124 |
|
| 125 |
-
return apds
|
| 126 |
|
| 127 |
# =====================================================
|
| 128 |
# Main plot function
|
| 129 |
# =====================================================
|
| 130 |
|
| 131 |
-
def plot_stock_with_patterns(symbol, start, end,
|
| 132 |
if not symbol:
|
| 133 |
return None, "Stock symbol required"
|
| 134 |
|
| 135 |
-
|
| 136 |
-
df = yf.download(symbol, start=start, end=end, progress=False)
|
| 137 |
-
except Exception as e:
|
| 138 |
-
return None, str(e)
|
| 139 |
-
|
| 140 |
if df.empty:
|
| 141 |
return None, "No data found"
|
| 142 |
|
| 143 |
-
|
| 144 |
-
df_clean = clean_ohlc(df)
|
| 145 |
-
except Exception as e:
|
| 146 |
-
return None, str(e)
|
| 147 |
|
| 148 |
addplots = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
|
| 150 |
-
|
| 151 |
-
talib_name = PATTERN_DISPLAY_MAP[name]
|
| 152 |
-
apds, err = find_candlestick_patterns(df_clean, talib_name)
|
| 153 |
-
if err:
|
| 154 |
-
return None, err
|
| 155 |
-
addplots.extend(apds)
|
| 156 |
|
| 157 |
os.makedirs("/tmp", exist_ok=True)
|
| 158 |
path = f"/tmp/{symbol}_{pd.Timestamp.now().strftime('%Y%m%d%H%M%S')}.png"
|
| 159 |
|
| 160 |
fig, _ = mpf.plot(
|
| 161 |
df_clean,
|
| 162 |
-
type=
|
| 163 |
-
volume="Volume" in df_clean.columns,
|
| 164 |
-
addplot=addplots if addplots else None,
|
| 165 |
style="yahoo",
|
| 166 |
-
title=f"{symbol} •
|
| 167 |
figscale=1.7,
|
| 168 |
returnfig=True
|
| 169 |
)
|
|
@@ -178,7 +182,7 @@ def plot_stock_with_patterns(symbol, start, end, selected):
|
|
| 178 |
with gr.Blocks(fill_height=True, theme=gr.themes.Soft()) as iface:
|
| 179 |
gr.Markdown(
|
| 180 |
"""
|
| 181 |
-
# 📊 TALib Candlestick Pattern Dashboard
|
| 182 |
**Bullish = Green â–² | Bearish = Red â–¼**
|
| 183 |
"""
|
| 184 |
)
|
|
@@ -189,45 +193,40 @@ with gr.Blocks(fill_height=True, theme=gr.themes.Soft()) as iface:
|
|
| 189 |
|
| 190 |
symbol = gr.Textbox(
|
| 191 |
label="Stock / Index Symbol",
|
| 192 |
-
value="MSFT"
|
| 193 |
-
placeholder="AAPL, MSFT, ^NSEI, ^GSPC"
|
| 194 |
)
|
| 195 |
|
| 196 |
-
start = gr.Textbox(
|
| 197 |
-
|
| 198 |
-
value="2024-01-01"
|
| 199 |
-
)
|
| 200 |
|
| 201 |
-
|
| 202 |
-
label="
|
| 203 |
-
|
|
|
|
| 204 |
)
|
| 205 |
|
| 206 |
-
|
| 207 |
-
label="Candlestick
|
| 208 |
choices=DISPLAY_PATTERNS,
|
| 209 |
-
value=
|
| 210 |
-
interactive=True
|
| 211 |
)
|
| 212 |
|
| 213 |
run = gr.Button("📈 Generate Chart", variant="primary")
|
| 214 |
-
|
| 215 |
-
status = gr.Textbox(
|
| 216 |
-
label="Status",
|
| 217 |
-
interactive=False
|
| 218 |
-
)
|
| 219 |
|
| 220 |
with gr.Column(scale=3):
|
| 221 |
-
gr.
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
|
|
|
|
|
|
| 227 |
|
| 228 |
run.click(
|
| 229 |
plot_stock_with_patterns,
|
| 230 |
-
inputs=[symbol, start, end,
|
| 231 |
outputs=[chart, status]
|
| 232 |
)
|
| 233 |
|
|
|
|
| 2 |
TALib + mplfinance + Gradio
|
| 3 |
- Clean dashboard layout
|
| 4 |
- Pattern names without CDL
|
| 5 |
+
- Chart type dropdown
|
| 6 |
+
- Pattern dropdown (auto-disabled for Line)
|
| 7 |
+
- Pattern name shown on chart
|
| 8 |
"""
|
| 9 |
|
| 10 |
import yfinance as yf
|
|
|
|
| 23 |
|
| 24 |
TALIB_PATTERNS = sorted([n for n in dir(talib) if n.startswith("CDL")])
|
| 25 |
PATTERN_DISPLAY_MAP = {n.replace("CDL", ""): n for n in TALIB_PATTERNS}
|
| 26 |
+
|
| 27 |
+
DISPLAY_PATTERNS = ["None"] + list(PATTERN_DISPLAY_MAP.keys())
|
| 28 |
+
|
| 29 |
+
# Chart type mapping
|
| 30 |
+
CHART_TYPE_MAP = {
|
| 31 |
+
"Candlestick": "candle",
|
| 32 |
+
"OHLC": "ohlc",
|
| 33 |
+
"Line": "line"
|
| 34 |
+
}
|
| 35 |
|
| 36 |
# =====================================================
|
| 37 |
# Data utilities
|
|
|
|
| 98 |
def find_candlestick_patterns(df, talib_pattern):
|
| 99 |
func = getattr(talib, talib_pattern)
|
| 100 |
|
|
|
|
|
|
|
| 101 |
o, h, l, c = (
|
| 102 |
df["Open"].values,
|
| 103 |
df["High"].values,
|
|
|
|
| 115 |
bull[s > 0] = df.loc[s > 0, "Low"] * 0.98
|
| 116 |
apds.append(
|
| 117 |
mpf.make_addplot(
|
| 118 |
+
bull, type="scatter",
|
| 119 |
+
marker="^", markersize=90,
|
| 120 |
+
color="green", alpha=0.85
|
| 121 |
)
|
| 122 |
)
|
| 123 |
|
|
|
|
| 126 |
bear[s < 0] = df.loc[s < 0, "High"] * 1.02
|
| 127 |
apds.append(
|
| 128 |
mpf.make_addplot(
|
| 129 |
+
bear, type="scatter",
|
| 130 |
+
marker="v", markersize=90,
|
| 131 |
+
color="red", alpha=0.85
|
| 132 |
)
|
| 133 |
)
|
| 134 |
|
| 135 |
+
return apds
|
| 136 |
|
| 137 |
# =====================================================
|
| 138 |
# Main plot function
|
| 139 |
# =====================================================
|
| 140 |
|
| 141 |
+
def plot_stock_with_patterns(symbol, start, end, chart_type, pattern):
|
| 142 |
if not symbol:
|
| 143 |
return None, "Stock symbol required"
|
| 144 |
|
| 145 |
+
df = yf.download(symbol, start=start, end=end, progress=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
if df.empty:
|
| 147 |
return None, "No data found"
|
| 148 |
|
| 149 |
+
df_clean = clean_ohlc(df)
|
|
|
|
|
|
|
|
|
|
| 150 |
|
| 151 |
addplots = []
|
| 152 |
+
pattern_label = ""
|
| 153 |
+
|
| 154 |
+
if chart_type != "Line" and pattern != "None":
|
| 155 |
+
talib_name = PATTERN_DISPLAY_MAP.get(pattern)
|
| 156 |
+
addplots = find_candlestick_patterns(df_clean, talib_name)
|
| 157 |
+
pattern_label = f" | Pattern: {pattern}"
|
| 158 |
|
| 159 |
+
mpf_type = CHART_TYPE_MAP[chart_type]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
|
| 161 |
os.makedirs("/tmp", exist_ok=True)
|
| 162 |
path = f"/tmp/{symbol}_{pd.Timestamp.now().strftime('%Y%m%d%H%M%S')}.png"
|
| 163 |
|
| 164 |
fig, _ = mpf.plot(
|
| 165 |
df_clean,
|
| 166 |
+
type=mpf_type,
|
| 167 |
+
volume="Volume" in df_clean.columns and mpf_type != "line",
|
| 168 |
+
addplot=addplots if addplots and mpf_type != "line" else None,
|
| 169 |
style="yahoo",
|
| 170 |
+
title=f"{symbol} • {chart_type}{pattern_label}",
|
| 171 |
figscale=1.7,
|
| 172 |
returnfig=True
|
| 173 |
)
|
|
|
|
| 182 |
with gr.Blocks(fill_height=True, theme=gr.themes.Soft()) as iface:
|
| 183 |
gr.Markdown(
|
| 184 |
"""
|
| 185 |
+
# 📊 TALib Candlestick Pattern Dashboard
|
| 186 |
**Bullish = Green â–² | Bearish = Red â–¼**
|
| 187 |
"""
|
| 188 |
)
|
|
|
|
| 193 |
|
| 194 |
symbol = gr.Textbox(
|
| 195 |
label="Stock / Index Symbol",
|
| 196 |
+
value="MSFT"
|
|
|
|
| 197 |
)
|
| 198 |
|
| 199 |
+
start = gr.Textbox(label="Start Date", value="2024-01-01")
|
| 200 |
+
end = gr.Textbox(label="End Date", value=date.today().strftime("%Y-%m-%d"))
|
|
|
|
|
|
|
| 201 |
|
| 202 |
+
chart_type = gr.Dropdown(
|
| 203 |
+
label="Chart Type",
|
| 204 |
+
choices=list(CHART_TYPE_MAP.keys()),
|
| 205 |
+
value="Candlestick"
|
| 206 |
)
|
| 207 |
|
| 208 |
+
pattern = gr.Dropdown(
|
| 209 |
+
label="Candlestick Pattern",
|
| 210 |
choices=DISPLAY_PATTERNS,
|
| 211 |
+
value="HAMMER"
|
|
|
|
| 212 |
)
|
| 213 |
|
| 214 |
run = gr.Button("📈 Generate Chart", variant="primary")
|
| 215 |
+
status = gr.Textbox(label="Status", interactive=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 216 |
|
| 217 |
with gr.Column(scale=3):
|
| 218 |
+
chart = gr.Image(type="filepath", height=720, show_label=False)
|
| 219 |
+
|
| 220 |
+
# 🔥 Auto-disable pattern when Line chart is selected
|
| 221 |
+
chart_type.change(
|
| 222 |
+
lambda ct: gr.update(interactive=(ct != "Line")),
|
| 223 |
+
inputs=chart_type,
|
| 224 |
+
outputs=pattern
|
| 225 |
+
)
|
| 226 |
|
| 227 |
run.click(
|
| 228 |
plot_stock_with_patterns,
|
| 229 |
+
inputs=[symbol, start, end, chart_type, pattern],
|
| 230 |
outputs=[chart, status]
|
| 231 |
)
|
| 232 |
|