93 lines
3.5 KiB
Python
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 |