fix(oneshot): add global position limit — no new entry while any position is open

Previously the per-market state machine check (sm.is(IDLE)) only blocked
re-entry on the same slug. A fresh market slot (different slug) would get
its own IDLE state machine and could trigger another entry while the previous
market's position was still being held.

Added posEngine.hasAnyPosition() global guard in onSignal so the engine holds
exactly one position at a time across all tracked markets.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
direkturcrypto
2026-02-24 14:07:13 +07:00
parent bf09d30376
commit 2692694309
2 changed files with 12 additions and 0 deletions
+7
View File
@@ -175,6 +175,13 @@ async function onSignal(evt) {
// Only enter from IDLE — one position per market slot
if (!sm.is(State.IDLE)) return;
// Global position limit: never open a new position while any other market
// is still being held. The engine is designed to focus on one bet at a time.
if (posEngine.hasAnyPosition()) {
dbg('SIGNAL', `${marketSlug} | blocked — position already open in another market`);
return;
}
// ── Risk gate ─────────────────────────────────────────────────────────
const riskCheck = riskEngine.canTrade();
+5
View File
@@ -68,6 +68,11 @@ export class PositionEngine {
return this._positions.has(marketSlug);
}
/** True if ANY position is open across all tracked markets */
hasAnyPosition() {
return this._positions.size > 0;
}
/**
* Close the position actively (adverse-move emergency exit) and return exit data.
*