diff --git a/lib/strategies/martingale-alpha.js b/lib/strategies/martingale-alpha.js index fb43987..d60eba0 100644 --- a/lib/strategies/martingale-alpha.js +++ b/lib/strategies/martingale-alpha.js @@ -20,53 +20,57 @@ export class MartingaleAlphaStrategy extends BaseStrategy { maxPct: config.maxPct || 60, baseBet: config.baseBet || 1, maxRounds: config.maxRounds || 3, - cooldownMs: config.cooldownMs || 60000, + slippage: config.slippage || 3, + cooldownMs: config.cooldownMs || 20000, ...config }); - this.round = 0; // 0 = waiting, 1-3 = active round + this.round = 0; this.currentBetSize = this.config.baseBet; - this.lastTradeTime = 0; - this.lastTradeTicker = null; this.cycleWins = 0; this.cycleLosses = 0; this.totalCycles = 0; + + this._lastTrade = { + paper: { time: 0, ticker: null }, + live: { time: 0, ticker: null } + }; } - evaluate(state) { + evaluate(state, caller = 'paper') { if (!state || !this.enabled) return null; + const track = this._lastTrade[caller] || this._lastTrade.paper; const now = Date.now(); - if (now - this.lastTradeTime < this.config.cooldownMs) return null; - if (state.ticker === this.lastTradeTicker) return null; + if (now - track.time < this.config.cooldownMs) return null; + if (state.ticker === track.ticker) return null; const { yesPct, noPct } = state; const { minPct, maxPct } = this.config; - // Only trade when both sides are in the 40-60% range (coin-flip territory) if (yesPct < minPct || yesPct > maxPct) return null; if (noPct < minPct || noPct > maxPct) return null; - // Secure random coin flip: 0 = yes, 1 = no const flip = crypto.randomInt(0, 2); const side = flip === 0 ? 'yes' : 'no'; const price = side === 'yes' ? yesPct : noPct; + const maxPrice = Math.min(price + this.config.slippage, 95); - // Determine bet size based on current round - const roundIndex = this.round; // 0, 1, or 2 + const roundIndex = this.round; const betSize = this.config.baseBet * Math.pow(2, roundIndex); const signal = { strategy: this.name, side, price, + maxPrice, size: betSize, reason: `R${roundIndex + 1}/${this.config.maxRounds} coin-flip ${side.toUpperCase()} @ ${price}ยข ($${betSize}) | Market: ${yesPct}/${noPct}`, ticker: state.ticker }; - this.lastTradeTime = now; - this.lastTradeTicker = state.ticker; + track.time = now; + track.ticker = state.ticker; this.currentBetSize = betSize; return signal; @@ -100,7 +104,9 @@ export class MartingaleAlphaStrategy extends BaseStrategy { _resetCycle() { this.round = 0; this.currentBetSize = this.config.baseBet; - this.lastTradeTicker = null; // Allow trading same ticker in new cycle + // Reset both callers' ticker locks so new cycle can trade same market + this._lastTrade.paper.ticker = null; + this._lastTrade.live.ticker = null; } toJSON() {