添加一些东西
This commit is contained in:
@@ -9,6 +9,7 @@ class DATA_SRC(Enum):
|
||||
|
||||
|
||||
class KL_TYPE(Enum):
|
||||
K_1S = auto()
|
||||
K_1M = auto()
|
||||
K_DAY = auto()
|
||||
K_WEEK = auto()
|
||||
@@ -18,6 +19,7 @@ class KL_TYPE(Enum):
|
||||
K_15M = auto()
|
||||
K_30M = auto()
|
||||
K_60M = auto()
|
||||
K_2H = auto()
|
||||
K_4H = auto()
|
||||
K_6H = auto()
|
||||
K_8H = auto()
|
||||
|
||||
+7
-4
@@ -127,7 +127,7 @@ def get_crypto_kl_data(symbol, timeframe, limit=1000, start_time=None, end_time=
|
||||
batch_size = 1200 # 小时级数据可以获取更多
|
||||
else:
|
||||
batch_size = 1500 # 日线及以上可以获取更多
|
||||
|
||||
batch_size = 1000
|
||||
# 初始化存储所有K线数据的列表
|
||||
all_ohlcv = []
|
||||
|
||||
@@ -370,13 +370,14 @@ def analyze_chan(df, timeframe='1d'):
|
||||
"divergence_rate": float("inf"),
|
||||
"bsp2_follow_1": False,
|
||||
"bsp3_follow_1": False,
|
||||
"min_zs_cnt": 0,
|
||||
"min_zs_cnt": 1,
|
||||
"bs1_peak": False,
|
||||
"macd_algo": "peak",
|
||||
"bs_type": '1,2,3a,1p,2s,3b',
|
||||
"print_warning": True, # 开启警告以便调试
|
||||
"zs_algo": "normal", # 使用标准中枢算法提高稳定性 over_seg, normal, auto
|
||||
"bi_algo": "normal",
|
||||
"seg_algo": "chan",
|
||||
})
|
||||
# 将数据设置到WebDataAPI
|
||||
from DataAPI.WebDataAPI import WebDataAPI
|
||||
@@ -471,8 +472,10 @@ def analyze_chan(df, timeframe='1d'):
|
||||
# 只在数据量较少时打印分析结果摘要,避免在回放时产生过多日志
|
||||
if len(df) <= 50:
|
||||
print(f"chan.py分析完成: 笔{len(bi_list)}个, 线段{len(seg_list)}个, 中枢{len(zs_list)}个, 买卖点{len(buy_sell_points)}个")
|
||||
|
||||
|
||||
#last_seg = seg_list[-2]
|
||||
#last_bi = last_seg.end_bi
|
||||
#last_klu = last_bi.get_end_klu()
|
||||
#print(last_klu.time, last_seg.is_sure, last_seg.dir, "--------------------------------")
|
||||
return {
|
||||
'klc_list': kline_list.lst if hasattr(kline_list, 'lst') else [],
|
||||
'klu_list': [], # KLU数据在klc中
|
||||
|
||||
+180
-12
@@ -1221,6 +1221,26 @@
|
||||
// 只显示旋转加载图标
|
||||
$('#refreshLoadingSpinner').show();
|
||||
|
||||
// 在开始更新前保存当前所有图表的视图状态
|
||||
let savedViewState = null;
|
||||
if (tvWidget && tvWidget.state && tvWidget.state.isInitialized) {
|
||||
savedViewState = {
|
||||
visibleRange: null,
|
||||
logicalRange: null
|
||||
};
|
||||
|
||||
// 保存主图表的视图状态
|
||||
if (tvWidget.mainChart && tvWidget.mainChart.timeScale) {
|
||||
try {
|
||||
savedViewState.visibleRange = tvWidget.mainChart.timeScale().getVisibleRange();
|
||||
savedViewState.logicalRange = tvWidget.mainChart.timeScale().getVisibleLogicalRange();
|
||||
console.log('已保存图表视图状态:', savedViewState);
|
||||
} catch (e) {
|
||||
console.warn('保存图表视图状态时出错:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取参数
|
||||
const dataSource = $('#dataSource').val() || 'crypto';
|
||||
let symbol;
|
||||
@@ -1278,6 +1298,11 @@
|
||||
// 保存当前数据
|
||||
currentData = data;
|
||||
|
||||
// 将保存的视图状态传递给刷新函数
|
||||
if (savedViewState) {
|
||||
data._savedViewState = savedViewState;
|
||||
}
|
||||
|
||||
// 检查和记录服务器返回的时区
|
||||
console.log('服务器返回的时区:', data.timezone || '未指定');
|
||||
|
||||
@@ -3401,27 +3426,73 @@
|
||||
|
||||
// 先恢复可视范围,避免先显示默认范围再跳转的跳跃效果
|
||||
if (tvWidget.mainChart && (tvWidget.state.logicalRange || tvWidget.state.visibleRange)) {
|
||||
console.log('回放模式:优先恢复视图范围以避免跳跃');
|
||||
console.log('检测到保存的视图状态,准备恢复所有图表范围');
|
||||
|
||||
// 在回放模式下,图表已锁定,不设置范围
|
||||
if (isReplaying) {
|
||||
// 回放模式下跳过范围设置,因为图表已锁定
|
||||
console.log('回放模式:跳过范围设置,图表已锁定');
|
||||
} else {
|
||||
// 非回放模式下延迟应用
|
||||
// 非回放模式下延迟应用,确保所有图表都能正确恢复
|
||||
setTimeout(() => {
|
||||
try {
|
||||
if (tvWidget.state.logicalRange) {
|
||||
console.log('开始恢复所有图表的logicalRange:', tvWidget.state.logicalRange);
|
||||
|
||||
// 恢复主图表
|
||||
tvWidget.mainChart.timeScale().setVisibleLogicalRange(tvWidget.state.logicalRange);
|
||||
if (tvWidget.volumeChart) tvWidget.volumeChart.timeScale().setVisibleLogicalRange(tvWidget.state.logicalRange);
|
||||
if (tvWidget.macdChart) tvWidget.macdChart.timeScale().setVisibleLogicalRange(tvWidget.state.logicalRange);
|
||||
if (tvWidget.atrChart) tvWidget.atrChart.timeScale().setVisibleLogicalRange(tvWidget.state.logicalRange);
|
||||
} else if (tvWidget.state.visibleRange) {
|
||||
tvWidget.mainChart.timeScale().setVisibleRange(tvWidget.state.visibleRange);
|
||||
if (tvWidget.volumeChart) tvWidget.volumeChart.timeScale().setVisibleRange(tvWidget.state.visibleRange);
|
||||
if (tvWidget.macdChart) tvWidget.macdChart.timeScale().setVisibleRange(tvWidget.state.visibleRange);
|
||||
if (tvWidget.atrChart) tvWidget.atrChart.timeScale().setVisibleRange(tvWidget.state.visibleRange);
|
||||
console.log('✅ 主图表范围已恢复');
|
||||
|
||||
// 恢复成交量图表
|
||||
if (tvWidget.volumeChart && tvWidget.volumeChart.timeScale) {
|
||||
tvWidget.volumeChart.timeScale().setVisibleLogicalRange(tvWidget.state.logicalRange);
|
||||
console.log('✅ 成交量图表范围已恢复');
|
||||
}
|
||||
}, 20);
|
||||
|
||||
// 恢复MACD图表
|
||||
if (tvWidget.macdChart && tvWidget.macdChart.timeScale) {
|
||||
tvWidget.macdChart.timeScale().setVisibleLogicalRange(tvWidget.state.logicalRange);
|
||||
console.log('✅ MACD图表范围已恢复');
|
||||
}
|
||||
|
||||
// 恢复ATR图表
|
||||
if (tvWidget.atrChart && tvWidget.atrChart.timeScale) {
|
||||
tvWidget.atrChart.timeScale().setVisibleLogicalRange(tvWidget.state.logicalRange);
|
||||
console.log('✅ ATR图表范围已恢复');
|
||||
}
|
||||
|
||||
} else if (tvWidget.state.visibleRange) {
|
||||
console.log('开始恢复所有图表的visibleRange:', tvWidget.state.visibleRange);
|
||||
|
||||
// 恢复主图表
|
||||
tvWidget.mainChart.timeScale().setVisibleRange(tvWidget.state.visibleRange);
|
||||
console.log('✅ 主图表范围已恢复');
|
||||
|
||||
// 恢复成交量图表
|
||||
if (tvWidget.volumeChart && tvWidget.volumeChart.timeScale) {
|
||||
tvWidget.volumeChart.timeScale().setVisibleRange(tvWidget.state.visibleRange);
|
||||
console.log('✅ 成交量图表范围已恢复');
|
||||
}
|
||||
|
||||
// 恢复MACD图表
|
||||
if (tvWidget.macdChart && tvWidget.macdChart.timeScale) {
|
||||
tvWidget.macdChart.timeScale().setVisibleRange(tvWidget.state.visibleRange);
|
||||
console.log('✅ MACD图表范围已恢复');
|
||||
}
|
||||
|
||||
// 恢复ATR图表
|
||||
if (tvWidget.atrChart && tvWidget.atrChart.timeScale) {
|
||||
tvWidget.atrChart.timeScale().setVisibleRange(tvWidget.state.visibleRange);
|
||||
console.log('✅ ATR图表范围已恢复');
|
||||
}
|
||||
}
|
||||
|
||||
console.log('🎉 所有图表视图范围恢复完成');
|
||||
|
||||
} catch (e) {
|
||||
console.error('❌ 恢复图表视图范围时出错:', e);
|
||||
}
|
||||
}, 50); // 减少延迟到50ms以提高用户体验
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3514,9 +3585,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 保存当前的可见范围到全局状态
|
||||
// 保存当前的可见范围到全局状态,确保ATR图表状态也被保存
|
||||
if (tvWidget && tvWidget.state) {
|
||||
tvWidget.state.logicalRange = logicalRange;
|
||||
// 同时尝试保存visibleRange作为备份
|
||||
try {
|
||||
if (sourceChart && sourceChart.timeScale) {
|
||||
tvWidget.state.visibleRange = sourceChart.timeScale().getVisibleRange();
|
||||
}
|
||||
} catch (e) {
|
||||
console.debug('保存visibleRange时出错:', e);
|
||||
}
|
||||
console.log('📝 图表状态已保存,包括ATR图表');
|
||||
}
|
||||
} else {
|
||||
console.warn('⚠️ 无效的逻辑范围:', logicalRange);
|
||||
@@ -4749,12 +4829,33 @@
|
||||
data.original_kline_data = data.kline_data;
|
||||
data.original_macd = data.macd;
|
||||
|
||||
// 提取保存的视图状态
|
||||
const savedViewState = data._savedViewState;
|
||||
if (savedViewState) {
|
||||
console.log('检测到保存的视图状态,将在图表更新后恢复:', savedViewState);
|
||||
}
|
||||
|
||||
// 如果图表未初始化,则创建图表,否则更新图表数据
|
||||
if (!tvWidget.state.isInitialized) {
|
||||
console.log('图表尚未初始化,创建新图表');
|
||||
initTradingView($('#symbol').val(), $('#timeframe').val());
|
||||
|
||||
// 如果有保存的视图状态,在图表初始化后恢复
|
||||
if (savedViewState) {
|
||||
setTimeout(() => {
|
||||
restoreViewState(savedViewState);
|
||||
}, 500); // 给图表足够时间完成初始化
|
||||
}
|
||||
} else {
|
||||
console.log('图表已初始化,进行增量更新');
|
||||
|
||||
// 如果有保存的视图状态,先将其存储到tvWidget.state中
|
||||
if (savedViewState) {
|
||||
tvWidget.state.visibleRange = savedViewState.visibleRange;
|
||||
tvWidget.state.logicalRange = savedViewState.logicalRange;
|
||||
console.log('已将保存的视图状态存储到tvWidget.state');
|
||||
}
|
||||
|
||||
updateTradingViewData();
|
||||
}
|
||||
|
||||
@@ -4772,6 +4873,73 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 恢复所有图表的视图状态,包括ATR图表
|
||||
function restoreViewState(viewState) {
|
||||
if (!viewState || !tvWidget) {
|
||||
console.warn('无效的视图状态或图表对象,跳过恢复');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('开始恢复所有图表的视图状态:', viewState);
|
||||
|
||||
try {
|
||||
// 恢复主图表
|
||||
if (tvWidget.mainChart && tvWidget.mainChart.timeScale) {
|
||||
if (viewState.logicalRange) {
|
||||
tvWidget.mainChart.timeScale().setVisibleLogicalRange(viewState.logicalRange);
|
||||
console.log('✅ 主图表视图状态已恢复 (logicalRange)');
|
||||
} else if (viewState.visibleRange) {
|
||||
tvWidget.mainChart.timeScale().setVisibleRange(viewState.visibleRange);
|
||||
console.log('✅ 主图表视图状态已恢复 (visibleRange)');
|
||||
}
|
||||
}
|
||||
|
||||
// 恢复成交量图表
|
||||
if (tvWidget.volumeChart && tvWidget.volumeChart.timeScale) {
|
||||
if (viewState.logicalRange) {
|
||||
tvWidget.volumeChart.timeScale().setVisibleLogicalRange(viewState.logicalRange);
|
||||
console.log('✅ 成交量图表视图状态已恢复');
|
||||
} else if (viewState.visibleRange) {
|
||||
tvWidget.volumeChart.timeScale().setVisibleRange(viewState.visibleRange);
|
||||
console.log('✅ 成交量图表视图状态已恢复');
|
||||
}
|
||||
}
|
||||
|
||||
// 恢复MACD图表
|
||||
if (tvWidget.macdChart && tvWidget.macdChart.timeScale) {
|
||||
if (viewState.logicalRange) {
|
||||
tvWidget.macdChart.timeScale().setVisibleLogicalRange(viewState.logicalRange);
|
||||
console.log('✅ MACD图表视图状态已恢复');
|
||||
} else if (viewState.visibleRange) {
|
||||
tvWidget.macdChart.timeScale().setVisibleRange(viewState.visibleRange);
|
||||
console.log('✅ MACD图表视图状态已恢复');
|
||||
}
|
||||
}
|
||||
|
||||
// 恢复ATR图表
|
||||
if (tvWidget.atrChart && tvWidget.atrChart.timeScale) {
|
||||
if (viewState.logicalRange) {
|
||||
tvWidget.atrChart.timeScale().setVisibleLogicalRange(viewState.logicalRange);
|
||||
console.log('✅ ATR图表视图状态已恢复 (logicalRange)');
|
||||
} else if (viewState.visibleRange) {
|
||||
tvWidget.atrChart.timeScale().setVisibleRange(viewState.visibleRange);
|
||||
console.log('✅ ATR图表视图状态已恢复 (visibleRange)');
|
||||
}
|
||||
}
|
||||
|
||||
// 同时更新tvWidget.state以保持状态同步
|
||||
if (tvWidget.state) {
|
||||
tvWidget.state.visibleRange = viewState.visibleRange;
|
||||
tvWidget.state.logicalRange = viewState.logicalRange;
|
||||
}
|
||||
|
||||
console.log('🎉 所有图表视图状态恢复完成');
|
||||
|
||||
} catch (e) {
|
||||
console.error('❌ 恢复图表视图状态时出错:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// 绑定主周期MACD背离显示开关
|
||||
$('#showMainMacdDiv').change(function() {
|
||||
refreshChartOnly();
|
||||
|
||||
Reference in New Issue
Block a user