双买持仓页面新增分析按钮,展示盈亏平衡点和盈利区间

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
fish
2026-07-28 14:42:39 +08:00
parent 39c5e22ed6
commit fcaf2dc2d4
+34 -1
View File
@@ -101,7 +101,9 @@
<td>{{ t.put_open_fee or 0 }}</td> <td>{{ t.put_open_fee or 0 }}</td>
<td><b>{{ "%.0f"|format(t.total_cost) }}</b></td> <td><b>{{ "%.0f"|format(t.total_cost) }}</b></td>
<td> <td>
<button style="background:var(--accent);color:#fff;border:none;padding:3px 10px;border-radius:4px;cursor:pointer;font-size:0.78rem;" <button style="background:var(--warn);color:#fff;border:none;padding:3px 10px;border-radius:4px;cursor:pointer;font-size:0.78rem;"
onclick="showOpenAnalysis('{{ t.product_code }} {{ t.contract_code.replace(t.product_code, '', 1) }}', {{ t.call_strike_price }}, {{ t.put_strike_price }}, {{ t.call_open_price }}, {{ t.put_open_price }}, {{ t.call_open_fee or 0 }}, {{ t.put_open_fee or 0 }}, {{ t.point_value }})">分析</button>
<button style="background:var(--accent);color:#fff;border:none;padding:3px 10px;border-radius:4px;cursor:pointer;font-size:0.78rem;margin-left:8px;"
onclick="showCloseForm({{ t.id }})">平仓</button> 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;" <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.call_strike_price }}, {{ t.put_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> onclick="showEditForm({{ t.id }}, '{{ t.product_code }}', '{{ t.contract_code }}', {{ t.call_strike_price }}, {{ t.put_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>
@@ -329,6 +331,37 @@ function hideCloseForm() {
</div> </div>
<script> <script>
function showOpenAnalysis(title, callStrike, putStrike, callOpen, putOpen, callOpenFee, putOpenFee, pointValue) {
document.getElementById('pnlTitle').textContent = title + ' 持仓分析';
document.getElementById('pnlFormula').textContent = 'C行权价: ' + callStrike + ' P行权价: ' + putStrike + ' | 每点 ' + pointValue + ' 元';
var totalPremium = callOpen + putOpen;
var totalOpenFee = callOpenFee + putOpenFee;
var premiumRmb = totalPremium * pointValue;
var totalCost = premiumRmb + totalOpenFee;
var beUpper = callStrike + totalPremium;
var beLower = putStrike - totalPremium;
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 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 style="background:var(--accent-light);"><td><b>盈亏平衡点(上)</b></td><td>' + callStrike + ' + ' + totalPremium.toFixed(2) + '</td><td style="text-align:right;font-weight:600;">' + beUpper.toFixed(2) + '</td></tr>';
html += '<tr style="background:var(--accent-light);"><td><b>盈亏平衡点(下)</b></td><td>' + putStrike + ' - ' + totalPremium.toFixed(2) + '</td><td style="text-align:right;font-weight:600;">' + beLower.toFixed(2) + '</td></tr>';
document.getElementById('pnlTable').innerHTML = html;
var insight = '<b>最大亏损 = ' + totalCost.toFixed(2) + ' 元</b>(标的价格在 ' + putStrike + ' ~ ' + callStrike + ' 区间时)<br>';
insight += '盈利区间: 标的价格 &gt; <b style="color:var(--success-fg);">' + beUpper.toFixed(2) + '</b> 或 &lt; <b style="color:var(--success-fg);">' + beLower.toFixed(2) + '</b><br>';
insight += '<span style="color:var(--sub);">平仓后可在已平仓页查看实际盈亏明细</span>';
document.getElementById('pnlInsight').innerHTML = insight;
document.getElementById('pnlOverlay').style.display = 'block';
document.getElementById('pnlBox').style.display = 'block';
}
function showDualPnlDrawer(title, callStrike, putStrike, callOpen, putOpen, callClose, putClose, callOpenFee, putOpenFee, callCloseFee, putCloseFee, pnl, pointValue) { function showDualPnlDrawer(title, callStrike, putStrike, callOpen, putOpen, callClose, putClose, callOpenFee, putOpenFee, callCloseFee, putCloseFee, pnl, pointValue) {
document.getElementById('pnlTitle').textContent = title + ' 双买分析'; document.getElementById('pnlTitle').textContent = title + ' 双买分析';
document.getElementById('pnlFormula').textContent = 'C行权价: ' + callStrike + ' P行权价: ' + putStrike + ' | 每点 ' + pointValue + ' 元'; document.getElementById('pnlFormula').textContent = 'C行权价: ' + callStrike + ' P行权价: ' + putStrike + ' | 每点 ' + pointValue + ' 元';