added more functions

This commit is contained in:
Bojan Kucera 2025-06-04 19:27:11 -04:00
parent a53d8d13ca
commit a1c82ae0b8
7 changed files with 648 additions and 177 deletions

View file

@ -452,3 +452,73 @@ export function validatePositionSize(
violations
};
}
/**
* Optimal F position sizing (Ralph Vince's method)
*/
export function optimalFPositionSize(
accountSize: number,
historicalReturns: number[],
maxIterations: number = 100
): number {
if (historicalReturns.length === 0 || accountSize <= 0) return 0;
// Convert returns to P&L per unit
const pnlValues = historicalReturns.map(ret => ret * 1000); // Assuming $1000 per unit
let bestF = 0;
let bestTWR = 0; // Terminal Wealth Relative
// Test different f values (0.01 to 1.00)
for (let f = 0.01; f <= 1.0; f += 0.01) {
let twr = 1.0;
let valid = true;
for (const pnl of pnlValues) {
const hpr = 1 + (f * pnl / 1000); // Holding Period Return
if (hpr <= 0) {
valid = false;
break;
}
twr *= hpr;
}
if (valid && twr > bestTWR) {
bestTWR = twr;
bestF = f;
}
}
// Apply safety factor
const safeF = bestF * 0.75; // 75% of optimal f for safety
return accountSize * safeF;
}
/**
* Secure F position sizing (safer version of Optimal F)
*/
export function secureFPositionSize(
accountSize: number,
historicalReturns: number[],
confidenceLevel: number = 0.95
): number {
if (historicalReturns.length === 0 || accountSize <= 0) return 0;
// Sort returns to find worst-case scenarios
const sortedReturns = [...historicalReturns].sort((a, b) => a - b);
const worstCaseIndex = Math.floor((1 - confidenceLevel) * sortedReturns.length);
const worstCaseReturn = sortedReturns[worstCaseIndex];
// Calculate maximum position size that won't bankrupt at confidence level
const maxLoss = Math.abs(worstCaseReturn);
const maxRiskPercentage = 0.02; // Never risk more than 2% on worst case
if (maxLoss === 0) return accountSize * 0.1; // Default to 10% if no historical losses
const secureF = Math.min(maxRiskPercentage / maxLoss, 0.25); // Cap at 25%
return accountSize * secureF;
}