Add a slow, rare-signal MS->W1->D1 (monthly/weekly/daily) Ichimoku alignment EA variant for multi-week/month trend trades, plus a daily no-VPS Python monitor (GitHub Actions cron + Telegram) that computes the same alignment from independent Yahoo data. Watch list covers crypto, metals, US indices, and common trending FX majors. Document both in README and EXPERIMENTAL-NOTES.
53 lines
1.5 KiB
Python
53 lines
1.5 KiB
Python
"""Data layer: fetch daily OHLC and resample to completed weekly/monthly bars.
|
|
|
|
Weekly bars are Friday-labelled, monthly bars are month-end labelled (both
|
|
label by period *end*, matching MT5's bar time). A bucket whose label lands
|
|
after the last available daily bar is still forming and is dropped, so every
|
|
bar fed to the alignment check is a completed one.
|
|
"""
|
|
|
|
import pandas as pd
|
|
import yfinance as yf
|
|
|
|
import config
|
|
|
|
|
|
def fetch_daily(ticker):
|
|
"""Daily OHLC for `ticker`, oldest -> newest, with lower-case columns."""
|
|
df = yf.download(
|
|
ticker,
|
|
period=config.HISTORY,
|
|
interval="1d",
|
|
auto_adjust=False,
|
|
progress=False,
|
|
threads=False,
|
|
)
|
|
if df is None or df.empty:
|
|
return None
|
|
df = df[["Open", "High", "Low", "Close"]].dropna()
|
|
df.columns = ["open", "high", "low", "close"]
|
|
df.index = pd.to_datetime(df.index)
|
|
df = df[~df.index.duplicated(keep="last")].sort_index()
|
|
return df
|
|
|
|
|
|
def resample(df, rule):
|
|
grouped = df.resample(rule)
|
|
out = pd.DataFrame(
|
|
{
|
|
"open": grouped["open"].first(),
|
|
"high": grouped["high"].max(),
|
|
"low": grouped["low"].min(),
|
|
"close": grouped["close"].last(),
|
|
}
|
|
).dropna()
|
|
return out
|
|
|
|
|
|
def resample_completed(df, rule):
|
|
"""Resample to `rule` and drop a trailing bucket that is still forming."""
|
|
out = resample(df, rule)
|
|
if len(out) > 1 and out.index[-1] > df.index[-1]:
|
|
out = out.iloc[:-1]
|
|
return out
|