Add period selector and crypto-style trend plan preview table.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+55
-16
@@ -20,29 +20,68 @@
|
||||
return o;
|
||||
}
|
||||
|
||||
function showPreview(el, text, ok) {
|
||||
function esc(s) {
|
||||
return String(s == null ? '' : s)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
}
|
||||
|
||||
function showPreview(el, content, ok, isHtml) {
|
||||
if (!el) return;
|
||||
if (!text) {
|
||||
if (!content) {
|
||||
el.hidden = true;
|
||||
el.textContent = '';
|
||||
el.innerHTML = '';
|
||||
return;
|
||||
}
|
||||
el.hidden = false;
|
||||
el.textContent = text;
|
||||
el.style.color = ok === false ? 'var(--loss)' : '';
|
||||
if (isHtml) {
|
||||
el.innerHTML = content;
|
||||
} else {
|
||||
el.innerHTML = '';
|
||||
el.textContent = content;
|
||||
}
|
||||
}
|
||||
|
||||
function formatPlan(plan) {
|
||||
function fmtNum(v) {
|
||||
if (v == null || v === '') return '—';
|
||||
return String(v);
|
||||
}
|
||||
|
||||
function renderTrendPlanHtml(plan) {
|
||||
if (!plan) return '';
|
||||
var lines = [];
|
||||
if (plan.symbol) lines.push('品种:' + plan.symbol);
|
||||
if (plan.target_lots != null) lines.push('目标手数:' + plan.target_lots);
|
||||
if (plan.first_lots != null) lines.push('首仓:' + plan.first_lots + ' 手');
|
||||
if (plan.grid && plan.grid.length) {
|
||||
lines.push('补仓档位:' + plan.grid.map(function (g) { return g.price; }).join(' → '));
|
||||
var summary = plan.summary_line || (
|
||||
(plan.symbol_name || plan.symbol || '') + ' ' +
|
||||
(plan.direction_label || '') + ' ' + (plan.period_label || '')
|
||||
);
|
||||
var detail = plan.detail_line || '';
|
||||
var rows = plan.preview_rows || [];
|
||||
var html = '<div class="trend-summary">' + esc(summary) + '</div>';
|
||||
if (detail) {
|
||||
html += '<div class="trend-detail">' + esc(detail) + '</div>';
|
||||
}
|
||||
if (plan.message) lines.push(plan.message);
|
||||
return lines.length ? lines.join('\n') : JSON.stringify(plan, null, 2);
|
||||
if (rows.length) {
|
||||
html += '<table class="strategy-preview-table"><thead><tr>' +
|
||||
'<th>档位</th><th>触发/参考价</th><th>手数</th><th>加仓后均价</th>' +
|
||||
'<th>止盈盈利(元)</th><th>止损(元)</th><th>盈亏比</th>' +
|
||||
'</tr></thead><tbody>';
|
||||
rows.forEach(function (row) {
|
||||
html += '<tr><td>' + esc(row.level) + '</td>' +
|
||||
'<td>' + fmtNum(row.price) + '</td>' +
|
||||
'<td>' + fmtNum(row.lots) + '</td>' +
|
||||
'<td>' + fmtNum(row.avg_after) + '</td>' +
|
||||
'<td>' + fmtNum(row.profit_at_tp) + '</td>' +
|
||||
'<td>' + fmtNum(row.loss_at_sl) + '</td>' +
|
||||
'<td>' + fmtNum(row.rr_ratio) + '</td></tr>';
|
||||
});
|
||||
html += '</tbody></table>';
|
||||
} else {
|
||||
html += '<div class="trend-detail">目标手数 ' + fmtNum(plan.target_lots) +
|
||||
' · 首仓 ' + fmtNum(plan.first_lots) + ' 手</div>';
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
function formatRoll(preview) {
|
||||
@@ -66,12 +105,12 @@
|
||||
btnPreview.disabled = true;
|
||||
jsonPost('/api/strategy/trend/preview', formData(trendForm)).then(function (d) {
|
||||
if (!d.ok) {
|
||||
showPreview(previewEl, d.error || '预览失败', false);
|
||||
showPreview(previewEl, d.error || '预览失败', false, false);
|
||||
btnExec.hidden = true;
|
||||
return;
|
||||
}
|
||||
trendPayload = formData(trendForm);
|
||||
showPreview(previewEl, formatPlan(d.plan), true);
|
||||
showPreview(previewEl, renderTrendPlanHtml(d.plan), true, true);
|
||||
btnExec.hidden = false;
|
||||
}).finally(function () {
|
||||
btnPreview.disabled = false;
|
||||
@@ -102,11 +141,11 @@
|
||||
btnRollP.disabled = true;
|
||||
jsonPost('/api/strategy/roll/preview', formData(rollForm)).then(function (d) {
|
||||
if (!d.ok) {
|
||||
showPreview(rollPrev, d.error, false);
|
||||
showPreview(rollPrev, d.error, false, false);
|
||||
btnRollE.hidden = true;
|
||||
return;
|
||||
}
|
||||
showPreview(rollPrev, formatRoll(d.preview), true);
|
||||
showPreview(rollPrev, formatRoll(d.preview), true, false);
|
||||
btnRollE.hidden = false;
|
||||
}).finally(function () {
|
||||
btnRollP.disabled = false;
|
||||
|
||||
Reference in New Issue
Block a user