添加macd周期参数设置
This commit is contained in:
+38
-8
@@ -33,8 +33,11 @@ class TRADE_POINT_TYPE:
|
|||||||
SELL3 = -3 # 三类卖点
|
SELL3 = -3 # 三类卖点
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
macd_factor = 2 *6
|
macd_factor = 2
|
||||||
smooth_factor = 1
|
smooth_factor = 1
|
||||||
|
macd_fast_period = 12 * macd_factor
|
||||||
|
macd_slow_period = 26 * macd_factor
|
||||||
|
macd_signal_period = 9 * smooth_factor
|
||||||
# 初始化交易所
|
# 初始化交易所
|
||||||
exchange = ccxt.binance({
|
exchange = ccxt.binance({
|
||||||
'enableRateLimit': True,
|
'enableRateLimit': True,
|
||||||
@@ -422,10 +425,8 @@ def get_a_stock_kl_data(symbol, timeframe, limit=100000, start_time=None, end_ti
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def add_indicators(df):
|
def add_indicators(df):
|
||||||
fast = 12 * macd_factor
|
global macd_fast_period, macd_slow_period, macd_signal_period
|
||||||
slow = 26 * macd_factor
|
macd = ta.MACD(df, fastperiod=macd_fast_period, slowperiod=macd_slow_period, signalperiod=macd_signal_period)
|
||||||
period = 9 * smooth_factor
|
|
||||||
macd = ta.MACD(df, fastperiod=fast, slowperiod=slow, signalperiod=period)
|
|
||||||
|
|
||||||
df['macd'] = macd['macd']
|
df['macd'] = macd['macd']
|
||||||
df['macdsignal'] = macd['macdsignal']
|
df['macdsignal'] = macd['macdsignal']
|
||||||
@@ -510,10 +511,11 @@ def add_indicators(df):
|
|||||||
|
|
||||||
def calculate_macd(df):
|
def calculate_macd(df):
|
||||||
"""计算MACD指标"""
|
"""计算MACD指标"""
|
||||||
exp1 = df['close'].ewm(span=12*macd_factor, adjust=False).mean()
|
global macd_fast_period, macd_slow_period, macd_signal_period
|
||||||
exp2 = df['close'].ewm(span=26*macd_factor, adjust=False).mean()
|
exp1 = df['close'].ewm(span=macd_fast_period, adjust=False).mean()
|
||||||
|
exp2 = df['close'].ewm(span=macd_slow_period, adjust=False).mean()
|
||||||
macd = exp1 - exp2
|
macd = exp1 - exp2
|
||||||
signal = macd.ewm(span=9 * smooth_factor, adjust=False).mean()
|
signal = macd.ewm(span=macd_signal_period, adjust=False).mean()
|
||||||
histogram = macd - signal
|
histogram = macd - signal
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -1845,6 +1847,34 @@ def search_stock():
|
|||||||
return jsonify({'error': str(e)})
|
return jsonify({'error': str(e)})
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/macd_config', methods=['GET', 'POST'])
|
||||||
|
def macd_config():
|
||||||
|
"""获取或设置MACD参数"""
|
||||||
|
global macd_fast_period, macd_slow_period, macd_signal_period
|
||||||
|
if request.method == 'GET':
|
||||||
|
return jsonify({
|
||||||
|
'fast': macd_fast_period,
|
||||||
|
'slow': macd_slow_period,
|
||||||
|
'signal': macd_signal_period
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
data = request.get_json(silent=True) or {}
|
||||||
|
fast = data.get('fast')
|
||||||
|
slow = data.get('slow')
|
||||||
|
signal = data.get('signal')
|
||||||
|
if fast is not None:
|
||||||
|
macd_fast_period = int(fast)
|
||||||
|
if slow is not None:
|
||||||
|
macd_slow_period = int(slow)
|
||||||
|
if signal is not None:
|
||||||
|
macd_signal_period = int(signal)
|
||||||
|
return jsonify({
|
||||||
|
'fast': macd_fast_period,
|
||||||
|
'slow': macd_slow_period,
|
||||||
|
'signal': macd_signal_period
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def get_uncompleted_seg_list(seg_list, client_tz):
|
def get_uncompleted_seg_list(seg_list, client_tz):
|
||||||
"""获取未完成线段列表,正确处理倒数第二个和最后一个未完成线段"""
|
"""获取未完成线段列表,正确处理倒数第二个和最后一个未完成线段"""
|
||||||
uncompleted_segs = [seg for seg in seg_list if not seg.is_sure]
|
uncompleted_segs = [seg for seg in seg_list if not seg.is_sure]
|
||||||
|
|||||||
+182
-9
@@ -764,6 +764,91 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.macd-config-modal {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0,0,0,0.5);
|
||||||
|
z-index: 10000;
|
||||||
|
display: none;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.macd-config-content {
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
width: 360px;
|
||||||
|
max-width: 90vw;
|
||||||
|
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
.macd-config-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.macd-config-form {
|
||||||
|
display: grid;
|
||||||
|
gap: 14px;
|
||||||
|
}
|
||||||
|
.macd-config-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
.macd-config-label {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
.macd-config-input {
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.macd-config-input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #0d6efd;
|
||||||
|
box-shadow: 0 0 0 2px rgba(13, 110, 253, 0.25);
|
||||||
|
}
|
||||||
|
.macd-config-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.macd-config-btn {
|
||||||
|
padding: 8px 18px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
.macd-config-btn-primary {
|
||||||
|
background: #0d6efd;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.macd-config-btn-primary:hover {
|
||||||
|
background: #0b5ed7;
|
||||||
|
}
|
||||||
|
.macd-config-btn-secondary {
|
||||||
|
background: #f8f9fa;
|
||||||
|
color: #6c757d;
|
||||||
|
}
|
||||||
|
.macd-config-btn-secondary:hover {
|
||||||
|
background: #e9ecef;
|
||||||
|
}
|
||||||
|
.macd-config-hint {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -854,6 +939,7 @@
|
|||||||
<div class="form-check form-check-inline">
|
<div class="form-check form-check-inline">
|
||||||
<input class="form-check-input" type="checkbox" id="showMacd" checked>
|
<input class="form-check-input" type="checkbox" id="showMacd" checked>
|
||||||
<label class="form-check-label" for="showMacd">ChanMACD</label>
|
<label class="form-check-label" for="showMacd">ChanMACD</label>
|
||||||
|
<button class="btn btn-sm btn-outline-secondary ms-1 p-0" onclick="showMacdConfig()" style="width:22px;height:22px;line-height:1;font-size:12px;" title="MACD参数设置">⚙</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex align-items-center mb-2">
|
<div class="d-flex align-items-center mb-2">
|
||||||
<label for="refreshInterval" class="form-label me-2 mb-0">自动刷新:</label>
|
<label for="refreshInterval" class="form-label me-2 mb-0">自动刷新:</label>
|
||||||
@@ -1783,6 +1869,56 @@
|
|||||||
$('#showMacd').change(function() {
|
$('#showMacd').change(function() {
|
||||||
updateChartDisplay();
|
updateChartDisplay();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function showMacdConfig() {
|
||||||
|
$.get('/api/macd_config', function(data) {
|
||||||
|
$('#macdFastPeriod').val(data.fast);
|
||||||
|
$('#macdSlowPeriod').val(data.slow);
|
||||||
|
$('#macdSignalPeriod').val(data.signal);
|
||||||
|
$('#macdConfigModal').css('display', 'flex');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideMacdConfig() {
|
||||||
|
$('#macdConfigModal').css('display', 'none');
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetMacdConfig() {
|
||||||
|
$('#macdFastPeriod').val(24);
|
||||||
|
$('#macdSlowPeriod').val(52);
|
||||||
|
$('#macdSignalPeriod').val(9);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveMacdConfig() {
|
||||||
|
const fast = parseInt($('#macdFastPeriod').val());
|
||||||
|
const slow = parseInt($('#macdSlowPeriod').val());
|
||||||
|
const signal = parseInt($('#macdSignalPeriod').val());
|
||||||
|
if (fast >= slow) {
|
||||||
|
alert('快线周期必须小于慢线周期');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fast < 2 || slow < 2 || signal < 2) {
|
||||||
|
alert('周期值必须大于等于2');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$.ajax({
|
||||||
|
url: '/api/macd_config',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/json',
|
||||||
|
data: JSON.stringify({ fast: fast, slow: slow, signal: signal }),
|
||||||
|
success: function() {
|
||||||
|
hideMacdConfig();
|
||||||
|
updateChart();
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
alert('保存MACD参数失败');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).on('click', '#macdConfigModal', function(e) {
|
||||||
|
if (e.target === this) hideMacdConfig();
|
||||||
|
});
|
||||||
|
|
||||||
// 添加原始K线复选框变更事件
|
// 添加原始K线复选框变更事件
|
||||||
$('#showOriginalKline').change(function() {
|
$('#showOriginalKline').change(function() {
|
||||||
@@ -6585,21 +6721,29 @@
|
|||||||
// 首先同步时间轴设置
|
// 首先同步时间轴设置
|
||||||
syncTimeScaleSettings();
|
syncTimeScaleSettings();
|
||||||
|
|
||||||
// 然后让主图表适应内容
|
// 显示最近 200 根K线而非全部挤压(避免K线过多时重叠)
|
||||||
mainChart.timeScale().fitContent();
|
const totalBars = candles ? candles.length : 0;
|
||||||
|
const visibleBarsCount = 200;
|
||||||
|
if (totalBars > visibleBarsCount) {
|
||||||
|
const rangeFrom = totalBars - visibleBarsCount;
|
||||||
|
const rangeTo = totalBars + 12;
|
||||||
|
mainChart.timeScale().setVisibleLogicalRange({ from: rangeFrom, to: rangeTo });
|
||||||
|
} else {
|
||||||
|
mainChart.timeScale().fitContent();
|
||||||
|
}
|
||||||
|
|
||||||
// 立即同步其他图表到主图表的范围
|
// 立即同步其他图表到主图表的范围
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const visibleRange = mainChart.timeScale().getVisibleRange();
|
const logRange = mainChart.timeScale().getVisibleLogicalRange();
|
||||||
if (visibleRange) {
|
if (logRange) {
|
||||||
console.log('🔧 同步可见范围:', visibleRange);
|
console.log('🔧 同步可见范围:', logRange);
|
||||||
volumeChart.timeScale().setVisibleRange(visibleRange);
|
volumeChart.timeScale().setVisibleLogicalRange(logRange);
|
||||||
atrChart.timeScale().setVisibleRange(visibleRange);
|
atrChart.timeScale().setVisibleLogicalRange(logRange);
|
||||||
if (showMacd && macdChart) {
|
if (showMacd && macdChart) {
|
||||||
macdChart.timeScale().setVisibleRange(visibleRange);
|
macdChart.timeScale().setVisibleLogicalRange(logRange);
|
||||||
}
|
}
|
||||||
if (showMacd && chanMacdChart) {
|
if (showMacd && chanMacdChart) {
|
||||||
chanMacdChart.timeScale().setVisibleRange(visibleRange);
|
chanMacdChart.timeScale().setVisibleLogicalRange(logRange);
|
||||||
}
|
}
|
||||||
console.log('🔧 时间轴同步完成');
|
console.log('🔧 时间轴同步完成');
|
||||||
}
|
}
|
||||||
@@ -10461,5 +10605,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- MACD参数配置弹窗 -->
|
||||||
|
<div id="macdConfigModal" class="macd-config-modal">
|
||||||
|
<div class="macd-config-content">
|
||||||
|
<div class="macd-config-title">ChanMACD 参数设置</div>
|
||||||
|
<div class="macd-config-form">
|
||||||
|
<div class="macd-config-group">
|
||||||
|
<label class="macd-config-label">快线周期 (Fast)</label>
|
||||||
|
<input type="number" id="macdFastPeriod" class="macd-config-input" value="24" min="2" max="200">
|
||||||
|
<div class="macd-config-hint">默认: 24 (12×2)</div>
|
||||||
|
</div>
|
||||||
|
<div class="macd-config-group">
|
||||||
|
<label class="macd-config-label">慢线周期 (Slow)</label>
|
||||||
|
<input type="number" id="macdSlowPeriod" class="macd-config-input" value="52" min="2" max="500">
|
||||||
|
<div class="macd-config-hint">默认: 52 (26×2)</div>
|
||||||
|
</div>
|
||||||
|
<div class="macd-config-group">
|
||||||
|
<label class="macd-config-label">信号线周期 (Signal)</label>
|
||||||
|
<input type="number" id="macdSignalPeriod" class="macd-config-input" value="9" min="2" max="200">
|
||||||
|
<div class="macd-config-hint">默认: 9</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="macd-config-actions">
|
||||||
|
<button class="macd-config-btn macd-config-btn-secondary" onclick="hideMacdConfig()">取消</button>
|
||||||
|
<button class="macd-config-btn macd-config-btn-secondary" onclick="resetMacdConfig()">恢复默认</button>
|
||||||
|
<button class="macd-config-btn macd-config-btn-primary" onclick="saveMacdConfig()">应用</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user