期权交易"权利金"改为"开仓价";新增期权双买交易功能,支持跨式策略开平仓及组合盈亏分析
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,419 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}期权双买交易{% endblock %}
|
||||
{% block heading %}期权双买交易{% endblock %}
|
||||
{% block breadcrumb %}跨式策略{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% set view = request.query_params.get('view', '') %}
|
||||
|
||||
<style>
|
||||
.tabs { display: flex; gap: 0; margin-bottom: 24px; border-bottom: 2px solid var(--border); }
|
||||
.tab-btn {
|
||||
padding: 10px 20px; border: none; background: none;
|
||||
font-size: 0.88rem; font-weight: 500; color: var(--sub);
|
||||
cursor: pointer; text-decoration: none; border-bottom: 2px solid transparent;
|
||||
margin-bottom: -2px; transition: color .12s, border-color .12s;
|
||||
}
|
||||
.tab-btn:hover { color: var(--fg); }
|
||||
.tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }
|
||||
.tab-panel { display: none; }
|
||||
.tab-panel.active { display: block; }
|
||||
</style>
|
||||
|
||||
<div class="tabs">
|
||||
<a href="/dual-options/" class="tab-btn{% if view != 'closed' %} active{% endif %}">📋 持仓</a>
|
||||
<a href="/dual-options/?view=closed" class="tab-btn{% if view == 'closed' %} active{% endif %}">📊 已平仓</a>
|
||||
</div>
|
||||
|
||||
{% if view != 'closed' %}
|
||||
<div class="tab-panel active">
|
||||
|
||||
{# ── 新建双买开仓 ── #}
|
||||
<div class="section-title">新建双买开仓(同时买入看涨 + 看跌)</div>
|
||||
<div class="form-card" style="margin-bottom:28px;max-width:100%;">
|
||||
<form method="post" action="/dual-options/open">
|
||||
<div style="display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap;">
|
||||
<div class="form-group" style="margin-bottom:0;flex:0 0 auto;min-width:100px;">
|
||||
<label>品种</label>
|
||||
<select id="productSelect" required onchange="filterContracts()">
|
||||
<option value="">--</option>
|
||||
{% for pcode in product_contracts %}
|
||||
<option value="{{ pcode }}">{{ pcode }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group" style="margin-bottom:0;flex:0 0 auto;min-width:120px;">
|
||||
<label>合约</label>
|
||||
<select name="contract_code" id="contractSelect" required disabled>
|
||||
<option value="">-- 先选品种 --</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group" style="margin-bottom:0;flex:0 0 auto;min-width:90px;">
|
||||
<label>行权价</label>
|
||||
<input type="number" step="any" name="strike_price" required placeholder="1300" style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group" style="margin-bottom:0;flex:0 0 auto;min-width:100px;">
|
||||
<label>看涨开仓价</label>
|
||||
<input type="number" step="any" name="call_open_price" required placeholder="C权利金" style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group" style="margin-bottom:0;flex:0 0 auto;min-width:100px;">
|
||||
<label>看跌开仓价</label>
|
||||
<input type="number" step="any" name="put_open_price" required placeholder="P权利金" style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group" style="margin-bottom:0;flex:0 0 auto;min-width:130px;">
|
||||
<label>开仓日期</label>
|
||||
<input type="date" name="open_date" value="{{ today }}" required style="font-size:0.85rem;">
|
||||
</div>
|
||||
<div class="form-group" style="margin-bottom:0;flex:0 0 auto;min-width:80px;">
|
||||
<label>C手续费</label>
|
||||
<input type="number" step="any" name="call_open_fee" value="0" style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group" style="margin-bottom:0;flex:0 0 auto;min-width:80px;">
|
||||
<label>P手续费</label>
|
||||
<input type="number" step="any" name="put_open_fee" value="0" style="font-size:0.9rem;">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" style="font-size:0.82rem;padding:8px 18px;">双买开仓</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{# ── 持仓列表 ── #}
|
||||
<div class="section-title">持仓中 · {{ open_trades|length }} 笔</div>
|
||||
|
||||
{% if open_trades %}
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<tr><th>品种</th><th>合约</th><th>行权价</th><th>开仓日期</th><th>看涨开仓价</th><th>看跌开仓价</th><th>C手续费</th><th>P手续费</th><th>总成本</th><th>操作</th></tr>
|
||||
{% for t in open_trades %}
|
||||
<tr>
|
||||
<td>{{ t.product_code }}</td>
|
||||
<td><strong>{{ t.contract_code.replace(t.product_code, '', 1) }}</strong></td>
|
||||
<td>{{ t.strike_price }}</td>
|
||||
<td>{{ t.open_date }} {{ weekdays[t.open_date.weekday()] }}</td>
|
||||
<td>{{ t.call_open_price }}</td>
|
||||
<td>{{ t.put_open_price }}</td>
|
||||
<td>{{ t.call_open_fee or 0 }}</td>
|
||||
<td>{{ t.put_open_fee or 0 }}</td>
|
||||
<td><b>{{ "%.0f"|format(t.total_cost) }}</b></td>
|
||||
<td>
|
||||
<button style="background:var(--accent);color:#fff;border:none;padding:3px 10px;border-radius:4px;cursor:pointer;font-size:0.78rem;"
|
||||
onclick="showCloseForm({{ t.id }})">平仓</button>
|
||||
<button style="background:var(--success-bg);color:var(--success-fg);border:1px solid var(--success);padding:3px 10px;border-radius:4px;cursor:pointer;font-size:0.78rem;margin-left:8px;"
|
||||
onclick="showEditForm({{ t.id }}, '{{ t.product_code }}', '{{ t.contract_code }}', {{ t.strike_price }}, {{ t.call_open_price }}, {{ t.put_open_price }}, {{ t.call_open_fee or 0 }}, {{ t.put_open_fee or 0 }}, '{{ t.open_date }}', null, null, null, null, null, 'open')">编辑</button>
|
||||
<form method="post" action="/dual-options/{{ t.id }}/delete" style="display:inline;margin-left:8px;">
|
||||
<button style="background:transparent;color:#dc2626;border:1px solid #ef4444;padding:3px 10px;border-radius:4px;cursor:pointer;font-size:0.78rem;" onclick="confirmDelete(event, '确定删除此记录?', this.closest('form').action)">删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div style="text-align:center;padding:40px;color:var(--sub);">暂无持仓</div>
|
||||
{% endif %}
|
||||
|
||||
{# ── 平仓弹窗 ── #}
|
||||
<div id="closeFormOverlay" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.35);z-index:99;" onclick="hideCloseForm()"></div>
|
||||
<div id="closeFormBox" style="display:none;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:24px;z-index:100;width:400px;max-width:90vw;">
|
||||
<h3 style="margin-bottom:16px;">双买平仓</h3>
|
||||
<form method="post" id="closeForm">
|
||||
<div class="form-group">
|
||||
<label>平仓日期</label>
|
||||
<input type="date" name="close_date" value="{{ today }}" required style="font-size:0.85rem;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>看涨平仓价</label>
|
||||
<input type="number" step="any" name="call_close_price" required style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>看跌平仓价</label>
|
||||
<input type="number" step="any" name="put_close_price" required style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>看涨手续费</label>
|
||||
<input type="number" step="any" name="call_close_fee" value="0" style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>看跌手续费</label>
|
||||
<input type="number" step="any" name="put_close_fee" value="0" style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div style="display:flex;gap:10px;justify-content:flex-end;">
|
||||
<button type="button" class="btn" style="background:var(--th-bg);color:var(--fg);" onclick="hideCloseForm()">取消</button>
|
||||
<button type="submit" class="btn btn-primary">确认平仓</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="tab-panel active">
|
||||
{# ═══════════════ 已平仓 ═══════════════ #}
|
||||
|
||||
{% if closed_trades %}
|
||||
<div class="section-title">已平仓 · {{ closed_trades|length }} 笔</div>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<tr><th>品种</th><th>合约</th><th>行权价</th><th>开仓日</th><th>平仓日</th><th>持仓</th><th>看涨(开/平)</th><th>看跌(开/平)</th><th>总成本</th><th>盈亏</th><th>操作</th></tr>
|
||||
{% for t in closed_trades %}
|
||||
<tr>
|
||||
<td>{{ t.product_code }}</td>
|
||||
<td><strong>{{ t.contract_code.replace(t.product_code, '', 1) }}</strong></td>
|
||||
<td>{{ t.strike_price }}</td>
|
||||
<td style="font-size:0.8rem;">{{ t.open_date }} {{ weekdays[t.open_date.weekday()] }}</td>
|
||||
<td style="font-size:0.8rem;">{{ t.close_date }} {{ weekdays[t.close_date.weekday()] }}</td>
|
||||
<td>{{ (t.close_date - t.open_date).days }}天</td>
|
||||
<td>{{ t.call_open_price }} / {{ t.call_close_price }}</td>
|
||||
<td>{{ t.put_open_price }} / {{ t.put_close_price }}</td>
|
||||
<td>{{ "%.0f"|format(t.total_cost) }}</td>
|
||||
<td>
|
||||
{% set p = t.pnl %}
|
||||
{% if p is not none %}
|
||||
<span style="font-weight:700;{% if p > 0 %}color:var(--success-fg);{% elif p < 0 %}color:var(--danger-fg);{% else %}color:var(--sub);{% endif %}">
|
||||
{% if p > 0 %}+{% endif %}{{ p }}
|
||||
</span>
|
||||
<span style="color:var(--sub);cursor:pointer;font-size:0.75rem;margin-left:4px;"
|
||||
onclick="showDualPnlDrawer('{{ t.product_code }} {{ t.contract_code.replace(t.product_code, '', 1) }} {{ t.strike_price }}', {{ t.strike_price }}, {{ t.call_open_price }}, {{ t.put_open_price }}, {{ t.call_close_price }}, {{ t.put_close_price }}, {{ t.call_open_fee or 0 }}, {{ t.put_open_fee or 0 }}, {{ t.call_close_fee or 0 }}, {{ t.put_close_fee or 0 }}, {{ p }}, {{ t.point_value }})" title="盈亏分析">ⓘ</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<button style="background:var(--success-bg);color:var(--success-fg);border:1px solid var(--success);padding:3px 10px;border-radius:4px;cursor:pointer;font-size:0.78rem;"
|
||||
onclick="showEditForm({{ t.id }}, '{{ t.product_code }}', '{{ t.contract_code }}', {{ t.strike_price }}, {{ t.call_open_price }}, {{ t.put_open_price }}, {{ t.call_open_fee or 0 }}, {{ t.put_open_fee or 0 }}, '{{ t.open_date }}', {{ t.call_close_price }}, {{ t.put_close_price }}, {{ t.call_close_fee or 0 }}, {{ t.put_close_fee or 0 }}, '{{ t.close_date }}', 'closed')">编辑</button>
|
||||
<form method="post" action="/dual-options/{{ t.id }}/delete" style="display:inline;margin-left:8px;">
|
||||
<button style="background:transparent;color:#dc2626;border:1px solid #ef4444;padding:3px 10px;border-radius:4px;cursor:pointer;font-size:0.78rem;" onclick="confirmDelete(event, '确定删除此记录?', this.closest('form').action)">删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% set ns = namespace(total_pnl=0, total_open_fee=0, total_close_fee=0) %}
|
||||
{% for t in closed_trades %}
|
||||
{% set ns.total_pnl = ns.total_pnl + (t.pnl or 0) %}
|
||||
{% set ns.total_open_fee = ns.total_open_fee + (t.call_open_fee or 0) + (t.put_open_fee or 0) %}
|
||||
{% set ns.total_close_fee = ns.total_close_fee + (t.call_close_fee or 0) + (t.put_close_fee or 0) %}
|
||||
{% endfor %}
|
||||
<div style="display:flex;gap:24px;margin-bottom:24px;padding:12px 18px;background:var(--surface);border:1px solid var(--border);border-radius:8px;font-size:0.88rem;flex-wrap:wrap;">
|
||||
<span>盈亏合计 <b style="{% if ns.total_pnl > 0 %}color:var(--success-fg);{% elif ns.total_pnl < 0 %}color:var(--danger-fg);{% endif %}">{% if ns.total_pnl > 0 %}+{% endif %}{{ '%.2f'|format(ns.total_pnl) }}</b></span>
|
||||
<span style="color:var(--sub);">|</span>
|
||||
<span>开仓手续费 <b>{{ '%.2f'|format(ns.total_open_fee) }}</b></span>
|
||||
<span style="color:var(--sub);">|</span>
|
||||
<span>平仓手续费 <b>{{ '%.2f'|format(ns.total_close_fee) }}</b></span>
|
||||
<span style="color:var(--sub);">|</span>
|
||||
<span>手续费合计 <b>{{ '%.2f'|format(ns.total_open_fee + ns.total_close_fee) }}</b></span>
|
||||
</div>
|
||||
{% else %}
|
||||
<div style="text-align:center;padding:60px;color:var(--sub);">暂无已平仓记录</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# ── 盈亏分析抽屉 ── #}
|
||||
<div id="pnlOverlay" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.35);z-index:99;" onclick="hideDualPnlDrawer()"></div>
|
||||
<div id="pnlBox" style="display:none;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:24px;z-index:100;width:480px;max-width:90vw;max-height:90vh;overflow-y:auto;">
|
||||
<h3 style="margin-bottom:4px;" id="pnlTitle"></h3>
|
||||
<p style="font-size:0.8rem;color:var(--sub);margin-bottom:14px;" id="pnlFormula"></p>
|
||||
<table class="calc-table" style="width:100%;border-collapse:collapse;font-size:0.84rem;margin-bottom:12px;" id="pnlTable"></table>
|
||||
<div style="font-size:0.85rem;color:var(--fg);line-height:1.8;" id="pnlInsight"></div>
|
||||
<button style="position:absolute;top:12px;right:16px;background:none;border:none;font-size:1.3rem;cursor:pointer;color:var(--sub);" onclick="hideDualPnlDrawer()">×</button>
|
||||
</div>
|
||||
|
||||
{% if view != 'closed' %}
|
||||
<script>
|
||||
var productContracts = {{ product_contracts | tojson }};
|
||||
function filterContracts() {
|
||||
var prod = document.getElementById('productSelect').value;
|
||||
var sel = document.getElementById('contractSelect');
|
||||
sel.innerHTML = '<option value="">-- 选择合约 --</option>';
|
||||
sel.disabled = !prod;
|
||||
if (prod && productContracts[prod]) {
|
||||
productContracts[prod].forEach(function(c) {
|
||||
var display = c.startsWith(prod) ? c.substring(prod.length) : c;
|
||||
sel.innerHTML += '<option value="' + c + '">' + display + '</option>';
|
||||
});
|
||||
}
|
||||
}
|
||||
function showCloseForm(tradeId) {
|
||||
document.getElementById('closeForm').action = '/dual-options/' + tradeId + '/close';
|
||||
document.getElementById('closeFormOverlay').style.display = 'block';
|
||||
document.getElementById('closeFormBox').style.display = 'block';
|
||||
}
|
||||
function hideCloseForm() {
|
||||
document.getElementById('closeFormOverlay').style.display = 'none';
|
||||
document.getElementById('closeFormBox').style.display = 'none';
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{# ── 编辑弹窗 ── #}
|
||||
<div id="editFormOverlay" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.35);z-index:98;" onclick="hideEditForm()"></div>
|
||||
<div id="editFormBox" style="display:none;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:24px;z-index:99;width:440px;max-width:90vw;max-height:90vh;overflow-y:auto;">
|
||||
<h3 style="margin-bottom:16px;">编辑双买记录</h3>
|
||||
<form method="post" id="editForm">
|
||||
<div class="form-group">
|
||||
<label>合约</label>
|
||||
<input type="text" name="contract_code" id="editContract" required style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>行权价</label>
|
||||
<input type="number" step="any" name="strike_price" id="editStrike" required style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>开仓日期</label>
|
||||
<input type="date" name="open_date" id="editOpenDate" required style="font-size:0.85rem;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>看涨开仓价</label>
|
||||
<input type="number" step="any" name="call_open_price" id="editCallOpenPrice" required style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>看跌开仓价</label>
|
||||
<input type="number" step="any" name="put_open_price" id="editPutOpenPrice" required style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>看涨手续费</label>
|
||||
<input type="number" step="any" name="call_open_fee" id="editCallOpenFee" value="0" style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>看跌手续费</label>
|
||||
<input type="number" step="any" name="put_open_fee" id="editPutOpenFee" value="0" style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div id="editCloseFields" style="display:none;">
|
||||
<div class="form-group">
|
||||
<label>平仓日期</label>
|
||||
<input type="date" name="close_date" id="editCloseDate" style="font-size:0.85rem;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>看涨平仓价</label>
|
||||
<input type="number" step="any" name="call_close_price" id="editCallClosePrice" style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>看跌平仓价</label>
|
||||
<input type="number" step="any" name="put_close_price" id="editPutClosePrice" style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>看涨平仓手续费</label>
|
||||
<input type="number" step="any" name="call_close_fee" id="editCallCloseFee" value="0" style="font-size:0.9rem;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>看跌平仓手续费</label>
|
||||
<input type="number" step="any" name="put_close_fee" id="editPutCloseFee" value="0" style="font-size:0.9rem;">
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:10px;justify-content:flex-end;">
|
||||
<button type="button" class="btn" style="background:var(--th-bg);color:var(--fg);" onclick="hideEditForm()">取消</button>
|
||||
<button type="submit" class="btn btn-primary">保存</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{# ── 通用确认弹窗 ── #}
|
||||
<div id="confirmOverlay" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.35);z-index:199;" onclick="hideConfirm()"></div>
|
||||
<div id="confirmBox" style="display:none;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:28px 32px;z-index:200;text-align:center;max-width:90vw;">
|
||||
<p id="confirmMsg" style="font-size:0.95rem;margin-bottom:20px;"></p>
|
||||
<div style="display:flex;gap:10px;justify-content:center;">
|
||||
<button class="btn" style="background:var(--th-bg);color:var(--fg);" onclick="hideConfirm()">取消</button>
|
||||
<button class="btn" style="background:var(--danger);color:#fff;" id="confirmBtn">确认删除</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function showDualPnlDrawer(title, strikePrice, callOpen, putOpen, callClose, putClose, callOpenFee, putOpenFee, callCloseFee, putCloseFee, pnl, pointValue) {
|
||||
document.getElementById('pnlTitle').textContent = title + ' 双买分析';
|
||||
document.getElementById('pnlFormula').textContent = '行权价: ' + strikePrice + ' | 每点 ' + pointValue + ' 元';
|
||||
|
||||
var totalPremium = callOpen + putOpen;
|
||||
var totalOpenFee = callOpenFee + putOpenFee;
|
||||
var totalCloseFee = callCloseFee + putCloseFee;
|
||||
var totalFee = totalOpenFee + totalCloseFee;
|
||||
var premiumRmb = totalPremium * pointValue;
|
||||
var totalCost = premiumRmb + totalOpenFee;
|
||||
var beUpper = strikePrice + totalPremium;
|
||||
var beLower = strikePrice - totalPremium;
|
||||
var callPnl = (callClose - callOpen) * pointValue - callOpenFee - callCloseFee;
|
||||
var putPnl = (putClose - putOpen) * pointValue - putOpenFee - putCloseFee;
|
||||
|
||||
var colorFn = function(v) {
|
||||
if (v > 0) return 'color:var(--success-fg);';
|
||||
if (v < 0) return 'color:var(--danger-fg);';
|
||||
return 'color:var(--sub);';
|
||||
};
|
||||
var signed = function(v) { return (v > 0 ? '+' : '') + v.toFixed(2); };
|
||||
|
||||
var html = '<tr style="background:var(--th-bg);"><td>项目</td><td>计算</td><td style="text-align:right;">金额</td></tr>';
|
||||
html += '<tr><td>总权利金(/点)</td><td>' + callOpen + ' + ' + putOpen + '</td><td style="text-align:right;">' + totalPremium.toFixed(2) + ' 点</td></tr>';
|
||||
html += '<tr><td>总权利金(元)</td><td>' + totalPremium.toFixed(2) + ' × ' + pointValue + '</td><td style="text-align:right;">' + premiumRmb.toFixed(2) + '</td></tr>';
|
||||
html += '<tr><td>开仓手续费</td><td>C:' + callOpenFee + ' + P:' + putOpenFee + '</td><td style="text-align:right;color:var(--danger-fg);">-' + totalOpenFee.toFixed(2) + '</td></tr>';
|
||||
html += '<tr><td>平仓手续费</td><td>C:' + callCloseFee + ' + P:' + putCloseFee + '</td><td style="text-align:right;color:var(--danger-fg);">-' + totalCloseFee.toFixed(2) + '</td></tr>';
|
||||
html += '<tr style="font-weight:600;"><td>总成本</td><td>' + premiumRmb.toFixed(2) + ' + ' + totalOpenFee.toFixed(2) + '</td><td style="text-align:right;">' + totalCost.toFixed(2) + '</td></tr>';
|
||||
html += '<tr><td>盈亏平衡点(上)</td><td>' + strikePrice + ' + ' + totalPremium.toFixed(2) + '</td><td style="text-align:right;">' + beUpper.toFixed(2) + '</td></tr>';
|
||||
html += '<tr><td>盈亏平衡点(下)</td><td>' + strikePrice + ' - ' + totalPremium.toFixed(2) + '</td><td style="text-align:right;">' + beLower.toFixed(2) + '</td></tr>';
|
||||
html += '<tr style="background:var(--th-bg);"><td colspan="3"></td></tr>';
|
||||
html += '<tr><td>看涨盈亏</td><td>(' + callClose + ' - ' + callOpen + ') × ' + pointValue + ' - ' + callOpenFee + ' - ' + callCloseFee + '</td><td style="text-align:right;font-weight:600;' + colorFn(callPnl) + '">' + signed(callPnl) + '</td></tr>';
|
||||
html += '<tr><td>看跌盈亏</td><td>(' + putClose + ' - ' + putOpen + ') × ' + pointValue + ' - ' + putOpenFee + ' - ' + putCloseFee + '</td><td style="text-align:right;font-weight:600;' + colorFn(putPnl) + '">' + signed(putPnl) + '</td></tr>';
|
||||
document.getElementById('pnlTable').innerHTML = html;
|
||||
|
||||
var insight = '<b style="' + colorFn(pnl) + '">组合盈亏 = ' + signed(pnl) + '</b><br>';
|
||||
insight += '最大亏损 = ' + totalCost.toFixed(2) + ' 元(标的价格 = ' + strikePrice + ' 时)<br>';
|
||||
insight += '盈利区间: 标的价格 > ' + beUpper.toFixed(2) + ' 或 < ' + beLower.toFixed(2);
|
||||
|
||||
document.getElementById('pnlInsight').innerHTML = insight;
|
||||
document.getElementById('pnlOverlay').style.display = 'block';
|
||||
document.getElementById('pnlBox').style.display = 'block';
|
||||
}
|
||||
|
||||
function showEditForm(id, productCode, contractCode, strike, callOpen, putOpen, callOpenFee, putOpenFee, openDate, callClose, putClose, callCloseFee, putCloseFee, closeDate, status) {
|
||||
document.getElementById('editForm').action = '/dual-options/' + id + '/edit';
|
||||
document.getElementById('editContract').value = contractCode;
|
||||
document.getElementById('editStrike').value = strike;
|
||||
document.getElementById('editOpenDate').value = openDate;
|
||||
document.getElementById('editCallOpenPrice').value = callOpen;
|
||||
document.getElementById('editPutOpenPrice').value = putOpen;
|
||||
document.getElementById('editCallOpenFee').value = callOpenFee || 0;
|
||||
document.getElementById('editPutOpenFee').value = putOpenFee || 0;
|
||||
if (status === 'closed' && closeDate) {
|
||||
document.getElementById('editCloseFields').style.display = 'block';
|
||||
document.getElementById('editCloseDate').value = closeDate;
|
||||
document.getElementById('editCallClosePrice').value = callClose;
|
||||
document.getElementById('editPutClosePrice').value = putClose;
|
||||
document.getElementById('editCallCloseFee').value = callCloseFee || 0;
|
||||
document.getElementById('editPutCloseFee').value = putCloseFee || 0;
|
||||
} else {
|
||||
document.getElementById('editCloseFields').style.display = 'none';
|
||||
}
|
||||
document.getElementById('editFormOverlay').style.display = 'block';
|
||||
document.getElementById('editFormBox').style.display = 'block';
|
||||
}
|
||||
|
||||
function hideEditForm() {
|
||||
document.getElementById('editFormOverlay').style.display = 'none';
|
||||
document.getElementById('editFormBox').style.display = 'none';
|
||||
}
|
||||
|
||||
function hideDualPnlDrawer() {
|
||||
document.getElementById('pnlOverlay').style.display = 'none';
|
||||
document.getElementById('pnlBox').style.display = 'none';
|
||||
}
|
||||
|
||||
function confirmDelete(e, msg, url) {
|
||||
e.preventDefault();
|
||||
document.getElementById('confirmMsg').textContent = msg;
|
||||
document.getElementById('confirmBtn').onclick = function() {
|
||||
var f = document.createElement('form');
|
||||
f.method = 'POST';
|
||||
f.action = url;
|
||||
document.body.appendChild(f);
|
||||
f.submit();
|
||||
};
|
||||
document.getElementById('confirmOverlay').style.display = 'block';
|
||||
document.getElementById('confirmBox').style.display = 'block';
|
||||
}
|
||||
|
||||
function hideConfirm() {
|
||||
document.getElementById('confirmOverlay').style.display = 'none';
|
||||
document.getElementById('confirmBox').style.display = 'none';
|
||||
}
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user