spb/hfmarketdata
Public
Open high-frequency market data platform — FirstRate full-history downloader, DuckDB/Parquet lake, open REST API and React docs platform (www.hfmarketdata.io)
JavaScript 53.7%
Python 38.3%
CSS 4.6%
TypeScript 3.1%
1#!/usr/bin/env python32"""Fetch OHLCV bars from HF Market Data into CSV or Parquet.34Examples:5 fetch_bars.py --asset stock --ticker AAPL --start 2020-01-01 --out aapl.csv6 fetch_bars.py --asset stock --ticker AAPL MSFT --timeframe 1hour --start 2025-08-01 --out both.csv7 fetch_bars.py --asset futures --ticker CL --adjustment contin_adj_ratio --out cl.parquet8"""9from __future__ import annotations1011import argparse12import sys13from pathlib import Path1415import pandas as pd1617sys.path.insert(0, str(Path(__file__).parent))18import hfmd # noqa: E402192021def main() -> int:22 ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)23 ap.add_argument("--asset", required=True, choices=["stock", "etf", "crypto", "index", "fx", "futures"])24 ap.add_argument("--ticker", required=True, nargs="+", help="one or more symbols")25 ap.add_argument("--timeframe", default="1day", help="1min 5min 30min 1hour 1day (aliases 1m 5m 30m 1h 1d)")26 ap.add_argument("--start")27 ap.add_argument("--end")28 ap.add_argument("--adjustment", help="stock/etf: UNADJUSTED adj_split adj_splitdiv · futures: contin_UNadj contin_adj_ratio contin_adj_absolute")29 ap.add_argument("--out", required=True, help=".csv or .parquet")30 a = ap.parse_args()3132 frames = []33 for t in a.ticker:34 df = hfmd.bars(a.asset, t.upper(), a.timeframe, a.start, a.end, a.adjustment)35 if df.empty:36 hfmd.log(f"{t}: no rows returned")37 continue38 hfmd.log(f"{t}: {len(df):,} bars from {df['datetime'].iloc[0]} to {df['datetime'].iloc[-1]}")39 frames.append(df)40 if not frames:41 return 142 out = pd.concat(frames, ignore_index=True)43 if a.out.endswith(".parquet"):44 out.to_parquet(a.out, index=False)45 else:46 out.to_csv(a.out, index=False)47 print(f"wrote {a.out}: {len(out):,} rows, {out['ticker'].nunique()} ticker(s), columns={list(out.columns)}")48 return 0495051if __name__ == "__main__":52 sys.exit(main())53