Replay is ok now
This commit is contained in:
+122
@@ -353,6 +353,112 @@ def analyze_chan(df):
|
||||
for bi in bi_list:
|
||||
bi.cal_macd_div()
|
||||
#print(bi.start_time, bi.macd_hist, bi.macd_div)
|
||||
|
||||
def generate_replay_data(df, client_tz):
|
||||
"""生成逐步计算的回放数据"""
|
||||
print(f"开始生成回放数据,K线总数: {len(df)}")
|
||||
|
||||
replay_data = {}
|
||||
|
||||
# 为每个K线索引计算分析结果
|
||||
for i in range(1, len(df) + 1): # 从1开始,至少需要1根K线
|
||||
try:
|
||||
# 截取到当前索引的数据
|
||||
current_df = df.iloc[:i].copy()
|
||||
|
||||
# 添加技术指标
|
||||
current_df = add_indicators(current_df)
|
||||
|
||||
# 进行缠论分析
|
||||
analysis_result = analyze_chan(current_df)
|
||||
|
||||
# 计算MACD
|
||||
macd_data = calculate_macd(current_df)
|
||||
|
||||
# 构建该索引对应的分析结果
|
||||
step_data = {
|
||||
'kline_data': clean_dataframe_for_json(current_df).to_dict('records'),
|
||||
'bi_list': [{
|
||||
'start_time': bi.start_klc.end_time if isinstance(bi.start_klc.end_time, str) else bi.start_klc.end_time.astimezone(client_tz).isoformat(),
|
||||
'end_time': (bi.end_klc.end_time if isinstance(bi.end_klc.end_time, str) else bi.end_klc.end_time.astimezone(client_tz).isoformat()) if bi.end_klc else None,
|
||||
'sure_time': format_time_safely(bi.sure_time, client_tz) if bi.sure_time else None,
|
||||
'start_price': bi.start_klc.low if convert_direction(bi.dir) == 1 else bi.start_klc.high,
|
||||
'end_price': bi.end_klc.high if convert_direction(bi.dir) == 1 else bi.end_klc.low if bi.end_klc else None,
|
||||
'direction': convert_direction(bi.dir),
|
||||
'macd_div': float(bi.macd_div) if hasattr(bi, 'macd_div') else 0
|
||||
} for bi in analysis_result['bi_list'] if bi.end_klc],
|
||||
'seg_list': [{
|
||||
'start_time': seg.start_bi.start_klc.end_time if isinstance(seg.start_bi.start_klc.end_time, str) else seg.start_bi.start_klc.end_time.astimezone(client_tz).isoformat(),
|
||||
'end_time': (seg.end_bi.end_klc.end_time if isinstance(seg.end_bi.end_klc.end_time, str) else seg.end_bi.end_klc.end_time.astimezone(client_tz).isoformat()) if seg.end_bi else None,
|
||||
'sure_time': format_time_safely(seg.sure_time, client_tz) if seg.sure_time else None,
|
||||
'start_price': seg.start_bi.start_klc.low if convert_direction(seg.dir) == 1 else seg.start_bi.start_klc.high,
|
||||
'end_price': seg.end_bi.end_klc.high if convert_direction(seg.dir) == 1 else seg.end_bi.end_klc.low if seg.end_bi else None,
|
||||
'direction': convert_direction(seg.dir)
|
||||
} for seg in analysis_result['seg_list'] if seg.end_bi],
|
||||
'zs_list': [{
|
||||
'start_time': zs.start_klc.end_time if isinstance(zs.start_klc.end_time, str) else zs.start_klc.end_time.astimezone(client_tz).isoformat(),
|
||||
'end_time': (zs.end_klc.end_time if isinstance(zs.end_klc.end_time, str) else zs.end_klc.end_time.astimezone(client_tz).isoformat()) if zs.end_klc else None,
|
||||
'zg': zs.zg,
|
||||
'zd': zs.zd,
|
||||
'is_sure': zs.is_sure
|
||||
} for zs in analysis_result['zs_list'] if zs.end_klc],
|
||||
'uncompleted_zs_list': [{
|
||||
'start_time': zs.start_klc.end_time if isinstance(zs.start_klc.end_time, str) else zs.start_klc.end_time.astimezone(client_tz).isoformat(),
|
||||
'end_time': None,
|
||||
'zg': zs.zg,
|
||||
'zd': zs.zd,
|
||||
'is_sure': zs.is_sure
|
||||
} for zs in analysis_result['zs_list'] if not zs.is_sure],
|
||||
'trade_points': [{
|
||||
'type': point['type'],
|
||||
'time': format_time_safely(point['time'], client_tz),
|
||||
'price': point['price'],
|
||||
'desc': point['desc']
|
||||
} for point in analysis_result['trade_points']],
|
||||
'macd': macd_data,
|
||||
'bollinger': {
|
||||
'upper': current_df['bb_upper'].tolist(),
|
||||
'middle': current_df['bb_middle'].tolist(),
|
||||
'lower': current_df['bb_lower'].tolist()
|
||||
},
|
||||
'element_bollinger': {
|
||||
'upper': current_df['element_bb_upper'].tolist(),
|
||||
'middle': current_df['element_bb_middle'].tolist(),
|
||||
'lower': current_df['element_bb_lower'].tolist()
|
||||
},
|
||||
'klc_fx_info': [{
|
||||
'time': format_time_safely(point['time'], client_tz),
|
||||
'price': float(point['price']),
|
||||
'fx_type': point['fx_type'],
|
||||
'is_bottom': bool(point['is_bottom']),
|
||||
'fx_strength': float(point['fx_strength']),
|
||||
'fx_strength_level': str(point['fx_strength_level']),
|
||||
'is_strong_fx': bool(point['is_strong_fx'])
|
||||
} for point in analysis_result['klc_fx_info']],
|
||||
'klu_fx_info': [{
|
||||
'time': format_time_safely(point['time'], client_tz),
|
||||
'price': float(point['price']),
|
||||
'fx_type': point['fx_type'],
|
||||
'is_bottom': bool(point['is_bottom']),
|
||||
'fx_strength': float(point['fx_strength']),
|
||||
'fx_strength_level': str(point['fx_strength_level']),
|
||||
'is_strong_fx': bool(point['is_strong_fx']),
|
||||
'fx_confirmed': bool(point['fx_confirmed'])
|
||||
} for point in analysis_result['klu_fx_info']]
|
||||
}
|
||||
|
||||
replay_data[i-1] = step_data # 使用0-based索引
|
||||
|
||||
# 每处理100个点输出一次进度
|
||||
if i % 100 == 0 or i == len(df):
|
||||
print(f"生成回放数据进度: {i}/{len(df)}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"生成第{i}步回放数据时出错: {e}")
|
||||
continue
|
||||
|
||||
print(f"回放数据生成完成,总步数: {len(replay_data)}")
|
||||
return replay_data
|
||||
|
||||
# 获取原始K线数据用于KLU分型分析
|
||||
klu_list = []
|
||||
@@ -822,9 +928,13 @@ def analyze():
|
||||
elements_only_param = request.args.get('elements_only')
|
||||
elements_only = elements_only_param == 'true'
|
||||
|
||||
# 获取是否需要回放数据的参数
|
||||
need_replay_data = request.args.get('need_replay_data', 'false').lower() == 'true'
|
||||
|
||||
print(f"API请求参数: symbol={symbol}, timeframe={timeframe}, element_timeframe={element_timeframe}")
|
||||
print(f"时间范围: start_time={start_time}, end_time={end_time}")
|
||||
print(f"elements_only参数: 原始值={elements_only_param}, 处理后={elements_only}")
|
||||
print(f"need_replay_data参数: {need_replay_data}")
|
||||
|
||||
# 验证小周期是否小于主周期
|
||||
if element_timeframe and not is_smaller_or_equal_timeframe(element_timeframe, timeframe):
|
||||
@@ -862,6 +972,14 @@ def analyze():
|
||||
# 计算MACD
|
||||
macd_data = calculate_macd(df)
|
||||
|
||||
# 如果需要回放数据,生成逐步计算的回放数据
|
||||
if need_replay_data:
|
||||
print("开始生成回放数据...")
|
||||
replay_data = generate_replay_data(df, client_tz)
|
||||
print(f"回放数据生成完成,包含 {len(replay_data)} 个步骤")
|
||||
else:
|
||||
replay_data = None
|
||||
|
||||
# 添加主周期分析结果到返回数据
|
||||
result.update({
|
||||
'kline_data': clean_dataframe_for_json(df).to_dict('records'),
|
||||
@@ -936,6 +1054,10 @@ def analyze():
|
||||
'fx_confirmed': bool(point['fx_confirmed']) # 分型是否确认
|
||||
} for point in analysis_result['klu_fx_info']]
|
||||
})
|
||||
|
||||
# 如果生成了回放数据,添加到返回结果中
|
||||
if replay_data is not None:
|
||||
result['replay_data'] = replay_data
|
||||
else:
|
||||
print(f"只请求元素数据,跳过主周期数据处理 (elements_only={elements_only})")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user