fix: calibrate from replay outcomes
This commit is contained in:
@@ -12,6 +12,7 @@ const { calculateOutcome } = require('../src/autonomy/outcomes');
|
||||
const { createOrderIntent } = require('../src/autonomy/orderIntents');
|
||||
const { enqueueCoordinatorEvent, reconcileArchiveBatch, reconcileLiveBatch } = require('../workers/autonomyWorker');
|
||||
const { scheduleNext } = require('../workers/replayWorker');
|
||||
const { refreshHistoricalCalibration, createDecisions } = require('../workers/calibrationWorker');
|
||||
|
||||
test('autonomy schema and leased jobs are restart-safe', () => {
|
||||
const db = new Database(':memory:');
|
||||
@@ -120,6 +121,53 @@ test('calibration and policy abstain on insufficient evidence', () => {
|
||||
assert.equal(decide({ direction: 'negative', probability: 0.8, expectedExcessReturn: -0.02, lowerReturn: -0.04, sampleSize: 40 }).action, 'SELL');
|
||||
});
|
||||
|
||||
test('historical replay outcomes create replay calibration snapshots', () => {
|
||||
const db = new Database(':memory:');
|
||||
initAutonomySchema(db);
|
||||
const proposal = db.prepare("INSERT INTO autonomy_proposals(payload, information_cutoff, status) VALUES ('{}', '2020-01-01T00:00:00Z', 'accepted')").run();
|
||||
const prediction = db.prepare(`
|
||||
INSERT INTO autonomy_predictions
|
||||
(proposal_id, instrument, direction, event_type, horizon_days, information_cutoff, evidence_article_ids,
|
||||
learning_eligible, strategy_version, origin, replay_run_id, status)
|
||||
VALUES (?, 'NVDA', 'positive', 'earnings', 10, '2020-01-01T00:00:00Z', '[1]', 0, 'test', 'replay', 7, 'resolved')
|
||||
`).run(proposal.lastInsertRowid);
|
||||
db.prepare(`
|
||||
INSERT INTO autonomy_outcomes(prediction_id, excess_return, direction_correct)
|
||||
VALUES (?, 0.04, 1)
|
||||
`).run(prediction.lastInsertRowid);
|
||||
|
||||
assert.equal(refreshHistoricalCalibration(db, 'test-cal'), 1);
|
||||
const snapshot = db.prepare("SELECT source, replay_run_id, sample_size, directional_probability FROM autonomy_calibration_snapshots").get();
|
||||
assert.equal(snapshot.source, 'replay');
|
||||
assert.equal(snapshot.replay_run_id, 7);
|
||||
assert.equal(snapshot.sample_size, 1);
|
||||
assert(snapshot.directional_probability > 0.5);
|
||||
});
|
||||
|
||||
test('live decisions map calibration snapshot fields into policy inputs', () => {
|
||||
const db = new Database(':memory:');
|
||||
initAutonomySchema(db);
|
||||
const proposal = db.prepare("INSERT INTO autonomy_proposals(payload, information_cutoff, status) VALUES ('{}', datetime('now'), 'accepted')").run();
|
||||
const prediction = db.prepare(`
|
||||
INSERT INTO autonomy_predictions
|
||||
(proposal_id, instrument, direction, event_type, horizon_days, information_cutoff, evidence_article_ids,
|
||||
learning_eligible, strategy_version, origin, status)
|
||||
VALUES (?, 'NVDA', 'positive', 'earnings', 10, datetime('now'), '[1]', 1, 'test', 'live', 'open')
|
||||
`).run(proposal.lastInsertRowid);
|
||||
db.prepare(`
|
||||
INSERT INTO autonomy_calibration_snapshots
|
||||
(cohort_key, sample_size, effective_sample_size, directional_probability, expected_excess_return,
|
||||
lower_return, upper_return, parent_cohort_key, version, source)
|
||||
VALUES ('unknown|earnings|10|positive', 40, 42, 0.7, 0.02, -0.01, 0.06, NULL, 'test-cal', 'replay')
|
||||
`).run();
|
||||
|
||||
assert.equal(createDecisions(db), 1);
|
||||
const decision = db.prepare('SELECT * FROM autonomy_decisions WHERE prediction_id=?').get(prediction.lastInsertRowid);
|
||||
assert.equal(decision.action, 'BUY');
|
||||
assert.equal(decision.calibrated_probability, 0.7);
|
||||
assert.equal(decision.expected_excess_return, 0.02);
|
||||
});
|
||||
|
||||
test('paper execution is allowlisted, bounded and idempotent', () => {
|
||||
const intent = validatePaperIntent({ decisionId: 12, instrument: 'NVDA', action: 'BUY', notional: 100 }, { tradable: true, maxNotional: 500 });
|
||||
const broker = createSimulator();
|
||||
|
||||
Reference in New Issue
Block a user