#!/usr/bin/env python3 """Utility script to pull historical bars from MetaTrader 5 into live_store. Run inside the backend virtualenv with DATA_PROVIDER=metatrader. """ import argparse from datetime import datetime, timedelta try: import MetaTrader5 as mt5 # type: ignore except Exception as exc: # pragma: no cover raise SystemExit("MetaTrader5 package not installed.") from exc from app.streaming.live_store import live_store def parse_args(): parser = argparse.ArgumentParser(description="Import MT5 history into live_store.") parser.add_argument("symbol", help="Symbol, e.g., XAUUSD") parser.add_argument("timeframe", help="MT5 timeframe, e.g., 1m, 5m, 1h", default="1m") parser.add_argument("bars", type=int, default=1000, nargs="?", help="Number of bars to fetch") return parser.parse_args() def resolve_timeframe(name: str): mapping = { "1m": mt5.TIMEFRAME_M1, "5m": mt5.TIMEFRAME_M5, "15m": mt5.TIMEFRAME_M15, "30m": mt5.TIMEFRAME_M30, "60m": mt5.TIMEFRAME_H1, "1h": mt5.TIMEFRAME_H1, "4h": mt5.TIMEFRAME_H4, "1d": mt5.TIMEFRAME_D1, } return mapping.get(name.lower(), mt5.TIMEFRAME_M1) def main(): args = parse_args() if not mt5.initialize(): raise SystemExit(f"Failed to initialize MetaTrader5: {mt5.last_error()}") timeframe = resolve_timeframe(args.timeframe) rates = mt5.copy_rates_from_pos(args.symbol, timeframe, 0, args.bars) if not rates: raise SystemExit("No rates returned. Check symbol/timeframe.") for row in rates: live_store.ingest_bar( symbol=args.symbol, timeframe=args.timeframe, bar={ "time": int(row['time']), "open": float(row['open']), "high": float(row['high']), "low": float(row['low']), "close": float(row['close']), "volume": float(row.get('tick_volume', 0.0)), }, ) print(f"Imported {len(rates)} bars for {args.symbol} {args.timeframe}") if __name__ == "__main__": main()