Add personal license agreement and rename product section to tradable symbols.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+140
-136
@@ -1,136 +1,140 @@
|
||||
(function () {
|
||||
var trendPayload = null;
|
||||
|
||||
function jsonPost(url, body) {
|
||||
return fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body || {})
|
||||
}).then(function (r) { return r.json(); });
|
||||
}
|
||||
|
||||
function formData(form) {
|
||||
var fd = new FormData(form);
|
||||
var o = {};
|
||||
fd.forEach(function (v, k) { o[k] = v; });
|
||||
return o;
|
||||
}
|
||||
|
||||
function showPreview(el, text, ok) {
|
||||
if (!el) return;
|
||||
if (!text) {
|
||||
el.hidden = true;
|
||||
el.textContent = '';
|
||||
return;
|
||||
}
|
||||
el.hidden = false;
|
||||
el.textContent = text;
|
||||
el.style.color = ok === false ? 'var(--loss)' : '';
|
||||
}
|
||||
|
||||
function formatPlan(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(' → '));
|
||||
}
|
||||
if (plan.message) lines.push(plan.message);
|
||||
return lines.length ? lines.join('\n') : JSON.stringify(plan, null, 2);
|
||||
}
|
||||
|
||||
function formatRoll(preview) {
|
||||
if (!preview) return '';
|
||||
var lines = [];
|
||||
if (preview.add_lots != null) lines.push('加仓手数:' + preview.add_lots);
|
||||
if (preview.new_stop_loss != null) lines.push('新止损:' + preview.new_stop_loss);
|
||||
if (preview.total_lots != null) lines.push('合计手数:' + preview.total_lots);
|
||||
if (preview.worst_loss != null) lines.push('最坏亏损:' + preview.worst_loss + ' 元');
|
||||
if (preview.message) lines.push(preview.message);
|
||||
return lines.length ? lines.join('\n') : JSON.stringify(preview, null, 2);
|
||||
}
|
||||
|
||||
var trendForm = document.getElementById('trend-form');
|
||||
var btnPreview = document.getElementById('btn-trend-preview');
|
||||
var btnExec = document.getElementById('btn-trend-exec');
|
||||
var previewEl = document.getElementById('trend-preview');
|
||||
|
||||
if (btnPreview && trendForm) {
|
||||
btnPreview.addEventListener('click', function () {
|
||||
btnPreview.disabled = true;
|
||||
jsonPost('/api/strategy/trend/preview', formData(trendForm)).then(function (d) {
|
||||
if (!d.ok) {
|
||||
showPreview(previewEl, d.error || '预览失败', false);
|
||||
btnExec.hidden = true;
|
||||
return;
|
||||
}
|
||||
trendPayload = formData(trendForm);
|
||||
showPreview(previewEl, formatPlan(d.plan), true);
|
||||
btnExec.hidden = false;
|
||||
}).finally(function () {
|
||||
btnPreview.disabled = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
if (btnExec) {
|
||||
btnExec.addEventListener('click', function () {
|
||||
if (!trendPayload) return;
|
||||
btnExec.disabled = true;
|
||||
btnExec.textContent = '执行中…';
|
||||
jsonPost('/api/strategy/trend/execute', trendPayload).then(function (d) {
|
||||
if (!d.ok) { alert(d.error); return; }
|
||||
location.reload();
|
||||
}).finally(function () {
|
||||
btnExec.disabled = false;
|
||||
btnExec.textContent = '确认执行首仓';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var rollForm = document.getElementById('roll-form');
|
||||
var btnRollP = document.getElementById('btn-roll-preview');
|
||||
var btnRollE = document.getElementById('btn-roll-exec');
|
||||
var rollPrev = document.getElementById('roll-preview');
|
||||
if (btnRollP && rollForm) {
|
||||
btnRollP.addEventListener('click', function () {
|
||||
btnRollP.disabled = true;
|
||||
jsonPost('/api/strategy/roll/preview', formData(rollForm)).then(function (d) {
|
||||
if (!d.ok) {
|
||||
showPreview(rollPrev, d.error, false);
|
||||
btnRollE.hidden = true;
|
||||
return;
|
||||
}
|
||||
showPreview(rollPrev, formatRoll(d.preview), true);
|
||||
btnRollE.hidden = false;
|
||||
}).finally(function () {
|
||||
btnRollP.disabled = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
if (btnRollE && rollForm) {
|
||||
btnRollE.addEventListener('click', function () {
|
||||
btnRollE.disabled = true;
|
||||
btnRollE.textContent = '执行中…';
|
||||
jsonPost('/api/strategy/roll/execute', formData(rollForm)).then(function (d) {
|
||||
if (!d.ok) { alert(d.error); return; }
|
||||
location.reload();
|
||||
}).finally(function () {
|
||||
btnRollE.disabled = false;
|
||||
btnRollE.textContent = '执行滚仓';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var btnStop = document.getElementById('btn-trend-stop');
|
||||
if (btnStop) {
|
||||
btnStop.addEventListener('click', function () {
|
||||
var pid = document.querySelector('#trend-stop-form input[name=plan_id]');
|
||||
jsonPost('/api/strategy/trend/stop', { plan_id: pid ? pid.value : 0 }).then(function (d) {
|
||||
if (!d.ok) { alert(d.error); return; }
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
/* Copyright (c) 2025-2026 马建军. All rights reserved.
|
||||
* 专有软件 — 未经授权禁止复制、传播、转售。
|
||||
* 详见 LICENSE.zh-CN.txt
|
||||
*/
|
||||
(function () {
|
||||
var trendPayload = null;
|
||||
|
||||
function jsonPost(url, body) {
|
||||
return fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body || {})
|
||||
}).then(function (r) { return r.json(); });
|
||||
}
|
||||
|
||||
function formData(form) {
|
||||
var fd = new FormData(form);
|
||||
var o = {};
|
||||
fd.forEach(function (v, k) { o[k] = v; });
|
||||
return o;
|
||||
}
|
||||
|
||||
function showPreview(el, text, ok) {
|
||||
if (!el) return;
|
||||
if (!text) {
|
||||
el.hidden = true;
|
||||
el.textContent = '';
|
||||
return;
|
||||
}
|
||||
el.hidden = false;
|
||||
el.textContent = text;
|
||||
el.style.color = ok === false ? 'var(--loss)' : '';
|
||||
}
|
||||
|
||||
function formatPlan(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(' → '));
|
||||
}
|
||||
if (plan.message) lines.push(plan.message);
|
||||
return lines.length ? lines.join('\n') : JSON.stringify(plan, null, 2);
|
||||
}
|
||||
|
||||
function formatRoll(preview) {
|
||||
if (!preview) return '';
|
||||
var lines = [];
|
||||
if (preview.add_lots != null) lines.push('加仓手数:' + preview.add_lots);
|
||||
if (preview.new_stop_loss != null) lines.push('新止损:' + preview.new_stop_loss);
|
||||
if (preview.total_lots != null) lines.push('合计手数:' + preview.total_lots);
|
||||
if (preview.worst_loss != null) lines.push('最坏亏损:' + preview.worst_loss + ' 元');
|
||||
if (preview.message) lines.push(preview.message);
|
||||
return lines.length ? lines.join('\n') : JSON.stringify(preview, null, 2);
|
||||
}
|
||||
|
||||
var trendForm = document.getElementById('trend-form');
|
||||
var btnPreview = document.getElementById('btn-trend-preview');
|
||||
var btnExec = document.getElementById('btn-trend-exec');
|
||||
var previewEl = document.getElementById('trend-preview');
|
||||
|
||||
if (btnPreview && trendForm) {
|
||||
btnPreview.addEventListener('click', function () {
|
||||
btnPreview.disabled = true;
|
||||
jsonPost('/api/strategy/trend/preview', formData(trendForm)).then(function (d) {
|
||||
if (!d.ok) {
|
||||
showPreview(previewEl, d.error || '预览失败', false);
|
||||
btnExec.hidden = true;
|
||||
return;
|
||||
}
|
||||
trendPayload = formData(trendForm);
|
||||
showPreview(previewEl, formatPlan(d.plan), true);
|
||||
btnExec.hidden = false;
|
||||
}).finally(function () {
|
||||
btnPreview.disabled = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
if (btnExec) {
|
||||
btnExec.addEventListener('click', function () {
|
||||
if (!trendPayload) return;
|
||||
btnExec.disabled = true;
|
||||
btnExec.textContent = '执行中…';
|
||||
jsonPost('/api/strategy/trend/execute', trendPayload).then(function (d) {
|
||||
if (!d.ok) { alert(d.error); return; }
|
||||
location.reload();
|
||||
}).finally(function () {
|
||||
btnExec.disabled = false;
|
||||
btnExec.textContent = '确认执行首仓';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var rollForm = document.getElementById('roll-form');
|
||||
var btnRollP = document.getElementById('btn-roll-preview');
|
||||
var btnRollE = document.getElementById('btn-roll-exec');
|
||||
var rollPrev = document.getElementById('roll-preview');
|
||||
if (btnRollP && rollForm) {
|
||||
btnRollP.addEventListener('click', function () {
|
||||
btnRollP.disabled = true;
|
||||
jsonPost('/api/strategy/roll/preview', formData(rollForm)).then(function (d) {
|
||||
if (!d.ok) {
|
||||
showPreview(rollPrev, d.error, false);
|
||||
btnRollE.hidden = true;
|
||||
return;
|
||||
}
|
||||
showPreview(rollPrev, formatRoll(d.preview), true);
|
||||
btnRollE.hidden = false;
|
||||
}).finally(function () {
|
||||
btnRollP.disabled = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
if (btnRollE && rollForm) {
|
||||
btnRollE.addEventListener('click', function () {
|
||||
btnRollE.disabled = true;
|
||||
btnRollE.textContent = '执行中…';
|
||||
jsonPost('/api/strategy/roll/execute', formData(rollForm)).then(function (d) {
|
||||
if (!d.ok) { alert(d.error); return; }
|
||||
location.reload();
|
||||
}).finally(function () {
|
||||
btnRollE.disabled = false;
|
||||
btnRollE.textContent = '执行滚仓';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var btnStop = document.getElementById('btn-trend-stop');
|
||||
if (btnStop) {
|
||||
btnStop.addEventListener('click', function () {
|
||||
var pid = document.querySelector('#trend-stop-form input[name=plan_id]');
|
||||
jsonPost('/api/strategy/trend/stop', { plan_id: pid ? pid.value : 0 }).then(function (d) {
|
||||
if (!d.ok) { alert(d.error); return; }
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user