institutional-trader/backend/src/factorlab/__tests__/lookahead.test.js

61 lines
2.2 KiB
JavaScript

import { loadFundamentals, getFundamentalsAsOf } from '../fundamentals.js';
function runTest() {
console.log("Running fundamentals lookahead test...");
const testData = [
{
symbol: 'AAPL',
datekey: '2020-02-15', // Actually filed on Feb 15
fiscalEnd: '2019-12-31',
metrics: { roe: 0.10 }
},
{
symbol: 'AAPL',
datekey: '2020-05-15', // Q1 filed on May 15
fiscalEnd: '2020-03-31',
metrics: { roe: 0.12 }
},
{
symbol: 'MSFT',
datekey: null, // Missing datekey, should fallback to fiscalEnd + 120 days
fiscalEnd: '2019-12-31', // + 120 days = 2020-04-29
metrics: { roe: 0.15 }
}
];
loadFundamentals(testData);
// Test 1: Jan 31, 2020.
// The Dec 31 fiscal data isn't filed until Feb 15. We MUST return null.
const a1 = getFundamentalsAsOf('AAPL', '2020-01-31');
if (a1 !== null) throw new Error("Lookahead leak! Returned Q4 data before filing date.");
// Test 2: Feb 16, 2020.
// The Dec 31 fiscal data was filed Feb 15. We should get it.
const a2 = getFundamentalsAsOf('AAPL', '2020-02-16');
if (!a2 || a2.roe !== 0.10) throw new Error("Failed to return available data.");
// Test 3: May 14, 2020.
// Q1 isn't filed until May 15. We should still get Q4 (roe: 0.10).
const a3 = getFundamentalsAsOf('AAPL', '2020-05-14');
if (!a3 || a3.roe !== 0.10) throw new Error("Lookahead leak! Returned Q1 data early.");
// Test 4: May 16, 2020.
// Now we should get Q1 (roe: 0.12).
const a4 = getFundamentalsAsOf('AAPL', '2020-05-16');
if (!a4 || a4.roe !== 0.12) throw new Error("Failed to roll forward to new data.");
// Test 5: MSFT fallback logic. Target = April 28 (119 days after fiscalEnd). Should be null.
const m1 = getFundamentalsAsOf('MSFT', '2020-04-28');
if (m1 !== null) throw new Error("Lookahead leak! MSFT fallback data returned early.");
// Test 6: MSFT fallback logic. Target = April 30 (121 days after fiscalEnd). Should be available.
const m2 = getFundamentalsAsOf('MSFT', '2020-04-30');
if (!m2 || m2.roe !== 0.15) throw new Error("Failed to return fallback data after 120 days.");
console.log("PASS: Fundamentals guardrail strictly prevents lookahead bias.");
}
runTest();