added more functions
This commit is contained in:
parent
a1c82ae0b8
commit
cca9ac03dd
8 changed files with 1563 additions and 2 deletions
|
|
@ -517,3 +517,116 @@ export function calculateYangZhangVolatility(
|
|||
|
||||
return Math.sqrt(yangZhangVariance * annualizationFactor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parkinson volatility estimator
|
||||
*/
|
||||
export function parkinsonVolatility(
|
||||
ohlcv: OHLCVData[],
|
||||
annualizationFactor: number = 252
|
||||
): number {
|
||||
if (ohlcv.length < 2) return 0;
|
||||
const sum = ohlcv
|
||||
.slice(1)
|
||||
.reduce((acc, curr) => {
|
||||
const range = Math.log(curr.high / curr.low);
|
||||
return acc + range * range;
|
||||
}, 0);
|
||||
return Math.sqrt((sum / (ohlcv.length - 1)) * annualizationFactor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Implied Volatility using Black-Scholes model (simplified)
|
||||
*/
|
||||
export function calculateImpliedVolatility(
|
||||
optionPrice: number,
|
||||
spotPrice: number,
|
||||
strikePrice: number,
|
||||
timeToExpiry: number,
|
||||
riskFreeRate: number,
|
||||
optionType: 'call' | 'put',
|
||||
maxIterations: number = 100,
|
||||
tolerance: number = 1e-6
|
||||
): number {
|
||||
// Bisection method for implied volatility calculation
|
||||
let low = 0.01;
|
||||
let high = 5.0;
|
||||
let impliedVol = 0.0;
|
||||
|
||||
for (let i = 0; i < maxIterations; i++) {
|
||||
impliedVol = (low + high) / 2;
|
||||
const modelPrice = blackScholes(spotPrice, strikePrice, timeToExpiry, impliedVol, riskFreeRate, optionType);
|
||||
const diff = optionPrice - modelPrice;
|
||||
|
||||
if (Math.abs(diff) < tolerance) {
|
||||
return impliedVol;
|
||||
}
|
||||
|
||||
if (diff > 0) {
|
||||
low = impliedVol;
|
||||
} else {
|
||||
high = impliedVol;
|
||||
}
|
||||
}
|
||||
|
||||
return impliedVol; // Return best estimate if no convergence
|
||||
}
|
||||
|
||||
/**
|
||||
* Black-Scholes option pricing model
|
||||
*/
|
||||
function blackScholes(
|
||||
spotPrice: number,
|
||||
strikePrice: number,
|
||||
timeToExpiry: number,
|
||||
volatility: number,
|
||||
riskFreeRate: number,
|
||||
optionType: 'call' | 'put'
|
||||
): number {
|
||||
const d1 = (Math.log(spotPrice / strikePrice) + (riskFreeRate + 0.5 * volatility * volatility) * timeToExpiry) / (volatility * Math.sqrt(timeToExpiry));
|
||||
const d2 = d1 - volatility * Math.sqrt(timeToExpiry);
|
||||
|
||||
if (optionType === 'call') {
|
||||
return spotPrice * normalCDF(d1) - strikePrice * Math.exp(-riskFreeRate * timeToExpiry) * normalCDF(d2);
|
||||
} else {
|
||||
return strikePrice * Math.exp(-riskFreeRate * timeToExpiry) * normalCDF(-d2) - spotPrice * normalCDF(-d1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal cumulative distribution function
|
||||
*/
|
||||
function normalCDF(x: number): number {
|
||||
const a1 = 0.254829592;
|
||||
const a2 = -0.284496736;
|
||||
const a3 = 1.421060743;
|
||||
const a4 = -1.453152027;
|
||||
const a5 = 1.061405429;
|
||||
const p = 0.3275911;
|
||||
|
||||
const sign = x < 0 ? -1 : 1;
|
||||
const absX = Math.abs(x);
|
||||
const t = 1 / (1 + p * absX);
|
||||
const y = 1 - (a1 * t + a2 * t * t + a3 * t * t * t + a4 * t * t * t * t + a5 * t * t * t * t * t) * Math.exp(-absX * absX / 2);
|
||||
|
||||
return 0.5 * (1 + sign * y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forecast volatility using EWMA
|
||||
*/
|
||||
export function forecastVolatilityEWMA(
|
||||
volatilities: number[],
|
||||
lambda: number = 0.94,
|
||||
forecastHorizon: number = 1
|
||||
): number {
|
||||
if (volatilities.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let forecast = volatilities[volatilities.length - 1];
|
||||
for (let i = 0; i < forecastHorizon; i++) {
|
||||
forecast = lambda * forecast + (1 - lambda) * forecast; // Using the last value as the long-term average
|
||||
}
|
||||
return forecast;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue