test2026 / index.html
Bondya's picture
Update index.html
976095e verified
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>财顾报价通 - 理财公司预期收益率报价系统</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
:root {
--primary-color: #2c3e50;
--secondary-color: #3498db;
--success-color: #27ae60;
--warning-color: #f39c12;
--danger-color: #e74c3c;
--light-color: #ecf0f1;
--dark-color: #34495e;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
color: #333;
line-height: 1.6;
min-height: 100vh;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
header {
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
margin-bottom: 30px;
text-align: center;
}
.logo {
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
margin-bottom: 10px;
}
.logo h1 {
color: var(--primary-color);
font-size: 2.2rem;
}
.subtitle {
color: var(--dark-color);
opacity: 0.8;
}
.calculator {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 30px;
margin-bottom: 40px;
}
@media (max-width: 768px) {
.calculator {
grid-template-columns: 1fr;
}
}
.panel {
background: white;
padding: 25px;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}
.panel h2 {
color: var(--primary-color);
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 2px solid var(--light-color);
display: flex;
align-items: center;
gap: 10px;
}
.form-group {
margin-bottom: 25px;
}
.form-group label {
display: block;
margin-bottom: 10px;
font-weight: 600;
color: var(--dark-color);
font-size: 1.1rem;
}
.button-group {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.btn {
padding: 12px 20px;
border: 2px solid #ddd;
background: white;
color: var(--dark-color);
border-radius: 6px;
cursor: pointer;
font-weight: 500;
transition: all 0.3s ease;
flex: 1;
min-width: 120px;
text-align: center;
}
.btn:hover {
border-color: var(--secondary-color);
color: var(--secondary-color);
}
.btn.active {
background: var(--secondary-color);
color: white;
border-color: var(--secondary-color);
}
.calculate-btn {
width: 100%;
padding: 16px;
background: linear-gradient(135deg, var(--secondary-color), #2980b9);
color: white;
border: none;
border-radius: 8px;
font-size: 1.1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
margin-top: 10px;
}
.calculate-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.preview-item {
display: flex;
justify-content: space-between;
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 1px solid var(--light-color);
}
.preview-label {
font-weight: 500;
}
.preview-value {
font-weight: 600;
color: var(--secondary-color);
}
.result-section {
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
margin-top: 30px;
}
.result-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 25px;
margin: 25px 0;
}
.result-card {
background: #f8f9fa;
padding: 20px;
border-radius: 8px;
border-left: 4px solid var(--secondary-color);
}
.result-item {
display: flex;
justify-content: space-between;
margin-bottom: 12px;
}
.highlight {
color: var(--success-color);
font-weight: 600;
font-size: 1.2rem;
}
.loading {
text-align: center;
padding: 30px;
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid var(--secondary-color);
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 15px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.hidden {
display: none;
}
.feature-list {
list-style: none;
padding-left: 0;
}
.feature-list li {
padding: 8px 0;
display: flex;
align-items: center;
gap: 10px;
}
.feature-list li i {
color: var(--success-color);
}
footer {
text-align: center;
margin-top: 40px;
padding-top: 20px;
border-top: 1px solid #ddd;
color: #666;
font-size: 0.9rem;
}
.contribution-breakdown {
background: #f0f8ff;
padding: 15px;
border-radius: 6px;
margin-top: 15px;
}
.contribution-item {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
font-size: 0.95rem;
}
.range-indicator {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
font-size: 0.85rem;
margin-left: 5px;
}
.range-pessimistic {
background: #ffebee;
color: #c62828;
}
.range-neutral {
background: #fff3e0;
color: #ef6c00;
}
.range-optimistic {
background: #e8f5e9;
color: #2e7d32;
}
.bp-unit {
font-size: 0.85rem;
color: #666;
margin-left: 2px;
}
</style>
</head>
<body>
<div class="container">
<header>
<div class="logo">
<h1>财顾报价通</h1>
</div>
<p class="subtitle">理财公司预期收益率报价系统 - 增强版</p>
</header>
<div class="calculator">
<div class="panel">
<h2>⚙️ 参数设置</h2>
<div class="form-group">
<label>策略类型</label>
<div class="button-group">
<button class="btn active" data-type="strategy" data-value="PURE_BOND">纯债策略</button>
<button class="btn" data-type="strategy" data-value="FIXED_INCOME_PLUS">固收+策略</button>
</div>
</div>
<div class="form-group">
<label>投资期限</label>
<div class="button-group">
<button class="btn active" data-type="period" data-value="SHORT">短期(0-3个月)</button>
<button class="btn" data-type="period" data-value="MEDIUM">中期(3-6个月)</button>
<button class="btn" data-type="period" data-value="LONG">长期(6-12个月)</button>
</div>
</div>
<div class="form-group">
<label>风险风格</label>
<div class="button-group">
<button class="btn active" data-type="risk" data-value="CONSERVATIVE">保守型</button>
<button class="btn" data-type="risk" data-value="NEUTRAL">中性型</button>
<button class="btn" data-type="risk" data-value="AGGRESSIVE">激进型</button>
</div>
</div>
<div id="plus-section" class="form-group hidden">
<label>增强资产类别</label>
<div class="button-group">
<button class="btn active" data-type="asset" data-value="CONVERTIBLE_BOND">转债</button>
<button class="btn" data-type="asset" data-value="EQUITY">权益</button>
<button class="btn" data-type="asset" data-value="REITS">REITs</button>
</div>
<label style="margin-top: 20px; display: block;">资产预期</label>
<div class="button-group">
<button class="btn" data-type="expectation" data-value="PESSIMISTIC">悲观</button>
<button class="btn active" data-type="expectation" data-value="NEUTRAL">中性</button>
<button class="btn" data-type="expectation" data-value="OPTIMISTIC">乐观</button>
</div>
<div style="margin-top: 10px; font-size: 0.9rem; color: #666; padding: 8px; background: #f5f5f5; border-radius: 4px;">
<div><strong>配置比例:</strong> 悲观(95%债+5%资产) | 中性(90%债+10%资产) | 乐观(80%债+20%资产)</div>
</div>
</div>
<button id="calculate" class="calculate-btn">🚀 计算预期收益率</button>
</div>
<div class="panel">
<h2>👁️ 参数预览</h2>
<div id="preview">
<div class="preview-item">
<span class="preview-label">策略类型:</span>
<span id="preview-strategy" class="preview-value">纯债策略</span>
</div>
<div class="preview-item">
<span class="preview-label">投资期限:</span>
<span id="preview-period" class="preview-value">短期(0-3个月)</span>
</div>
<div class="preview-item">
<span class="preview-label">风险风格:</span>
<span id="preview-risk" class="preview-value">保守型</span>
</div>
<div class="preview-item hidden" id="preview-asset-item">
<span class="preview-label">增强资产:</span>
<span id="preview-asset" class="preview-value">转债</span>
</div>
<div class="preview-item hidden" id="preview-expectation-item">
<span class="preview-label">资产预期:</span>
<span id="preview-expectation" class="preview-value">中性</span>
</div>
</div>
<h2 style="margin-top: 30px;">✨ 系统特点</h2>
<ul class="feature-list">
<li><i></i> 基于量化模型计算</li>
<li><i></i> 正态分布资本利得模型</li>
<li><i></i> 详细收益贡献分解</li>
<li><i></i> 市场实际参考区间</li>
<li><i></i> 纯前端计算,保护隐私</li>
</ul>
</div>
</div>
<div id="loading" class="loading hidden">
<div class="spinner"></div>
<p>正在计算预期收益率...</p>
</div>
<div id="result" class="result-section hidden">
<h2>📊 报价结果详情</h2>
<div id="result-content"></div>
</div>
<footer>
<p>© 2024 财顾报价通 | 仅供演示使用 | 计算结果仅供参考,不构成投资建议</p>
</footer>
</div>
<script>
// 全局状态
const state = {
strategy: 'PURE_BOND',
period: 'SHORT',
risk: 'CONSERVATIVE',
asset: 'CONVERTIBLE_BOND',
expectation: 'NEUTRAL',
updatePreview() {
document.getElementById('preview-strategy').textContent =
this.strategy === 'PURE_BOND' ? '纯债策略' : '固收+策略';
document.getElementById('preview-period').textContent =
this.getPeriodLabel(this.period);
document.getElementById('preview-risk').textContent =
this.getRiskLabel(this.risk);
const plusSection = document.getElementById('plus-section');
const assetPreview = document.getElementById('preview-asset-item');
const expectationPreview = document.getElementById('preview-expectation-item');
if (this.strategy === 'FIXED_INCOME_PLUS') {
plusSection.classList.remove('hidden');
assetPreview.classList.remove('hidden');
expectationPreview.classList.remove('hidden');
document.getElementById('preview-asset').textContent =
this.getAssetLabel(this.asset);
document.getElementById('preview-expectation').textContent =
this.getExpectationLabel(this.expectation);
} else {
plusSection.classList.add('hidden');
assetPreview.classList.add('hidden');
expectationPreview.classList.add('hidden');
}
},
getPeriodLabel(value) {
const labels = {
'SHORT': '短期(0-3个月)',
'MEDIUM': '中期(3-6个月)',
'LONG': '长期(6-12个月)'
};
return labels[value];
},
getRiskLabel(value) {
const labels = {
'CONSERVATIVE': '保守型',
'NEUTRAL': '中性型',
'AGGRESSIVE': '激进型'
};
return labels[value];
},
getAssetLabel(value) {
const labels = {
'CONVERTIBLE_BOND': '转债',
'EQUITY': '权益',
'REITS': 'REITs'
};
return labels[value];
},
getExpectationLabel(value) {
const labels = {
'PESSIMISTIC': '悲观',
'NEUTRAL': '中性',
'OPTIMISTIC': '乐观'
};
return labels[value];
}
};
// 正态分布函数
function normalCDF(x, mean = 0, std = 1) {
return 0.5 * (1 + erf((x - mean) / (std * Math.sqrt(2))));
}
function erf(x) {
const a1 = 0.254829592;
const a2 = -0.284496736;
const a3 = 1.421413741;
const a4 = -1.453152027;
const a5 = 1.061405429;
const p = 0.3275911;
const sign = (x >= 0) ? 1 : -1;
x = Math.abs(x);
const t = 1.0 / (1.0 + p * x);
const y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * Math.exp(-x * x);
return sign * y;
}
function normalQuantile(p, mean = 0, std = 1) {
if (p <= 0 || p >= 1) return mean;
const a1 = -39.6968302866538, a2 = 220.946098424521, a3 = -275.928510446969;
const a4 = 138.357751867269, a5 = -30.6647980661472, a6 = 2.50662827745924;
const b1 = -54.4760987982241, b2 = 161.585836858041, b3 = -155.698979859887;
const b4 = 66.8013118877197, b5 = -13.2806815528857;
const c1 = -7.78489400243029E-03, c2 = -0.322396458041136, c3 = -2.40075827716184;
const c4 = -2.54973253934373, c5 = 4.37466414146497, c6 = 2.93816398269878;
const d1 = 7.78469570904146E-03, d2 = 0.32246712907004, d3 = 2.445134137143;
const d4 = 3.75440866190742;
let q, r;
if (p < 0.02425) {
q = Math.sqrt(-2 * Math.log(p));
return mean + std * (((((c1 * q + c2) * q + c3) * q + c4) * q + c5) * q + c6) /
((((d1 * q + d2) * q + d3) * q + d4) * q + 1);
} else if (p <= 0.97575) {
q = p - 0.5;
r = q * q;
return mean + std * (((((a1 * r + a2) * r + a3) * r + a4) * r + a5) * r + a6) * q /
(((((b1 * r + b2) * r + b3) * r + b4) * r + b5) * r + 1);
} else {
q = Math.sqrt(-2 * Math.log(1 - p));
return mean + std * -(((((c1 * q + c2) * q + c3) * q + c4) * q + c5) * q + c6) /
((((d1 * q + d2) * q + d3) * q + d4) * q + 1);
}
}
// 计算资本利得区间(基于正态分布,第50-80百分位)
function calculateCapitalGainRange(period) {
// 确定波段次数(按照我们讨论的逻辑)
let cycles;
switch(period) {
case 'SHORT': cycles = 1; break; // 0-3个月:1次
case 'MEDIUM': cycles = 1.5; break; // 3-6个月:1.5次
case 'LONG': cycles = 3; break; // 6-12个月:3次
default: cycles = 1;
}
// 单次波段参数:正态分布 N(0, σ),σ=18bp
const singleStd = 18; // 18bp标准差,基于我们讨论的参数
const singleMean = 0; // 均值为0,第50百分位不亏钱
// 年化分布参数(n次独立同分布的和)
const annualMean = singleMean * cycles;
const annualStd = singleStd * Math.sqrt(cycles);
// 计算第80百分位(因为我们取第50-80百分位区间,下限为0,上限为第80百分位)
const p80 = normalQuantile(0.8, annualMean, annualStd);
return {
lower: 0, // 第50百分位为0
upper: p80 / 100 // 转换为百分比
};
}
// 初始化
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.btn').forEach(btn => {
btn.addEventListener('click', function() {
const type = this.dataset.type;
const value = this.dataset.value;
document.querySelectorAll(`.btn[data-type="${type}"]`).forEach(b => {
b.classList.remove('active');
});
this.classList.add('active');
state[type] = value;
state.updatePreview();
});
});
document.getElementById('calculate').addEventListener('click', calculateQuotation);
});
// 计算核心函数
function calculateQuotation() {
document.getElementById('loading').classList.remove('hidden');
document.getElementById('result').classList.add('hidden');
setTimeout(() => {
try {
const result = performCalculation();
displayResults(result);
} catch (error) {
alert('计算错误: ' + error.message);
} finally {
document.getElementById('loading').classList.add('hidden');
}
}, 800);
}
// 核心计算逻辑
function performCalculation() {
const { strategy, period, risk, asset, expectation } = state;
// 使用您提供的默认收益率数据
const defaultReturns = {
"7d_notice_deposit": 1.35,
"3m_state_ncd": 1.55,
"overnight_rate": 1.28,
"gov_bond_under_1y": 1.57,
"gov_bond_under_2y": 1.60,
"gov_bond_under_3y": 1.70,
"gov_bond_under_5y": 1.88,
"ncd_1y_state": 1.62,
"ncd_1y_aaa": 1.65,
"ncd_1y_aa": 1.71,
"credit_1y_aaa_plus": 1.7,
"credit_1y_aaa": 1.81,
"credit_1y_aa": 2.1,
"credit_2y_aaa_plus": 1.8,
"credit_2y_aaa": 2.09,
"credit_2y_aa": 2.54,
};
// 资产预期收益率区间(使用您提供的数据)
const assetReturnRanges = {
'CONVERTIBLE_BOND': {
'PESSIMISTIC': { min: -5, max: 0 },
'NEUTRAL': { min: 0, max: 6 },
'OPTIMISTIC': { min: 6, max: 12 }
},
'EQUITY': {
'PESSIMISTIC': { min: -10, max: 0 },
'NEUTRAL': { min: 0, max: 10 },
'OPTIMISTIC': { min: 10, max: 20 }
},
'REITS': {
'PESSIMISTIC': { min: -5, max: -1 },
'NEUTRAL': { min: -1, max: 3 },
'OPTIMISTIC': { min: 3, max: 7 }
}
};
// 市场参考数据
const marketRef = {
pure_bond: {
'SHORT': [1.24, 1.40],
'MEDIUM': [1.74, 3.00],
'LONG': [2.05, 3.24]
},
fixed_income_plus: {
'SHORT': [1.24, 1.60],
'MEDIUM': [1.84, 2.94],
'LONG': [2.18, 3.03]
}
};
// 计算基础收益率(不含资本利得)- 已按照您的最新要求更新
function calculateBaseReturn() {
let baseReturn = 0;
let leverage = 100;
if (period === 'SHORT') {
// 短期限配置 - 无杠杆
if (risk === 'CONSERVATIVE') {
// 保守:7天通知存款50%,实时3m国股行同业存单20%,实时隔夜利率30%
baseReturn = defaultReturns['7d_notice_deposit'] * 0.5 +
defaultReturns['3m_state_ncd'] * 0.2 +
defaultReturns['overnight_rate'] * 0.3;
} else if (risk === 'NEUTRAL') {
// 中性:7天通知存款40%,实时3m国股行同业存单35%,实时隔夜利率25%
baseReturn = defaultReturns['7d_notice_deposit'] * 0.4 +
defaultReturns['3m_state_ncd'] * 0.35 +
defaultReturns['overnight_rate'] * 0.25;
} else { // AGGRESSIVE
// 激进:7天通知存款30%,实时3m国股行同业存单50%,实时隔夜利率20%
baseReturn = defaultReturns['7d_notice_deposit'] * 0.3 +
defaultReturns['3m_state_ncd'] * 0.5 +
defaultReturns['overnight_rate'] * 0.2;
}
} else if (period === 'MEDIUM') {
// 中期限配置
if (risk === 'CONSERVATIVE') {
// 保守:1y以下利率政金债占15,2y以下利率政金债占15,
// 1yAAA+信用债占15,1yAAA信用债占20,1yAA信用债占50,且不加杠杆
baseReturn = defaultReturns['gov_bond_under_2y'] * 0.15 +
defaultReturns['credit_1y_aaa_plus'] * 0.15 +
defaultReturns['credit_1y_aaa'] * 0.2 +
defaultReturns['credit_1y_aa'] * 0.5;
leverage = 100; // 不加杠杆
} else if (risk === 'NEUTRAL') {
// 中性:2y以下利率政金债占20,1yAAA+信用债占10,
// 1yAAA信用债占10,1yAA信用债占60,且杠杆率为120
baseReturn = defaultReturns['gov_bond_under_2y'] * 0.2 +
defaultReturns['credit_1y_aaa_plus'] * 0.1 +
defaultReturns['credit_1y_aaa'] * 0.1 +
defaultReturns['credit_1y_aa'] * 0.6;
leverage = 120; // 杠杆率120
} else { // AGGRESSIVE
// 激进:2y以下利率政金债占20,1yAAA信用债占10,
// 1yAA信用债占70,且杠杆率为140
baseReturn = defaultReturns['gov_bond_under_2y'] * 0.2 +
defaultReturns['credit_1y_aaa'] * 0.1 +
defaultReturns['credit_1y_aa'] * 0.7;
leverage = 140; // 杠杆率140
}
} else { // LONG - 长期限
if (risk === 'CONSERVATIVE') {
// 保守:5y以下利率政金债占15,2yAAA+信用债占15,
// 2yAAA信用债占20,2yAA信用债占50,且不加杠杆
baseReturn = defaultReturns['gov_bond_under_5y'] * 0.15 +
defaultReturns['credit_2y_aaa_plus'] * 0.15 +
defaultReturns['credit_2y_aaa'] * 0.2 +
defaultReturns['credit_2y_aa'] * 0.5;
leverage = 100; // 不加杠杆
} else if (risk === 'NEUTRAL') {
// 中性:5y以下利率政金债占20,2yAAA+信用债占15,
// 2yAAA信用债占15,2yAA信用债占50,且杠杆率为120
baseReturn = defaultReturns['gov_bond_under_5y'] * 0.2 +
defaultReturns['credit_2y_aaa_plus'] * 0.15 +
defaultReturns['credit_2y_aaa'] * 0.15 +
defaultReturns['credit_2y_aa'] * 0.5;
leverage = 120; // 杠杆率120
} else { // AGGRESSIVE
// 激进:5y以下利率政金债占20,2yAAA信用债占10,
// 2yAA信用债占70,且杠杆率为140
baseReturn = defaultReturns['gov_bond_under_5y'] * 0.2 +
defaultReturns['credit_2y_aaa'] * 0.1 +
defaultReturns['credit_2y_aa'] * 0.7;
leverage = 140; // 杠杆率140
}
}
// 杠杆计算
const fundingCost = defaultReturns['overnight_rate'];
let leveredReturn = baseReturn;
if (leverage > 100) {
const L = leverage / 100;
leveredReturn = L * baseReturn - (L - 1) * fundingCost;
}
return {
baseReturn: leveredReturn,
leverage: leverage,
fundingCost: fundingCost
};
}
// 纯债策略计算
if (strategy === 'PURE_BOND') {
const bondResult = calculateBaseReturn();
const capGain = calculateCapitalGainRange(period);
// 总收益率区间 = 基础收益率 + 资本利得区间
const totalLower = bondResult.baseReturn + capGain.lower;
const totalUpper = bondResult.baseReturn + capGain.upper;
return {
strategy: '纯债策略',
period: state.getPeriodLabel(period),
risk: state.getRiskLabel(risk),
leverage: bondResult.leverage + '%',
fundingCost: bondResult.fundingCost.toFixed(2) + '%',
baseReturn: bondResult.baseReturn.toFixed(2) + '%',
capitalGainRange: `${(capGain.lower * 100).toFixed(2)}bp ~ ${(capGain.upper * 100).toFixed(2)}bp`,
capitalGainLower: capGain.lower,
capitalGainUpper: capGain.upper,
totalReturn: `${totalLower.toFixed(2)}% ~ ${totalUpper.toFixed(2)}%`,
totalLower: totalLower,
totalUpper: totalUpper,
marketRef: `${marketRef.pure_bond[period][0]}% - ${marketRef.pure_bond[period][1]}%`,
hasCapitalGain: true
};
}
// 固收+策略计算
else {
// 计算纯债部分
const bondResult = calculateBaseReturn();
const capGain = calculateCapitalGainRange(period);
// 获取资产预期收益率区间
const assetRange = assetReturnRanges[asset][expectation];
// 配置比例
let bondWeight, assetWeight;
if (expectation === 'PESSIMISTIC') {
bondWeight = 95;
assetWeight = 5;
} else if (expectation === 'NEUTRAL') {
bondWeight = 90;
assetWeight = 10;
} else { // OPTIMISTIC
bondWeight = 80;
assetWeight = 20;
}
// 计算资本利得贡献(考虑债券权重)
const capitalGainLower = capGain.lower * bondWeight / 100;
const capitalGainUpper = capGain.upper * bondWeight / 100;
// 计算增强资产贡献区间(考虑资产权重)
const assetContributionLower = assetRange.min * assetWeight / 100;
const assetContributionUpper = assetRange.max * assetWeight / 100;
// 计算纯债基础部分贡献(考虑债券权重)
const baseBondContribution = bondResult.baseReturn * bondWeight / 100;
// 计算总收益率区间
// 下限:基础债券贡献 + 资本利得下限 + 资产贡献下限
const totalLower = baseBondContribution + capitalGainLower + assetContributionLower;
// 上限:基础债券贡献 + 资本利得上限 + 资产贡献上限
const totalUpper = baseBondContribution + capitalGainUpper + assetContributionUpper;
return {
strategy: '固收+策略',
period: state.getPeriodLabel(period),
risk: state.getRiskLabel(risk),
asset: state.getAssetLabel(asset),
expectation: state.getExpectationLabel(expectation),
expectationType: expectation,
bondWeight: bondWeight + '%',
assetWeight: assetWeight + '%',
baseBondReturn: bondResult.baseReturn.toFixed(2) + '%',
baseBondContribution: baseBondContribution.toFixed(2) + '%',
capitalGainRange: `${(capGain.lower * 100).toFixed(2)}bp ~ ${(capGain.upper * 100).toFixed(2)}bp`,
capitalGainLower: capitalGainLower,
capitalGainUpper: capitalGainUpper,
assetReturnRange: `${assetRange.min}% ~ ${assetRange.max}%`,
assetContributionRange: `${assetContributionLower.toFixed(2)}% ~ ${assetContributionUpper.toFixed(2)}%`,
totalReturn: `${totalLower.toFixed(2)}% ~ ${totalUpper.toFixed(2)}%`,
totalLower: totalLower,
totalUpper: totalUpper,
marketRef: `${marketRef.fixed_income_plus[period][0]}% - ${marketRef.fixed_income_plus[period][1]}%`,
hasCapitalGain: true
};
}
}
// 显示结果
function displayResults(result) {
const content = document.getElementById('result-content');
let html = `
<div class="result-grid">
<div class="result-card">
<h3>📋 基本信息</h3>
<div class="result-item">
<span>策略类型:</span>
<span class="highlight">${result.strategy}</span>
</div>
<div class="result-item">
<span>投资期限:</span>
<span>${result.period}</span>
</div>
<div class="result-item">
<span>风险风格:</span>
<span>${result.risk}</span>
</div>`;
if (result.strategy === '纯债策略') {
html += `
<div class="result-item">
<span>杠杆率:</span>
<span>${result.leverage}</span>
</div>
<div class="result-item">
<span>融资成本:</span>
<span>${result.fundingCost}</span>
</div>`;
} else {
html += `
<div class="result-item">
<span>增强资产:</span>
<span>${result.asset}</span>
</div>
<div class="result-item">
<span>资产预期:</span>
<span>${result.expectation}
<span class="range-indicator range-${result.expectationType.toLowerCase()}">
${result.expectationType === 'PESSIMISTIC' ? '悲观' :
result.expectationType === 'NEUTRAL' ? '中性' : '乐观'}
</span>
</span>
</div>
<div class="result-item">
<span>债券比例:</span>
<span>${result.bondWeight}</span>
</div>
<div class="result-item">
<span>资产比例:</span>
<span>${result.assetWeight}</span>
</div>`;
}
html += `
</div>
<div class="result-card">
<h3>📈 收益率分析</h3>
<div class="contribution-breakdown">`;
if (result.strategy === '纯债策略') {
html += `
<div class="contribution-item">
<span>基础收益率:</span>
<span>${result.baseReturn}</span>
</div>
<div class="contribution-item">
<span>资本利得贡献:</span>
<span>${result.capitalGainRange}<span class="bp-unit">bp</span></span>
</div>`;
} else {
html += `
<div class="contribution-item">
<span>债券基础部分:</span>
<span>${result.baseBondContribution}</span>
</div>
<div class="contribution-item">
<span>资本利得贡献:</span>
<span>${result.capitalGainRange}<span class="bp-unit">bp</span></span>
</div>
<div class="contribution-item">
<span>增强资产贡献:</span>
<span>${result.assetContributionRange}</span>
</div>
<div class="contribution-item" style="font-size: 0.9rem; color: #666;">
<span>(资产预期收益率:</span>
<span>${result.assetReturnRange})</span>
</div>`;
}
html += `
<div class="contribution-item" style="margin-top: 10px; padding-top: 10px; border-top: 2px solid #ddd; font-weight: 600;">
<span>理论预期收益率:</span>
<span class="highlight">${result.totalReturn}</span>
</div>
</div>
<div class="result-item" style="margin-top: 15px;">
<span>市场实际参考区间:</span>
<span>${result.marketRef}</span>
</div>
</div>
</div>
<div style="margin-top: 30px; padding: 20px; background: #f0f8ff; border-radius: 8px;">
<h3>💡 计算说明</h3>
<p><strong>资本利得模型:</strong>基于正态分布N(0, 18bp),不同期限对应不同波段次数,计算第50-80百分位交易员收益区间:</p>
<ul style="margin-left: 20px; margin-top: 5px;">
<li>短期(0-3个月):1次波段</li>
<li>中期(3-6个月):1.5次波段</li>
<li>长期(6-12个月):3次波段</li>
</ul>
<p><strong>资本利得区间:</strong>下限为0bp(第50百分位不亏钱),上限为第80百分位值</p>
<p><strong>资产预期:</strong>${result.strategy === '固收+策略' ?
`采用${result.expectation}预期,${result.asset}指数预测区间为${result.assetReturnRange}` :
'纯债策略主要依赖票息收入和资本利得'}</p>
<p><strong>最终收益率:</strong>基础收益率 + 资本利得区间 + 增强资产贡献区间(固收+策略)</p>
</div>`;
content.innerHTML = html;
document.getElementById('result').classList.remove('hidden');
document.getElementById('result').scrollIntoView({ behavior: 'smooth' });
}
</script>
</body>
</html>