Spaces:
Sleeping
Sleeping
Upload 2 files
Browse files- app.py +83 -0
- requirements.txt +4 -0
app.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import yfinance as yf
|
| 3 |
+
import pandas as pd
|
| 4 |
+
import numpy as np
|
| 5 |
+
|
| 6 |
+
def ema(s, n):
|
| 7 |
+
return s.ewm(span=int(n), adjust=False).mean()
|
| 8 |
+
|
| 9 |
+
def rsi(s, n=9):
|
| 10 |
+
d=s.diff()
|
| 11 |
+
up=d.clip(lower=0).ewm(alpha=1/n, adjust=False).mean()
|
| 12 |
+
dn=(-d.clip(upper=0)).ewm(alpha=1/n, adjust=False).mean()
|
| 13 |
+
rs=up/dn.replace(0,np.nan)
|
| 14 |
+
return 100-100/(1+rs)
|
| 15 |
+
|
| 16 |
+
def analyze(ticker, interval, period, module):
|
| 17 |
+
try:
|
| 18 |
+
df=yf.download(ticker, period=period, interval=interval,
|
| 19 |
+
auto_adjust=False, progress=False, threads=False)
|
| 20 |
+
if df is None or df.empty:
|
| 21 |
+
return "Yahoo Finance veri döndürmedi. Sembol veya zaman aralığını kontrol edin.", None
|
| 22 |
+
if isinstance(df.columns, pd.MultiIndex):
|
| 23 |
+
df.columns=df.columns.get_level_values(0)
|
| 24 |
+
df=df.rename(columns=str.title)
|
| 25 |
+
need={"Open","High","Low","Close"}
|
| 26 |
+
if not need.issubset(df.columns):
|
| 27 |
+
return f"OHLC sütunları bulunamadı: {list(df.columns)}", None
|
| 28 |
+
c=df["Close"]
|
| 29 |
+
df["MACD"]=ema(c,8)-ema(c,17)
|
| 30 |
+
df["MACD_Signal"]=ema(df["MACD"],9)
|
| 31 |
+
df["RSI_9"]=rsi(c,9)
|
| 32 |
+
tp=(df["High"]+df["Low"]+c)/3
|
| 33 |
+
mean=tp.rolling(13).mean()
|
| 34 |
+
mad=tp.rolling(13).apply(lambda x: np.mean(np.abs(x-np.mean(x))),raw=True)
|
| 35 |
+
df["CCI_13"]=(tp-mean)/(0.015*mad.replace(0,np.nan))
|
| 36 |
+
ll=df["Low"].rolling(5).min()
|
| 37 |
+
hh=df["High"].rolling(5).max()
|
| 38 |
+
df["Stoch_K"]=100*(c-ll)/(hh-ll).replace(0,np.nan)
|
| 39 |
+
df["Stoch_D"]=df["Stoch_K"].rolling(3).mean()
|
| 40 |
+
df["EMA_5"]=ema(c,5)
|
| 41 |
+
df["EMA_9"]=ema(c,9)
|
| 42 |
+
bullish=(df["MACD"]>df["MACD_Signal"]) & (df["EMA_5"]>df["EMA_9"])
|
| 43 |
+
bearish=(df["MACD"]<df["MACD_Signal"]) & (df["EMA_5"]<df["EMA_9"])
|
| 44 |
+
df["Signal"]=np.select([bullish,bearish],["BUY","SELL"],default="HOLD")
|
| 45 |
+
last=df.iloc[-1]
|
| 46 |
+
# EA module's visible initial-entry logic uses candle direction and H1 RSI(14) guard.
|
| 47 |
+
h1=yf.download(ticker,period="60d",interval="1h",auto_adjust=False,progress=False,threads=False)
|
| 48 |
+
if isinstance(h1.columns,pd.MultiIndex): h1.columns=h1.columns.get_level_values(0)
|
| 49 |
+
h1rsi=rsi(h1["Close"],14).iloc[-2] if h1 is not None and len(h1)>15 else np.nan
|
| 50 |
+
candle="BUY bias" if len(df)>2 and df["Close"].iloc[-2] > df["Close"].iloc[-3] else "SELL bias"
|
| 51 |
+
if module=="EA entry filter":
|
| 52 |
+
signal=("BUY condition" if candle=="BUY bias" and h1rsi>30 else
|
| 53 |
+
"SELL condition" if candle=="SELL bias" and h1rsi<70 else "No entry condition")
|
| 54 |
+
else:
|
| 55 |
+
signal=str(last["Signal"])
|
| 56 |
+
report=(f"## {ticker} · {interval}\\n"
|
| 57 |
+
f"**Last close:** {float(last['Close']):.6g} \\n"
|
| 58 |
+
f"**Selected view:** {signal} \\n"
|
| 59 |
+
f"**EA-style candle filter:** {candle} · H1 RSI(14): {h1rsi:.2f} \\n"
|
| 60 |
+
f"**MACD(8,17,9):** {last['MACD']:.6g} / signal {last['MACD_Signal']:.6g} \\n"
|
| 61 |
+
f"**RSI(9):** {last['RSI_9']:.2f} · **CCI(13):** {last['CCI_13']:.2f} \\n"
|
| 62 |
+
f"**Stochastic(5,3,3):** K {last['Stoch_K']:.2f} / D {last['Stoch_D']:.2f}\\n\\n"
|
| 63 |
+
f"Data source: Yahoo Finance via yfinance. Indicators are a research approximation; "
|
| 64 |
+
f"this app does not execute trades and is not a verified full EA port.")
|
| 65 |
+
cols=["Open","High","Low","Close"]+[x for x in ["Volume","MACD","MACD_Signal","RSI_9","CCI_13","Stoch_K","Stoch_D","EMA_5","EMA_9","Signal"] if x in df]
|
| 66 |
+
out=df[cols].tail(100).copy().reset_index()
|
| 67 |
+
return report,out
|
| 68 |
+
except Exception as e:
|
| 69 |
+
return f"Veri alınamadı: {e}",None
|
| 70 |
+
|
| 71 |
+
with gr.Blocks(title="AF Global Expert — Python Terminal",theme=gr.themes.Soft()) as demo:
|
| 72 |
+
gr.Markdown("# AF Global Expert · Python Terminal")
|
| 73 |
+
gr.Markdown("Yahoo Finance üzerinden OHLC verisi çeker. **Orijinal EA'nın birebir kopyası değildir; canlı emir göndermez.**")
|
| 74 |
+
with gr.Row():
|
| 75 |
+
ticker=gr.Textbox(label="Yahoo sembolü",value="EURUSD=X")
|
| 76 |
+
interval=gr.Dropdown(["1m","2m","5m","15m","30m","60m","1h","90m","1d","1wk"],value="1h",label="Zaman dilimi")
|
| 77 |
+
period=gr.Dropdown(["1d","5d","1mo","3mo","6mo","1y","2y","5y"],value="1y",label="Geçmiş")
|
| 78 |
+
module=gr.Radio(["İndikatör özeti","EA entry filter"],value="EA entry filter",label="Analiz modu")
|
| 79 |
+
btn=gr.Button("Yahoo Finance'tan veriyi çek ve analiz et",variant="primary")
|
| 80 |
+
result=gr.Markdown()
|
| 81 |
+
table=gr.Dataframe(label="Son 100 mum",interactive=False)
|
| 82 |
+
btn.click(analyze,[ticker,interval,period,module],[result,table])
|
| 83 |
+
demo.launch()
|
requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio>=4.44
|
| 2 |
+
yfinance>=0.2.65
|
| 3 |
+
pandas>=2.0
|
| 4 |
+
numpy>=1.24
|