6e423eebfb
新增 vnpy CTP 桥接、以损定仓/固定张数、趋势回调与滚仓策略、按资金推荐品种及交易风控;模拟盘走 SimNow,实盘预留期货公司配置。 Co-authored-by: Cursor <cursoragent@cursor.com>
140 lines
6.9 KiB
HTML
140 lines
6.9 KiB
HTML
{% extends "base.html" %}
|
||
{% block title %}行情K线 - 国内期货监控系统{% endblock %}
|
||
{% block content %}
|
||
|
||
<div class="card market-card">
|
||
<h2>行情 K 线</h2>
|
||
<form class="market-toolbar" id="market-form" onsubmit="return false;">
|
||
<div class="symbol-wrap market-symbol-wrap">
|
||
<input type="text" class="symbol-input" id="market-symbol-input" placeholder="点击选择主力合约,或输入搜索" autocomplete="off" value="{{ symbol }}">
|
||
<input type="hidden" name="symbol" id="market-symbol-hidden" value="{{ symbol }}">
|
||
<input type="hidden" name="symbol_name" id="market-symbol-name">
|
||
<input type="hidden" name="market_code" id="market-market-code">
|
||
<input type="hidden" name="sina_code" id="market-sina-code">
|
||
<div class="symbol-dropdown"></div>
|
||
<div class="symbol-selected" id="market-symbol-selected"></div>
|
||
</div>
|
||
<div class="market-period-tabs" id="market-period-tabs">
|
||
{% for p in market_periods %}
|
||
<button type="button" class="period-tab{% if p.key == period %} active{% endif %}" data-period="{{ p.key }}">{{ p.label }}</button>
|
||
{% endfor %}
|
||
</div>
|
||
<button type="button" class="btn-primary" id="market-load-btn">查看</button>
|
||
</form>
|
||
<div class="market-quote" id="market-quote">
|
||
<span class="market-quote-name" id="market-quote-name">—</span>
|
||
<span class="market-quote-price" id="market-quote-price">—</span>
|
||
<span class="market-quote-prev text-muted" id="market-quote-prev"></span>
|
||
<span class="market-quote-meta text-muted" id="market-quote-meta"></span>
|
||
</div>
|
||
<div class="market-chart-toolbar">
|
||
<div class="market-chart-options">
|
||
<label class="chart-opt"><input type="checkbox" id="chart-opt-prev-close">昨收线</label>
|
||
<label class="chart-opt"><input type="checkbox" id="chart-opt-ma">均线 21/55</label>
|
||
<label class="chart-opt"><input type="checkbox" id="chart-opt-gap-day">间隔日</label>
|
||
</div>
|
||
<div class="market-chart-zoom">
|
||
<button type="button" class="chart-zoom-btn" id="chart-zoom-in" title="放大">+</button>
|
||
<button type="button" class="chart-zoom-btn" id="chart-zoom-out" title="缩小">-</button>
|
||
<button type="button" class="chart-zoom-btn chart-zoom-reset" id="chart-zoom-reset">重置</button>
|
||
</div>
|
||
<span class="market-refresh-hint text-muted" id="market-refresh-hint"></span>
|
||
</div>
|
||
<div class="market-chart-wrap" id="market-chart-wrap">
|
||
<div id="market-chart" class="market-chart" aria-label="K线图"></div>
|
||
<div class="market-chart-empty" id="market-chart-empty">请选择合约并点击「查看」</div>
|
||
<div class="market-chart-loading" id="market-chart-loading">连接中…</div>
|
||
</div>
|
||
<p class="hint">数据来源:新浪财经。拖拽左右平移、滚轮缩放;按住图表上下拖动可平移价格轴。可视区内自动标注最高/最低价。</p>
|
||
</div>
|
||
|
||
<style>
|
||
.market-card{overflow:visible}
|
||
.market-card h2{margin-bottom:.75rem}
|
||
.market-toolbar{
|
||
display:flex;flex-wrap:wrap;gap:.65rem;align-items:flex-end;
|
||
margin-bottom:.75rem;position:relative;z-index:2;
|
||
min-height:2.5rem;
|
||
}
|
||
.market-symbol-wrap{flex:1;min-width:200px;max-width:360px;z-index:3}
|
||
.market-symbol-wrap .symbol-dropdown{max-height:min(70vh,420px)}
|
||
.market-symbol-wrap .symbol-selected{display:none}
|
||
.market-period-tabs{display:flex;flex-wrap:wrap;gap:.35rem;align-items:center}
|
||
.period-tab{
|
||
padding:.4rem .65rem;border-radius:999px;
|
||
border:1px solid var(--input-border);
|
||
background:var(--toggle-bg);color:var(--text-muted);
|
||
font-size:.78rem;cursor:pointer;width:auto;white-space:nowrap;
|
||
}
|
||
.period-tab:hover{border-color:var(--accent);color:var(--accent)}
|
||
.period-tab.active{
|
||
background:linear-gradient(135deg,var(--accent),var(--accent-2));
|
||
border-color:transparent;color:#fff;
|
||
}
|
||
#market-load-btn{width:auto;padding:.55rem 1.25rem;font-size:.85rem}
|
||
.market-quote{
|
||
display:flex;flex-wrap:wrap;align-items:baseline;gap:.5rem 1rem;
|
||
margin-bottom:.75rem;padding:.65rem .85rem;
|
||
background:var(--card-inner);border-radius:10px;border:1px solid var(--card-border);
|
||
min-height:2.75rem;
|
||
}
|
||
.market-quote-name{font-weight:600;color:var(--text-title)}
|
||
.market-quote-price{font-size:1.35rem;font-weight:700;color:var(--accent);font-variant-numeric:tabular-nums}
|
||
.market-quote-prev{font-size:.78rem}
|
||
.market-chart-toolbar{
|
||
display:flex;align-items:center;justify-content:space-between;gap:.75rem;
|
||
margin-bottom:.5rem;flex-wrap:wrap;
|
||
min-height:2rem;
|
||
}
|
||
.market-chart-options{display:flex;flex-wrap:wrap;gap:.5rem .85rem;align-items:center}
|
||
.chart-opt{
|
||
display:flex;align-items:center;gap:.35rem;font-size:.78rem;
|
||
color:var(--text-muted);cursor:pointer;user-select:none;
|
||
}
|
||
.chart-opt input{width:auto;margin:0;cursor:pointer}
|
||
.market-chart-zoom{display:flex;gap:.35rem;align-items:center}
|
||
.chart-zoom-btn{
|
||
width:32px;height:32px;padding:0;border-radius:8px;
|
||
border:1px solid var(--input-border);background:var(--toggle-bg);
|
||
color:var(--text-primary);font-size:1rem;line-height:1;cursor:pointer;
|
||
}
|
||
.chart-zoom-btn:hover{border-color:var(--accent);color:var(--accent)}
|
||
.chart-zoom-reset{width:auto;padding:0 .65rem;font-size:.75rem}
|
||
.market-refresh-hint{font-size:.72rem}
|
||
.market-chart-wrap{
|
||
position:relative;border-radius:12px;border:1px solid var(--card-border);
|
||
background:var(--card-inner);
|
||
height:min(62vh,520px);min-height:360px;
|
||
}
|
||
.market-chart{width:100%;height:100%}
|
||
.market-chart-empty,
|
||
.market-chart-loading{
|
||
position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
|
||
color:var(--text-muted);font-size:.9rem;pointer-events:none;
|
||
}
|
||
.market-chart-loading{display:none}
|
||
html[data-theme="light"] .market-chart-loading{background:rgba(244,247,252,.75)}
|
||
.market-chart-wrap.has-data .market-chart-empty{display:none}
|
||
.market-chart-wrap.loading .market-chart-loading{
|
||
display:flex;background:rgba(10,12,20,.35);
|
||
}
|
||
html[data-theme="light"] .market-chart-wrap.loading .market-chart-loading{background:rgba(244,247,252,.75)}
|
||
.market-chart-wrap.loading .market-chart-empty{display:none}
|
||
@media(max-width:767px){
|
||
.market-toolbar{align-items:stretch}
|
||
.market-symbol-wrap{max-width:none}
|
||
.market-period-tabs{order:3;width:100%}
|
||
#market-load-btn{order:4;width:100%}
|
||
.market-chart-wrap{min-height:300px;height:50vh}
|
||
.market-chart-toolbar{flex-direction:column;align-items:stretch}
|
||
.market-chart-options{order:1}
|
||
.market-chart-zoom{order:2}
|
||
}
|
||
</style>
|
||
{% endblock %}
|
||
|
||
{% block extra_js %}
|
||
<script src="https://cdn.jsdelivr.net/npm/echarts@5.5.1/dist/echarts.min.js"></script>
|
||
<script src="{{ url_for('static', filename='js/market.js') }}"></script>
|
||
{% endblock %}
|