update munend

This commit is contained in:
tinh
2026-03-21 10:38:38 +07:00
commit 0d5421e1e6
7 changed files with 155 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
pandas>=2.2.0
pyarrow>=15.0.0
MetaTrader5>=5.0.45
python-dateutil>=2.9.0
PyYAML>=6.0.1
@@ -0,0 +1,150 @@
"""
scripts/download_data.py
Usage example:
python scripts/download_data.py ^
--symbols EURUSD USDJPY GBPUSD USDCHF AUDUSD NZDUSD ^
--timeframes M15 H1 H4 ^
--start 2016-01-01 ^
--end 2026-01-01 ^
--output data/raw ^
--format parquet
"""
from __future__ import annotations
import argparse
import sys
from datetime import datetime
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from src.data.mt5_fetcher import MT5Config, MT5Fetcher # noqa: E402
DEFAULT_SYMBOLS = ["EURUSD", "USDJPY", "GBPUSD", "USDCHF", "AUDUSD", "NZDUSD"]
DEFAULT_TIMEFRAMES = ["M15", "H1", "H4"]
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Download Forex historical data from MT5")
parser.add_argument(
"--symbols",
nargs="+",
default=DEFAULT_SYMBOLS,
help="List of symbols to download",
)
parser.add_argument(
"--timeframes",
nargs="+",
default=DEFAULT_TIMEFRAMES,
help="List of timeframes, e.g. M15 H1 H4",
)
parser.add_argument(
"--start",
required=True,
help="Start date in YYYY-MM-DD",
)
parser.add_argument(
"--end",
required=True,
help="End date in YYYY-MM-DD",
)
parser.add_argument(
"--output",
default="data/raw",
help="Output directory",
)
parser.add_argument(
"--format",
choices=["parquet", "csv"],
default="parquet",
help="File format",
)
parser.add_argument(
"--terminal-path",
default=None,
help="Optional MT5 terminal path",
)
parser.add_argument(
"--login",
type=int,
default=None,
help="Optional MT5 login",
)
parser.add_argument(
"--password",
default=None,
help="Optional MT5 password",
)
parser.add_argument(
"--server",
default=None,
help="Optional MT5 server name",
)
return parser.parse_args()
def main() -> None:
args = parse_args()
start = datetime.fromisoformat(args.start)
end = datetime.fromisoformat(args.end)
output_dir = Path(args.output)
config = MT5Config(
terminal_path=args.terminal_path,
login=args.login,
password=args.password,
server=args.server,
)
fetcher = MT5Fetcher(config)
try:
print("[INFO] Initializing MT5...")
fetcher.initialize()
print("[INFO] MT5 initialized.")
for symbol in args.symbols:
for timeframe in args.timeframes:
print(f"[INFO] Downloading {symbol} {timeframe} ...")
df = fetcher.fetch_range(
symbol=symbol,
timeframe=timeframe,
start=start,
end=end,
)
stats = fetcher.validate_bars(df)
save_dir = output_dir / symbol / timeframe
saved_path = fetcher.save_dataframe(
df=df,
output_dir=save_dir,
symbol=symbol,
timeframe=timeframe,
fmt=args.format,
)
print(
f"[OK] {symbol} {timeframe} | rows={stats['rows']} | "
f"start={stats['start']} | end={stats['end']} | "
f"dup={stats['duplicate_timestamps']} | "
f"nulls={stats['null_count']} | "
f"bad_ohlc={stats['bad_ohlc_rows']} | "
f"saved={saved_path}"
)
print("[DONE] Download completed successfully.")
finally:
fetcher.shutdown()
print("[INFO] MT5 shutdown.")
if __name__ == "__main__":
main()