mirror of
https://ghfast.top/https://github.com/aeroxw/easy-tdx.git
synced 2026-09-12 14:34:15 +08:00
- Add ExTdxClient/AsyncExTdxClient for futures, HK stocks, etc (port 7727) - Add offline module: read daily bars, minute bars, blocks, gbbq, financials from local TDX installation directory (inspired by pytdx) - Add examples 09 (file download) and 10 (offline data reading) - Rewrite README with comprehensive API docs and code examples - Add TdxFileNotFoundError and TdxOfflineError exceptions Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
75 lines
2.4 KiB
Python
75 lines
2.4 KiB
Python
"""获取扩展行情分时数据(当日 + 历史)。"""
|
|
|
|
import struct
|
|
|
|
from ...commands.base import BaseCommand
|
|
from ..models import ExMinuteBar
|
|
|
|
|
|
class GetExMinuteTimeDataCmd(BaseCommand[list[ExMinuteBar]]):
|
|
"""获取当日分时行情数据。"""
|
|
|
|
def __init__(self, market: int, code: str) -> None:
|
|
self.market = market
|
|
self.code = code.encode("utf-8")
|
|
|
|
def build_request(self) -> bytes:
|
|
header = bytes.fromhex("01 07 08 00 01 01 0c 00 0c 00 0b 24")
|
|
return header + struct.pack("<B9s", self.market, self.code)
|
|
|
|
def parse_response(self, body: bytes) -> list[ExMinuteBar]:
|
|
if len(body) < 12:
|
|
return []
|
|
pos = 0
|
|
(market, raw_code, num) = struct.unpack("<B9sH", body[pos : pos + 12])
|
|
pos += 12
|
|
return self._parse_records(body, pos, num)
|
|
|
|
@staticmethod
|
|
def _parse_records(body: bytes, pos: int, num: int) -> list[ExMinuteBar]:
|
|
results: list[ExMinuteBar] = []
|
|
for _ in range(num):
|
|
if pos + 18 > len(body):
|
|
break
|
|
record_start = pos
|
|
(raw_time, price, avg_price, volume, amount) = struct.unpack(
|
|
"<HffII",
|
|
body[pos : pos + 18],
|
|
)
|
|
pos += 18
|
|
hour = raw_time // 60
|
|
minute = raw_time % 60
|
|
results.append(
|
|
ExMinuteBar(
|
|
hour=hour,
|
|
minute=minute,
|
|
price=price,
|
|
avg_price=avg_price,
|
|
volume=volume,
|
|
open_interest=amount,
|
|
_raw=body[record_start:pos],
|
|
)
|
|
)
|
|
return results
|
|
|
|
|
|
class GetExHistoryMinuteTimeDataCmd(BaseCommand[list[ExMinuteBar]]):
|
|
"""获取历史某日分时行情数据。"""
|
|
|
|
def __init__(self, market: int, code: str, date: int) -> None:
|
|
self.market = market
|
|
self.code = code.encode("utf-8")
|
|
self.date = date
|
|
|
|
def build_request(self) -> bytes:
|
|
header = bytes.fromhex("01 01 30 00 01 01 10 00 10 00 0c 24")
|
|
return header + struct.pack("<IB9s", self.date, self.market, self.code)
|
|
|
|
def parse_response(self, body: bytes) -> list[ExMinuteBar]:
|
|
if len(body) < 20:
|
|
return []
|
|
pos = 0
|
|
(_market, _code, _unk, num) = struct.unpack("<B9s8sH", body[pos : pos + 20])
|
|
pos += 20
|
|
return GetExMinuteTimeDataCmd._parse_records(body, pos, num)
|