# data_manager/data_structure/binance_kline.py from typing import List from .kline_base import KlineBase import datetime import pytz import pandas as pd class BinanceKline(KlineBase): """ Binance K线数据类,继承自KlineBase,包含Binance特有的额外字段。 """ def __init__(self, raw_data: List): """ 从Binance API返回的原始数据列表初始化。 Args: raw_data: Binance API返回的单个K线数据列表,格式如下: [ 1764837300000, // 开盘时间戳 '3180.66', // 开盘价 '3186.50', // 最高价 '3180.66', // 最低价 '3182.22', // 收盘价 '1281.633', // 成交量 1764837599999, // 收盘时间戳 '4080178.49870', // 成交额 2411, // 成交笔数 '730.307', // 主动买入成交量 '2324986.16889', // 主动买入成交额 '0' // 请忽略该参数 ] """ # 解析Binance特有的字段 open_time_ms = raw_data[0] open_price = float(raw_data[1]) high_price = float(raw_data[2]) low_price = float(raw_data[3]) close_price = float(raw_data[4]) volume = float(raw_data[5]) # BTC close_time_ms = raw_data[6] quote_asset_volume = float(raw_data[7]) # USDT trade_count = raw_data[8] # 成交笔数 taker_buy_volume = float(raw_data[9]) # 主动买入成交量 (BTC) taker_buy_quote_volume = float(raw_data[10]) # 主动买入成交额 (USDT) ignore = raw_data[11] # 忽略 # 调用父类构造函数,传入必需的OHLCV信息 super().__init__( open_time=open_time_ms, close_time=close_time_ms, open_price=open_price, high_price=high_price, low_price=low_price, close_price=close_price, volume=volume ) # Binance特有的字段 self.quote_asset_volume = quote_asset_volume # 成交额 self.trade_count = trade_count # 成交笔数 self.taker_buy_volume = taker_buy_volume # 主动买入成交量 self.taker_buy_quote_volume = taker_buy_quote_volume # 主动买入成交额 @property def open_datetime(self) -> datetime: """获取开盘时间的datetime对象 (转换为北京时间)""" # 1. 将毫秒时间戳转换为UTC datetime对象 (pandas.to_datetime 会自动处理) utc_dt = pd.to_datetime(self.open_time, unit='ms', utc=True) # 2. 设置为UTC时区 (确保是UTC) utc_dt = utc_dt.tz_convert('UTC') # 3. 转换为北京时间 (Asia/Shanghai) beijing_tz = pytz.timezone('Asia/Shanghai') beijing_dt = utc_dt.tz_convert(beijing_tz) return beijing_dt.to_pydatetime() # 转换回普通datetime对象 @property def close_datetime(self) -> datetime: """获取收盘时间的datetime对象 (转换为北京时间)""" # 1. 将毫秒时间戳转换为UTC datetime对象 (pandas.to_datetime 会自动处理) utc_dt = pd.to_datetime(self.close_time, unit='ms', utc=True) # 2. 设置为UTC时区 (确保是UTC) utc_dt = utc_dt.tz_convert('UTC') # 3. 转换为北京时间 (Asia/Shanghai) beijing_tz = pytz.timezone('Asia/Shanghai') beijing_dt = utc_dt.tz_convert(beijing_tz) return beijing_dt.to_pydatetime() # 转换回普通datetime对象 def to_dict(self) -> dict: """ 将K线数据转换为字典格式。 包含所有Binance特有的字段。 """ base_dict = { 'open_time': self.open_time, 'close_time': self.close_time, 'open_price': self.open_price, 'high_price': self.high_price, 'low_price': self.low_price, 'close_price': self.close_price, 'volume': self.volume, 'quote_asset_volume': self.quote_asset_volume, 'trade_count': self.trade_count, 'taker_buy_volume': self.taker_buy_volume, 'taker_buy_quote_volume': self.taker_buy_quote_volume } return base_dict def to_pandas_series(self) -> pd.Series: """ 将K线数据转换为pandas Series。 索引是 `open_time`。 """ series = pd.Series(self.to_dict()) series.name = self.open_time return series def __str__(self): """字符串表示""" base_str = super().__str__() return f"{base_str} | QuoteVol: {self.quote_asset_volume:.2f} | Trades: {self.trade_count} | TakerVol: {self.taker_buy_volume} | TakerQuoteVol: {self.taker_buy_quote_volume}" def __repr__(self): """详细字符串表示""" return self.__str__()