feat: add false breakout key monitor for BTC/ETH on three exchanges
Place limit orders outside key levels with fixed SL and 1.5 RR, 24h expiry, separate stats, and full-margin mode guard. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -338,14 +338,16 @@
|
||||
<option value="收敛突破">收敛突破</option>
|
||||
<option value="斐波回调0.618">斐波回调0.618</option>
|
||||
<option value="斐波回调0.786">斐波回调0.786</option>
|
||||
<option value="假突破">假突破(BTC/ETH)</option>
|
||||
<option value="关键阻力位">关键阻力位</option>
|
||||
<option value="关键支撑位">关键支撑位</option>
|
||||
</select>
|
||||
<select name="direction" id="key-direction" required>
|
||||
<option value="">方向</option><option value="long">做多</option><option value="short">做空</option>
|
||||
</select>
|
||||
<input name="upper" step="0.0001" placeholder="上沿/阻力" required>
|
||||
<input name="lower" step="0.0001" placeholder="下沿/支撑" required>
|
||||
<input name="key_price" id="key-fb-price" step="0.0001" placeholder="做空填高点/做多填低点" style="display:none">
|
||||
<input name="upper" id="key-upper" step="0.0001" placeholder="上沿/阻力" required>
|
||||
<input name="lower" id="key-lower" step="0.0001" placeholder="下沿/支撑" required>
|
||||
<select name="sl_tp_mode" id="key-sl-tp-mode" title="止盈止损方案">
|
||||
<option value="standard">标准突破</option>
|
||||
<option value="box_1p5">箱体1R·止盈1.5H</option>
|
||||
@@ -377,6 +379,7 @@
|
||||
<span class="pos-meta-item">上沿: {{ k.upper }}</span>
|
||||
<span class="pos-meta-item">下沿: {{ k.lower }}</span>
|
||||
{% if k.fib_entry_price %}<span class="pos-meta-item">挂E: {{ k.fib_entry_price }}</span>{% endif %}
|
||||
{% if k.monitor_type == '假突破' and k.fib_stop_loss %}<span class="pos-meta-item">SL: {{ k.fib_stop_loss }} / TP: {{ k.fib_take_profit }}</span>{% endif %}
|
||||
<span class="pos-meta-item">已提醒: {{ k.notification_count or 0 }}/{{ k.max_notify or 3 }}</span>
|
||||
{% if k.monitor_type in ['箱体突破','收敛突破'] %}
|
||||
<span class="pos-meta-item">方案: {{ '标准突破' if (k.sl_tp_mode or 'standard') == 'standard' else ('箱体1R·止盈1.5H' if k.sl_tp_mode == 'box_1p5' else '趋势单') }}</span>
|
||||
@@ -1349,7 +1352,8 @@ const KEY_ENTRY_REASON_BY_SIGNAL = {
|
||||
"箱体突破": "关键位箱体突破",
|
||||
"收敛突破": "关键位收敛突破",
|
||||
"斐波回调0.618": "关键位斐波0.618",
|
||||
"斐波回调0.786": "关键位斐波0.786"
|
||||
"斐波回调0.786": "关键位斐波0.786",
|
||||
"假突破": "关键位假突破"
|
||||
};
|
||||
|
||||
function splitLegacyEarlyExitReason(raw){
|
||||
@@ -1638,10 +1642,15 @@ function syncKeyMonitorFormFields(){
|
||||
const t = (typeEl.value || "").trim();
|
||||
const autoTypes = new Set(["箱体突破","收敛突破"]);
|
||||
const fibTypes = new Set(["斐波回调0.618","斐波回调0.786"]);
|
||||
const fbTypes = new Set(["假突破"]);
|
||||
const rsTypes = new Set(["关键阻力位","关键支撑位"]);
|
||||
const showAuto = autoTypes.has(t);
|
||||
const showBe = showAuto || fibTypes.has(t);
|
||||
const showFb = fbTypes.has(t);
|
||||
const showBe = showAuto || fibTypes.has(t) || showFb;
|
||||
const showDir = !rsTypes.has(t);
|
||||
const upperEl = document.getElementById("key-upper");
|
||||
const lowerEl = document.getElementById("key-lower");
|
||||
const fbPriceEl = document.getElementById("key-fb-price");
|
||||
if(dirEl){
|
||||
dirEl.style.display = showDir ? "" : "none";
|
||||
dirEl.required = showDir;
|
||||
@@ -1654,11 +1663,29 @@ function syncKeyMonitorFormFields(){
|
||||
manualTp.required = !!trend;
|
||||
}
|
||||
if(beWrap) beWrap.style.display = showBe ? "inline-flex" : "none";
|
||||
if(upperEl){
|
||||
upperEl.style.display = showFb ? "none" : "";
|
||||
upperEl.required = !showFb;
|
||||
if(showFb) upperEl.value = "";
|
||||
}
|
||||
if(lowerEl){
|
||||
lowerEl.style.display = showFb ? "none" : "";
|
||||
lowerEl.required = !showFb;
|
||||
if(showFb) lowerEl.value = "";
|
||||
}
|
||||
if(fbPriceEl){
|
||||
fbPriceEl.style.display = showFb ? "" : "none";
|
||||
fbPriceEl.required = showFb;
|
||||
if(!showFb) fbPriceEl.value = "";
|
||||
fbPriceEl.placeholder = (dirEl && dirEl.value === "short") ? "高点(阻力)" : ((dirEl && dirEl.value === "long") ? "低点(支撑)" : "做空填高点/做多填低点");
|
||||
}
|
||||
}
|
||||
const keyTypeSel = document.querySelector('#key-form [name="type"]');
|
||||
const keyModeSel = document.getElementById("key-sl-tp-mode");
|
||||
const keyDirSel = document.getElementById("key-direction");
|
||||
if(keyTypeSel) keyTypeSel.addEventListener("change", syncKeyMonitorFormFields);
|
||||
if(keyModeSel) keyModeSel.addEventListener("change", syncKeyMonitorFormFields);
|
||||
if(keyDirSel) keyDirSel.addEventListener("change", syncKeyMonitorFormFields);
|
||||
syncKeyMonitorFormFields();
|
||||
|
||||
const keyForm = document.getElementById("key-form");
|
||||
@@ -1672,6 +1699,12 @@ if(keyForm){
|
||||
alert("请先输入交易对");
|
||||
return;
|
||||
}
|
||||
const typeVal = (keyForm.querySelector('[name="type"]') || {}).value || "";
|
||||
if(typeVal === "假突破"){
|
||||
if(window.FormSubmitGuard) FormSubmitGuard.nativeSubmitOnce(keyForm, "提交中…");
|
||||
else keyForm.submit();
|
||||
return;
|
||||
}
|
||||
if(window.FormSubmitGuard) FormSubmitGuard.lock(keyForm, "校验排名中…");
|
||||
fetch(`/api/symbol_liquidity_rank?symbol=${encodeURIComponent(symbol)}`)
|
||||
.then(r=>r.json().then(d=>({status:r.status, data:d})))
|
||||
|
||||
Reference in New Issue
Block a user