- Add advanced metrics dashboard with trade analytics - Add new trading components (EntryTypeAnalysis, MultiDayPositionTracker, NewsEventTracker, etc.) - Add strategy mode selector and trend confirmation - Add risk automation panel and slippage correlation analysis - Add daily trading plan enhancements with modal components - Add custom hooks (useApi, useLocalStorage, useAdvancedTradeMetrics) - Add broker service integration and trading API - Add test setup and vitest configuration - Include parquet data files for live market data - Add comprehensive documentation in docs/ folder
69 lines
2.1 KiB
Python
69 lines
2.1 KiB
Python
#!/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()
|