diff --git a/lib/paper/engine.js b/lib/paper/engine.js index 8c16b16..af55370 100644 --- a/lib/paper/engine.js +++ b/lib/paper/engine.js @@ -53,7 +53,6 @@ export class PaperEngine { async init() { try { - // Load saved per-strategy states const states = await db.query('SELECT * FROM paper_strategy_state ORDER BY timestamp DESC'); const rows = states[0] || []; const seen = new Set(); @@ -68,7 +67,6 @@ export class PaperEngine { console.log(`[Paper:${saved.strategyName}] Restored: $${acct.balance.toFixed(2)}, ${acct.wins}W/${acct.losses}L`); } - // Load open positions const positions = await db.query('SELECT * FROM paper_positions WHERE settled = false'); if (positions[0]) { for (const pos of positions[0]) { @@ -140,7 +138,6 @@ export class PaperEngine { } async settle(ticker, rawResult) { - // Normalize result to lowercase const result = String(rawResult || '').toLowerCase(); if (result !== 'yes' && result !== 'no') { @@ -176,9 +173,11 @@ export class PaperEngine { else acct.losses++; try { + // FIX: Use explicit record identifier for SurrealDB updates + const recordId = pos.id.includes(':') ? pos.id : `paper_positions:${pos.id}`; const updated = await db.query( - `UPDATE paper_positions SET settled = true, result = $result, pnl = $pnl, settleTime = $settleTime WHERE id = $id`, - { id: pos.id, result, pnl: pos.pnl, settleTime: pos.settleTime } + `UPDATE ${recordId} SET settled = true, result = $result, pnl = $pnl, settleTime = $settleTime`, + { result, pnl: pos.pnl, settleTime: pos.settleTime } ); const rows = updated[0] || []; if (rows.length === 0) { @@ -219,7 +218,7 @@ export class PaperEngine { } /** - * Check unresolved tickers periodically for delayed results + * Check unresolved tickers periodically for delayed Kalshi results */ async checkOrphans(getMarketFn) { const orphanTickers = this.getOpenTickers(); @@ -238,7 +237,6 @@ export class PaperEngine { const settledPos = await this.settle(ticker, result); if (settledPos) results.settled.push(...settledPos); } else if (['expired', 'cancelled'].includes(status)) { - // Explicitly cancelled or expired with no valid outcome console.log(`[Paper] Ticker ${ticker} marked as ${status} — force-settling as expired`); const expiredPos = await this._forceExpirePositions(ticker); if (expiredPos) results.expired.push(...expiredPos); @@ -266,9 +264,10 @@ export class PaperEngine { acct.losses++; try { + const recordId = pos.id.includes(':') ? pos.id : `paper_positions:${pos.id}`; const updated = await db.query( - `UPDATE paper_positions SET settled = true, result = $result, pnl = $pnl, settleTime = $settleTime WHERE id = $id`, - { id: pos.id, result: 'expired', pnl: pos.pnl, settleTime: pos.settleTime } + `UPDATE ${recordId} SET settled = true, result = $result, pnl = $pnl, settleTime = $settleTime`, + { result: 'expired', pnl: pos.pnl, settleTime: pos.settleTime } ); const rows = updated[0] || []; if (rows.length === 0) { @@ -301,9 +300,10 @@ export class PaperEngine { pos.settleTime = Date.now(); try { - const updated = await db.query( - `UPDATE paper_positions SET settled = true, result = $result, pnl = $pnl, settleTime = $settleTime WHERE id = $id`, - { id: pos.id, result: 'cancelled', pnl: 0, settleTime: pos.settleTime } + const recordId = pos.id.includes(':') ? pos.id : `paper_positions:${pos.id}`; + await db.query( + `UPDATE ${recordId} SET settled = true, result = $result, pnl = $pnl, settleTime = $settleTime`, + { result: 'cancelled', pnl: 0, settleTime: pos.settleTime } ); } catch (e) {} console.log(`[Paper:${name}] Cancelled open position ${pos.id} for ${ticker} (refunded $${pos.cost})`);