Files
chan.py/DataAPI/WebDataAPI.py
T
2025-06-10 18:01:42 +08:00

93 lines
3.5 KiB
Python

from datetime import datetime
import pandas as pd
from Common.CEnum import AUTYPE, DATA_FIELD, KL_TYPE
from Common.CTime import CTime
from Common.func_util import kltype_lt_day, str2float
from KLine.KLine_Unit import CKLine_Unit
from .CommonStockAPI import CCommonStockApi
class WebDataAPI(CCommonStockApi):
"""Web应用的数据API适配器,用于将web应用的数据转换为chan.py格式"""
# 类变量用于存储数据
_data_cache = {}
def __init__(self, code, k_type=KL_TYPE.K_DAY, begin_date=None, end_date=None, autype=AUTYPE.QFQ):
super().__init__(code, k_type, begin_date, end_date, autype)
@classmethod
def set_data(cls, code, df_data):
"""设置指定代码的数据"""
cls._data_cache[code] = df_data
def get_kl_data(self):
"""将DataFrame数据转换为CKLine_Unit迭代器"""
df_data = self._data_cache.get(self.code)
if df_data is None or len(df_data) == 0:
return
# 确保数据按时间排序并重置索引
df_data = df_data.sort_values('date').reset_index(drop=True)
# 检查并处理重复时间
if 'timestamp' in df_data.columns:
df_data = df_data.drop_duplicates(subset=['timestamp'], keep='last')
df_data = df_data.sort_values('timestamp').reset_index(drop=True)
prev_timestamp = None
for idx, row in df_data.iterrows():
# 转换时间格式
if isinstance(row['date'], str):
time_obj = datetime.fromisoformat(row['date'].replace('Z', '+00:00'))
else:
time_obj = row['date']
# 检查时间戳确保单调递增
if 'timestamp' in row:
current_timestamp = row['timestamp']
if prev_timestamp is not None and current_timestamp <= prev_timestamp:
continue
prev_timestamp = current_timestamp
# 创建CTime对象 - 根据K线级别智能决定auto参数
# 对于日线及以上级别,且时分秒为0的情况,使用auto=True
# 对于分钟级别或有具体时分的数据,使用auto=False确保精确时间
use_auto = False # 默认不使用auto,确保时间精确
# 只有在日线级别且时分秒都为0时才考虑使用auto
if self.k_type in [KL_TYPE.K_DAY, KL_TYPE.K_WEEK, KL_TYPE.K_MON]:
if time_obj.hour == 0 and time_obj.minute == 0 and time_obj.second == 0:
use_auto = True
ctime = CTime(
time_obj.year,
time_obj.month,
time_obj.day,
time_obj.hour,
time_obj.minute,
time_obj.second,
auto=use_auto
)
# 创建数据字典
data_dict = {
DATA_FIELD.FIELD_TIME: ctime,
DATA_FIELD.FIELD_OPEN: float(row['open']),
DATA_FIELD.FIELD_HIGH: float(row['high']),
DATA_FIELD.FIELD_LOW: float(row['low']),
DATA_FIELD.FIELD_CLOSE: float(row['close']),
DATA_FIELD.FIELD_VOLUME: float(row['volume']) if 'volume' in row and pd.notna(row['volume']) else 0.0
}
yield CKLine_Unit(data_dict, autofix=True)
def SetBasciInfo(self):
pass
@classmethod
def do_init(cls):
pass
@classmethod
def do_close(cls):
pass