77 lines
2.8 KiB
Python
77 lines
2.8 KiB
Python
from __future__ import annotations
|
|
import time
|
|
from typing import Dict
|
|
import pandas as pd
|
|
from config import CFG
|
|
from data import fetch_batch
|
|
from strategy import evaluate_signal
|
|
from portfolio import Portfolio
|
|
from io_utils import ensure_dirs, save_outputs
|
|
|
|
def interval_to_timedelta(interval: str) -> pd.Timedelta:
|
|
# prosta mapka dla 1m/2m/5m/15m/30m/60m/1h
|
|
mapping = {
|
|
"1m":"1min","2m":"2min","5m":"5min","15m":"15min","30m":"30min",
|
|
"60m":"60min","90m":"90min","1h":"60min"
|
|
}
|
|
key = mapping.get(interval, "1min")
|
|
return pd.to_timedelta(key)
|
|
|
|
if __name__ == "__main__":
|
|
ensure_dirs(CFG.root_dir, CFG.tickers)
|
|
portfolio = Portfolio(starting_cash=CFG.starting_cash, commission_per_trade=1.0, slippage_bp=1.0)
|
|
|
|
last_ts: Dict[str, pd.Timestamp] = {}
|
|
hist: Dict[str, pd.DataFrame] = {}
|
|
bar_delta = interval_to_timedelta(CFG.interval)
|
|
|
|
while True:
|
|
round_t0 = time.time()
|
|
batch = fetch_batch(CFG.tickers, CFG.yf_period, CFG.interval)
|
|
|
|
for tk, df in batch.items():
|
|
if df.empty:
|
|
continue
|
|
df = df.copy()
|
|
df.index = pd.to_datetime(df.index, utc=True)
|
|
|
|
prev = hist.get(tk)
|
|
if prev is not None and not prev.empty:
|
|
df_all = pd.concat([prev, df[~df.index.isin(prev.index)]], axis=0).sort_index()
|
|
else:
|
|
df_all = df.sort_index()
|
|
hist[tk] = df_all.tail(2000)
|
|
|
|
last = last_ts.get(tk)
|
|
new_part = df_all[df_all.index > last] if last is not None else df_all
|
|
|
|
if not new_part.empty:
|
|
for ts, row in new_part.iterrows():
|
|
o,h,l,c = float(row["open"]), float(row["high"]), float(row["low"]), float(row["close"])
|
|
|
|
# 1) egzekucja oczekujących na OPEN tego baraz
|
|
portfolio.on_new_bar(tk, ts, o,h,l,c)
|
|
|
|
# 2) sygnał na CLOSE → plan na KOLEJNY OPEN
|
|
df_upto = hist[tk].loc[:ts]
|
|
dec = evaluate_signal(df_upto)
|
|
portfolio.schedule_order(
|
|
tk, dec.signal, dec.rpu, dec.sl, dec.tp,
|
|
next_bar_ts=ts + pd.to_timedelta(1, unit="min"),
|
|
ref_price=float(df_upto["close"].iloc[-1])
|
|
)
|
|
|
|
last_ts[tk] = new_part.index[-1]
|
|
|
|
# zapis
|
|
import pandas as pd
|
|
trades_df = pd.DataFrame(portfolio.trades)
|
|
eq_df = pd.DataFrame(portfolio.portfolio_equity, columns=["time","equity"])
|
|
save_outputs(CFG.root_dir, CFG.tickers, trades_df, eq_df, portfolio.cash)
|
|
|
|
elapsed = time.time() - round_t0
|
|
sleep_s = max(0, 120 - elapsed)
|
|
print(f"Runda OK ({elapsed:.1f}s). Pauza {sleep_s:.1f}s.")
|
|
print(sleep_s)
|
|
time.sleep(sleep_s)
|