fix: auto-redeem after ghost recovery when holding expensive side

When ghost fill recovery decides to hold the expensive side (not sell),
set pos.holdingSide so the existing waitAndRedeem flow picks it up after
executeMakerRebateStrategy — same path as CANCEL_CHEAP_ON_EXP_FILL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
direkturcrypto
2026-04-03 13:22:08 +07:00
parent 3d2a6e7c4a
commit 49de5c60e9
+6 -3
View File
@@ -225,21 +225,24 @@ async function recoverFromGhostFill(pos, yesShares, noShares, tag) {
if (yesRemainder >= 1) {
if (expSide === 'yes') {
logger.warn(`MakerMM${tag}: ghost recovery — holding YES remainder ${yesRemainder.toFixed(4)} (expensive $${pos.yes.buyPrice}, not market-selling)`);
logger.warn(`MakerMM${tag}: ghost recovery — holding YES remainder ${yesRemainder.toFixed(4)} (expensive $${pos.yes.buyPrice}, scheduling redeem after resolution)`);
pos.holdingSide = 'yes';
} else {
await marketSellToken(pos.yes.tokenId, yesRemainder, pos.tickSize, pos.negRisk, tag);
}
}
if (noRemainder >= 1) {
if (expSide === 'no') {
logger.warn(`MakerMM${tag}: ghost recovery — holding NO remainder ${noRemainder.toFixed(4)} (expensive $${pos.no.buyPrice}, not market-selling)`);
logger.warn(`MakerMM${tag}: ghost recovery — holding NO remainder ${noRemainder.toFixed(4)} (expensive $${pos.no.buyPrice}, scheduling redeem after resolution)`);
pos.holdingSide = 'no';
} else {
await marketSellToken(pos.no.tokenId, noRemainder, pos.tickSize, pos.negRisk, tag);
}
}
pos.totalProfit = mergeRecovered - (pos.yes.cost + pos.no.cost);
pos.status = 'done';
// Don't mark done if holding expensive side — waitAndRedeem will close it out
if (!pos.holdingSide) pos.status = 'done';
}
async function placeLimitBuy(tokenId, shares, price, tickSize, negRisk) {