Sessions 5-7a: 955 tests, deployment ready
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Correlation engine.
|
||||
*
|
||||
* Pearson correlation between two stat streams. Caller feeds in pairs of
|
||||
* arrays (same player or same team) and we return the coefficient plus
|
||||
* the implied SGP adjustment for value flagging.
|
||||
*/
|
||||
|
||||
function pearson(xs, ys) {
|
||||
if (!Array.isArray(xs) || !Array.isArray(ys) || xs.length !== ys.length || xs.length < 3) return null;
|
||||
let sx = 0, sy = 0;
|
||||
for (let i = 0; i < xs.length; i++) { sx += xs[i]; sy += ys[i]; }
|
||||
const mx = sx / xs.length, my = sy / ys.length;
|
||||
let num = 0, dx = 0, dy = 0;
|
||||
for (let i = 0; i < xs.length; i++) {
|
||||
const a = xs[i] - mx;
|
||||
const b = ys[i] - my;
|
||||
num += a * b; dx += a * a; dy += b * b;
|
||||
}
|
||||
const den = Math.sqrt(dx * dy);
|
||||
if (den === 0) return 0;
|
||||
return num / den;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare measured correlation to the book's implicit SGP adjustment.
|
||||
* `bookAdjustment` is the multiplier the book applies to the joint price
|
||||
* vs the independent-events price. >1 means the book over-prices the
|
||||
* correlation; <1 means under-priced (VALUE).
|
||||
*/
|
||||
function flagValue(measuredR, bookAdjustment) {
|
||||
if (measuredR == null || bookAdjustment == null) return null;
|
||||
if (bookAdjustment < 1 && measuredR > 0.15) return 'VALUE';
|
||||
if (bookAdjustment > 1.2 && measuredR < 0.1) return 'OVERPRICED';
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = { pearson, flagValue };
|
||||
Reference in New Issue
Block a user