GoshawkVortexAI commited on
Commit
d67afaf
·
verified ·
1 Parent(s): 721191e

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -341
app.py DELETED
@@ -1,341 +0,0 @@
1
- """
2
- EURUSD Pattern AI - yfinance + Gradio
3
- Candlestick pattern tespiti ve AI yorumu
4
- """
5
-
6
- import gradio as gr
7
- import yfinance as yf
8
- import pandas as pd
9
- import numpy as np
10
- import plotly.graph_objects as go
11
- from datetime import datetime, timedelta
12
-
13
- # ─── PATTERN TESPİT FONKSİYONLARI ───────────────────────────────────────────
14
-
15
- def detect_patterns(df):
16
- """Temel candlestick patternleri tespit eder."""
17
- patterns = []
18
- df = df.copy()
19
-
20
- o = df["Open"].values
21
- h = df["High"].values
22
- l = df["Low"].values
23
- c = df["Close"].values
24
- dates = df.index
25
-
26
- for i in range(2, len(df)):
27
- found = []
28
-
29
- body = abs(c[i] - o[i])
30
- body_prev = abs(c[i-1] - o[i-1])
31
- rng = h[i] - l[i]
32
- upper_wick = h[i] - max(c[i], o[i])
33
- lower_wick = min(c[i], o[i]) - l[i]
34
-
35
- # Doji
36
- if body < rng * 0.1:
37
- found.append("🔵 Doji")
38
-
39
- # Hammer
40
- if (lower_wick > body * 2 and upper_wick < body * 0.5
41
- and c[i-1] < o[i-1]):
42
- found.append("🟢 Hammer (Bullish)")
43
-
44
- # Shooting Star
45
- if (upper_wick > body * 2 and lower_wick < body * 0.5
46
- and c[i-1] > o[i-1]):
47
- found.append("🔴 Shooting Star (Bearish)")
48
-
49
- # Bullish Engulfing
50
- if (c[i-1] < o[i-1] and c[i] > o[i]
51
- and c[i] > o[i-1] and o[i] < c[i-1]):
52
- found.append("🟢 Bullish Engulfing")
53
-
54
- # Bearish Engulfing
55
- if (c[i-1] > o[i-1] and c[i] < o[i]
56
- and c[i] < o[i-1] and o[i] > c[i-1]):
57
- found.append("🔴 Bearish Engulfing")
58
-
59
- # Morning Star
60
- if (i >= 2 and c[i-2] < o[i-2]
61
- and body_prev < abs(c[i-2] - o[i-2]) * 0.3
62
- and c[i] > o[i]
63
- and c[i] > (c[i-2] + o[i-2]) / 2):
64
- found.append("🟢 Morning Star")
65
-
66
- # Evening Star
67
- if (i >= 2 and c[i-2] > o[i-2]
68
- and body_prev < abs(c[i-2] - o[i-2]) * 0.3
69
- and c[i] < o[i]
70
- and c[i] < (c[i-2] + o[i-2]) / 2):
71
- found.append("🔴 Evening Star")
72
-
73
- # Three White Soldiers
74
- if (i >= 2
75
- and c[i] > o[i] and c[i-1] > o[i-1] and c[i-2] > o[i-2]
76
- and c[i] > c[i-1] > c[i-2]):
77
- found.append("🟢 Three White Soldiers")
78
-
79
- # Three Black Crows
80
- if (i >= 2
81
- and c[i] < o[i] and c[i-1] < o[i-1] and c[i-2] < o[i-2]
82
- and c[i] < c[i-1] < c[i-2]):
83
- found.append("🔴 Three Black Crows")
84
-
85
- # Spinning Top
86
- if (body < rng * 0.3 and upper_wick > body and lower_wick > body):
87
- found.append("🔵 Spinning Top")
88
-
89
- if found:
90
- patterns.append({
91
- "Tarih": dates[i].strftime("%Y-%m-%d %H:%M") if hasattr(dates[i], "hour") else str(dates[i])[:10],
92
- "Pattern": ", ".join(found),
93
- "Close": round(c[i], 5),
94
- "Yön": "↑ Bullish" if any("Bullish" in p or "Hammer" in p or "Soldier" in p or "Morning" in p for p in found)
95
- else ("↓ Bearish" if any("Bearish" in p or "Star" in p or "Crow" in p or "Evening" in p for p in found)
96
- else "↔ Nötr"),
97
- })
98
-
99
- return patterns[-30:] if len(patterns) > 30 else patterns # son 30 pattern
100
-
101
-
102
- def calculate_indicators(df):
103
- """RSI, EMA, Bollinger hesaplar."""
104
- df = df.copy()
105
-
106
- # EMA
107
- df["EMA20"] = df["Close"].ewm(span=20).mean()
108
- df["EMA50"] = df["Close"].ewm(span=50).mean()
109
-
110
- # RSI
111
- delta = df["Close"].diff()
112
- gain = delta.clip(lower=0).rolling(14).mean()
113
- loss = (-delta.clip(upper=0)).rolling(14).mean()
114
- rs = gain / loss
115
- df["RSI"] = 100 - (100 / (1 + rs))
116
-
117
- # Bollinger
118
- df["BB_mid"] = df["Close"].rolling(20).mean()
119
- std = df["Close"].rolling(20).std()
120
- df["BB_upper"] = df["BB_mid"] + 2 * std
121
- df["BB_lower"] = df["BB_mid"] - 2 * std
122
-
123
- # MACD
124
- ema12 = df["Close"].ewm(span=12).mean()
125
- ema26 = df["Close"].ewm(span=26).mean()
126
- df["MACD"] = ema12 - ema26
127
- df["Signal"] = df["MACD"].ewm(span=9).mean()
128
-
129
- return df
130
-
131
-
132
- def build_chart(df, patterns):
133
- """Plotly candlestick + indikatör grafiği oluşturur."""
134
- fig = go.Figure()
135
-
136
- # Candlestick
137
- fig.add_trace(go.Candlestick(
138
- x=df.index, open=df["Open"], high=df["High"],
139
- low=df["Low"], close=df["Close"],
140
- name="EUR/USD", increasing_line_color="#26a69a",
141
- decreasing_line_color="#ef5350"
142
- ))
143
-
144
- # EMA
145
- fig.add_trace(go.Scatter(x=df.index, y=df["EMA20"], name="EMA 20",
146
- line=dict(color="#FFA726", width=1.2)))
147
- fig.add_trace(go.Scatter(x=df.index, y=df["EMA50"], name="EMA 50",
148
- line=dict(color="#AB47BC", width=1.2)))
149
-
150
- # Bollinger
151
- fig.add_trace(go.Scatter(x=df.index, y=df["BB_upper"], name="BB Üst",
152
- line=dict(color="#607D8B", dash="dot", width=1)))
153
- fig.add_trace(go.Scatter(x=df.index, y=df["BB_lower"], name="BB Alt",
154
- line=dict(color="#607D8B", dash="dot", width=1),
155
- fill="tonexty", fillcolor="rgba(96,125,139,0.07)"))
156
-
157
- # Pattern işaretleri
158
- for p in patterns[-10:]:
159
- try:
160
- dt = pd.to_datetime(p["Tarih"])
161
- row = df[df.index.date == dt.date()] if hasattr(df.index[0], "date") else df[df.index == p["Tarih"]]
162
- if not row.empty:
163
- y_pos = row["High"].values[0] * 1.001
164
- color = "#26a69a" if "↑" in p["Yön"] else ("#ef5350" if "↓" in p["Yön"] else "#FFA726")
165
- fig.add_annotation(x=row.index[0], y=y_pos,
166
- text=p["Pattern"].split(",")[0][2:],
167
- showarrow=True, arrowhead=2,
168
- font=dict(size=9, color=color),
169
- arrowcolor=color)
170
- except Exception:
171
- pass
172
-
173
- fig.update_layout(
174
- title="EUR/USD – Candlestick + İndikatörler",
175
- template="plotly_dark",
176
- xaxis_rangeslider_visible=False,
177
- height=550,
178
- legend=dict(orientation="h", y=1.02),
179
- margin=dict(l=40, r=20, t=50, b=20),
180
- font=dict(family="Inter, sans-serif"),
181
- paper_bgcolor="#0f1117",
182
- plot_bgcolor="#0f1117",
183
- )
184
- return fig
185
-
186
-
187
- def ai_summary(df, patterns):
188
- """Kural tabanlı AI yorumu üretir."""
189
- if df is None or df.empty:
190
- return "Veri yok."
191
-
192
- latest = df.iloc[-1]
193
- rsi = round(latest["RSI"], 1)
194
- macd = latest["MACD"]
195
- signal = latest["Signal"]
196
- close = round(latest["Close"], 5)
197
- ema20 = round(latest["EMA20"], 5)
198
- ema50 = round(latest["EMA50"], 5)
199
- bb_upper = round(latest["BB_upper"], 5)
200
- bb_lower = round(latest["BB_lower"], 5)
201
-
202
- lines = [f"### 🤖 AI Pattern & İndikatör Analizi\n"]
203
- lines.append(f"**Son Fiyat:** {close} | **RSI(14):** {rsi}")
204
- lines.append(f"**EMA20:** {ema20} | **EMA50:** {ema50}")
205
- lines.append(f"**BB Üst:** {bb_upper} | **BB Alt:** {bb_lower}\n")
206
-
207
- # Trend
208
- if close > ema20 > ema50:
209
- lines.append("📈 **Trend:** Güçlü Yükseliş – Fiyat her iki EMA'nın üzerinde.")
210
- elif close < ema20 < ema50:
211
- lines.append("📉 **Trend:** Güçlü Düşüş – Fiyat her iki EMA'nın altında.")
212
- elif close > ema20:
213
- lines.append("↗️ **Trend:** Kısa vadeli yükseliş, ancak EMA50 henüz kırılmadı.")
214
- else:
215
- lines.append("↘️ **Trend:** Kısa vadeli zayıflık.")
216
-
217
- # RSI
218
- if rsi > 70:
219
- lines.append(f"⚠️ **RSI {rsi}** – Aşırı alım bölgesi, düzeltme riski.")
220
- elif rsi < 30:
221
- lines.append(f"✅ **RSI {rsi}** – Aşırı satım bölgesi, toparlanma ihtimali.")
222
- else:
223
- lines.append(f"🔵 **RSI {rsi}** – Nötr bölgede.")
224
-
225
- # MACD
226
- if macd > signal:
227
- lines.append("✅ **MACD** Sinyal üzerinde – Momentum pozitif.")
228
- else:
229
- lines.append("⚠️ **MACD** Sinyal altında – Momentum negatif.")
230
-
231
- # Bollinger
232
- if close > bb_upper:
233
- lines.append("🔴 Fiyat **Bollinger Üst Bandı** dışında – Aşırı alım.")
234
- elif close < bb_lower:
235
- lines.append("🟢 Fiyat **Bollinger Alt Bandı** dışında – Aşırı satım.")
236
-
237
- # Son patternler
238
- if patterns:
239
- last = patterns[-3:]
240
- lines.append(f"\n**Son Tespit Edilen Patternler:**")
241
- for p in reversed(last):
242
- lines.append(f"- `{p['Tarih']}` → {p['Pattern']} {p['Yön']}")
243
-
244
- # Genel yorum
245
- bull_count = sum(1 for p in patterns[-10:] if "↑" in p.get("Yön", ""))
246
- bear_count = sum(1 for p in patterns[-10:] if "↓" in p.get("Yön", ""))
247
- lines.append(f"\n**Son 10 Pattern:** 🟢 {bull_count} Bullish | 🔴 {bear_count} Bearish")
248
-
249
- if bull_count > bear_count and rsi < 65 and macd > signal:
250
- lines.append("\n> 💡 **Genel Görünüm:** Birden fazla gösterge **yükseliş** yönünde hizalanmış.")
251
- elif bear_count > bull_count and rsi > 40 and macd < signal:
252
- lines.append("\n> 💡 **Genel Görünüm:** Birden fazla gösterge **düşüş** yönünde hizalanmış.")
253
- else:
254
- lines.append("\n> 💡 **Genel Görünüm:** Sinyaller karışık, dikkatli izlenebilir.")
255
-
256
- lines.append("\n---\n*Bu analiz yatırım tavsiyesi değildir.*")
257
- return "\n".join(lines)
258
-
259
-
260
- # ─── ANA FONKSİYON ───────────────────────────────────────────────────────────
261
-
262
- def analyze(period, interval):
263
- """Veri çek, analiz et, grafik + tablo + özet döndür."""
264
- try:
265
- ticker = "EURUSD=X"
266
- df = yf.download(ticker, period=period, interval=interval,
267
- auto_adjust=True, progress=False)
268
-
269
- if df.empty:
270
- return None, pd.DataFrame(), "⚠️ Veri alınamadı. Dönem/interval kombinasyonu geçersiz olabilir."
271
-
272
- # Çok seviyeli sütunları düzleştir
273
- if isinstance(df.columns, pd.MultiIndex):
274
- df.columns = df.columns.get_level_values(0)
275
-
276
- df = calculate_indicators(df)
277
- patterns = detect_patterns(df)
278
- fig = build_chart(df, patterns)
279
- summary = ai_summary(df, patterns)
280
-
281
- pat_df = pd.DataFrame(patterns) if patterns else pd.DataFrame(
282
- columns=["Tarih", "Pattern", "Close", "Yön"])
283
-
284
- return fig, pat_df, summary
285
-
286
- except Exception as e:
287
- return None, pd.DataFrame(), f"❌ Hata: {str(e)}"
288
-
289
-
290
- # ─── GRADIO ARAYÜZÜ ──────────────────────────────────────────────────────────
291
-
292
- PERIOD_CHOICES = ["1d", "5d", "1mo", "3mo", "6mo", "1y"]
293
- INTERVAL_CHOICES = ["15m", "30m", "1h", "4h", "1d"]
294
-
295
- with gr.Blocks(
296
- title="EUR/USD Pattern AI",
297
- theme=gr.themes.Base(
298
- primary_hue="teal",
299
- neutral_hue="slate",
300
- font=[gr.themes.GoogleFont("Inter"), "sans-serif"],
301
- ),
302
- css="""
303
- body { background: #0f1117 !important; }
304
- .gradio-container { max-width: 1100px !important; }
305
- #title { text-align: center; padding: 16px 0 4px; }
306
- #subtitle { text-align: center; color: #94a3b8; margin-bottom: 8px; font-size: 0.9em; }
307
- """
308
- ) as demo:
309
-
310
- gr.HTML("<h1 id='title'>📊 EUR/USD Pattern AI</h1>")
311
- gr.HTML("<p id='subtitle'>yfinance • Candlestick Pattern Tespiti • Teknik İndikatörler</p>")
312
-
313
- with gr.Row():
314
- period_dd = gr.Dropdown(PERIOD_CHOICES, value="1mo", label="Dönem")
315
- interval_dd = gr.Dropdown(INTERVAL_CHOICES, value="1d", label="Interval")
316
- run_btn = gr.Button("🔍 Analiz Et", variant="primary", scale=1)
317
-
318
- chart_out = gr.Plot(label="Grafik")
319
- summary_out = gr.Markdown(label="AI Yorumu")
320
- table_out = gr.Dataframe(
321
- label="Tespit Edilen Patternler",
322
- headers=["Tarih", "Pattern", "Close", "Yön"],
323
- interactive=False,
324
- wrap=True,
325
- )
326
-
327
- run_btn.click(
328
- fn=analyze,
329
- inputs=[period_dd, interval_dd],
330
- outputs=[chart_out, table_out, summary_out],
331
- )
332
-
333
- # Sayfa yüklenince otomatik çalıştır
334
- demo.load(
335
- fn=analyze,
336
- inputs=[period_dd, interval_dd],
337
- outputs=[chart_out, table_out, summary_out],
338
- )
339
-
340
- if __name__ == "__main__":
341
- demo.launch()