work on calculations
This commit is contained in:
parent
3d910a13e0
commit
ab7ef2b678
20 changed files with 1343 additions and 222 deletions
|
|
@ -52,9 +52,9 @@ export interface MarketRegime {
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculate Volume Weighted Average Price (VWAP)
|
||||
* Volume Weighted Average Price (VWAP)
|
||||
*/
|
||||
export function calculateVWAP(ohlcv: OHLCVData[]): number[] {
|
||||
export function VWAP(ohlcv: OHLCVData[]): number[] {
|
||||
if (ohlcv.length === 0) return [];
|
||||
|
||||
const vwap: number[] = [];
|
||||
|
|
@ -73,9 +73,9 @@ export function calculateVWAP(ohlcv: OHLCVData[]): number[] {
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculate Time Weighted Average Price (TWAP)
|
||||
* Time Weighted Average Price (TWAP)
|
||||
*/
|
||||
export function calculateTWAP(prices: number[], timeWeights?: number[]): number {
|
||||
export function TWAP(prices: number[], timeWeights?: number[]): number {
|
||||
if (prices.length === 0) return 0;
|
||||
|
||||
if (!timeWeights) {
|
||||
|
|
@ -93,9 +93,9 @@ export function calculateTWAP(prices: number[], timeWeights?: number[]): number
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculate market impact of trades
|
||||
* market impact of trades
|
||||
*/
|
||||
export function calculateMarketImpact(
|
||||
export function MarketImpact(
|
||||
trades: Array<{ price: number; volume: number; side: 'buy' | 'sell'; timestamp: Date }>,
|
||||
benchmarkPrice: number
|
||||
): {
|
||||
|
|
@ -138,9 +138,9 @@ export function calculateMarketImpact(
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculate liquidity metrics
|
||||
* liquidity metrics
|
||||
*/
|
||||
export function calculateLiquidityMetrics(
|
||||
export function LiquidityMetrics(
|
||||
ohlcv: OHLCVData[],
|
||||
bidPrices: number[],
|
||||
askPrices: number[],
|
||||
|
|
@ -209,13 +209,13 @@ export function identifyMarketRegime(
|
|||
const prices = recentData.map(candle => candle.close);
|
||||
const volumes = recentData.map(candle => candle.volume);
|
||||
|
||||
// Calculate returns and volatility
|
||||
// returns and volatility
|
||||
const returns = [];
|
||||
for (let i = 1; i < prices.length; i++) {
|
||||
returns.push((prices[i] - prices[i - 1]) / prices[i - 1]);
|
||||
}
|
||||
|
||||
const volatility = calculateVolatility(returns);
|
||||
const volatility = Volatility(returns);
|
||||
const averageVolume = volumes.reduce((sum, vol) => sum + vol, 0) / volumes.length;
|
||||
|
||||
// Trend analysis
|
||||
|
|
@ -258,9 +258,9 @@ export function identifyMarketRegime(
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculate order book imbalance
|
||||
* order book imbalance
|
||||
*/
|
||||
export function calculateOrderBookImbalance(
|
||||
export function OrderBookImbalance(
|
||||
bidPrices: number[],
|
||||
askPrices: number[],
|
||||
bidSizes: number[],
|
||||
|
|
@ -285,9 +285,9 @@ export function calculateOrderBookImbalance(
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculate intraday patterns
|
||||
* intraday patterns
|
||||
*/
|
||||
export function calculateIntradayPatterns(
|
||||
export function IntradayPatterns(
|
||||
ohlcv: OHLCVData[]
|
||||
): {
|
||||
hourlyReturns: { [hour: number]: number };
|
||||
|
|
@ -312,7 +312,7 @@ export function calculateIntradayPatterns(
|
|||
hourlyData[hour].volumes.push(ohlcv[i].volume);
|
||||
}
|
||||
|
||||
// Calculate statistics for each hour
|
||||
// statistics for each hour
|
||||
const hourlyReturns: { [hour: number]: number } = {};
|
||||
const hourlyVolatility: { [hour: number]: number } = {};
|
||||
const hourlyVolume: { [hour: number]: number } = {};
|
||||
|
|
@ -323,13 +323,13 @@ export function calculateIntradayPatterns(
|
|||
hourlyReturns[hour] = data.returns.length > 0 ?
|
||||
data.returns.reduce((sum, ret) => sum + ret, 0) / data.returns.length : 0;
|
||||
|
||||
hourlyVolatility[hour] = calculateVolatility(data.returns);
|
||||
hourlyVolatility[hour] = Volatility(data.returns);
|
||||
|
||||
hourlyVolume[hour] = data.volumes.length > 0 ?
|
||||
data.volumes.reduce((sum, vol) => sum + vol, 0) / data.volumes.length : 0;
|
||||
}
|
||||
|
||||
// Calculate opening gap and closing drift
|
||||
// opening gap and closing drift
|
||||
const openingGap = ohlcv.length > 1 ?
|
||||
(ohlcv[0].open - ohlcv[0].close) / ohlcv[0].close : 0;
|
||||
|
||||
|
|
@ -346,9 +346,9 @@ export function calculateIntradayPatterns(
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculate price discovery metrics
|
||||
* price discovery metrics
|
||||
*/
|
||||
export function calculatePriceDiscovery(
|
||||
export function PriceDiscovery(
|
||||
prices1: number[], // Prices from market 1
|
||||
prices2: number[] // Prices from market 2
|
||||
): {
|
||||
|
|
@ -366,7 +366,7 @@ export function calculatePriceDiscovery(
|
|||
};
|
||||
}
|
||||
|
||||
// Calculate returns
|
||||
// returns
|
||||
const returns1 = [];
|
||||
const returns2 = [];
|
||||
|
||||
|
|
@ -375,20 +375,20 @@ export function calculatePriceDiscovery(
|
|||
returns2.push((prices2[i] - prices2[i - 1]) / prices2[i - 1]);
|
||||
}
|
||||
|
||||
// Calculate correlations with lags
|
||||
const correlation0 = calculateCorrelation(returns1, returns2);
|
||||
// correlations with lags
|
||||
const correlation0 = Correlation(returns1, returns2);
|
||||
const correlation1 = returns1.length > 1 ?
|
||||
calculateCorrelation(returns1.slice(1), returns2.slice(0, -1)) : 0;
|
||||
Correlation(returns1.slice(1), returns2.slice(0, -1)) : 0;
|
||||
const correlationMinus1 = returns1.length > 1 ?
|
||||
calculateCorrelation(returns1.slice(0, -1), returns2.slice(1)) : 0;
|
||||
Correlation(returns1.slice(0, -1), returns2.slice(1)) : 0;
|
||||
|
||||
// Price lead-lag (simplified)
|
||||
const priceLeadLag = correlation1 - correlationMinus1;
|
||||
|
||||
// Information shares (simplified Hasbrouck methodology)
|
||||
const variance1 = calculateVariance(returns1);
|
||||
const variance2 = calculateVariance(returns2);
|
||||
const covariance = calculateCovariance(returns1, returns2);
|
||||
const variance1 = Variance(returns1);
|
||||
const variance2 = Variance(returns2);
|
||||
const covariance = Covariance(returns1, returns2);
|
||||
|
||||
const totalVariance = variance1 + variance2 + 2 * covariance;
|
||||
const informationShare1 = totalVariance > 0 ? (variance1 + covariance) / totalVariance : 0.5;
|
||||
|
|
@ -406,9 +406,9 @@ export function calculatePriceDiscovery(
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculate market stress indicators
|
||||
* market stress indicators
|
||||
*/
|
||||
export function calculateMarketStress(
|
||||
export function MarketStress(
|
||||
ohlcv: OHLCVData[],
|
||||
lookbackPeriod: number = 20
|
||||
): {
|
||||
|
|
@ -438,12 +438,12 @@ export function calculateMarketStress(
|
|||
}
|
||||
|
||||
// Volatility stress
|
||||
const volatility = calculateVolatility(returns);
|
||||
const volatility = Volatility(returns);
|
||||
const volatilityStress = Math.min(1, volatility / 0.05); // Normalize to 5% daily vol
|
||||
|
||||
// Liquidity stress (volume-based)
|
||||
const averageVolume = volumes.reduce((sum, vol) => sum + vol, 0) / volumes.length;
|
||||
const volumeVariability = calculateVolatility(volumes.map(vol => vol / averageVolume));
|
||||
const volumeVariability = Volatility(volumes.map(vol => vol / averageVolume));
|
||||
const liquidityStress = Math.min(1, volumeVariability);
|
||||
|
||||
// Correlation stress (simplified - would need multiple assets)
|
||||
|
|
@ -467,9 +467,82 @@ export function calculateMarketStress(
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* realized spread
|
||||
*/
|
||||
export function RealizedSpread(
|
||||
trades: Array<{ price: number; side: 'buy' | 'sell'; timestamp: Date }>,
|
||||
midPrices: number[],
|
||||
timeWindow: number = 5 // minutes
|
||||
): number {
|
||||
if (trades.length === 0 || midPrices.length === 0) return 0;
|
||||
|
||||
let totalSpread = 0;
|
||||
let count = 0;
|
||||
|
||||
for (const trade of trades) {
|
||||
// Find corresponding mid price
|
||||
const midPrice = midPrices[0]; // Simplified - should match by timestamp
|
||||
|
||||
const spread = trade.side === 'buy' ?
|
||||
2 * (trade.price - midPrice) :
|
||||
2 * (midPrice - trade.price);
|
||||
|
||||
totalSpread += spread;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count > 0 ? totalSpread / count : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* implementation shortfall
|
||||
*/
|
||||
export function ImplementationShortfall(
|
||||
decisionPrice: number,
|
||||
executionPrices: number[],
|
||||
volumes: number[],
|
||||
commissions: number[],
|
||||
marketImpact: number[]
|
||||
): {
|
||||
totalShortfall: number;
|
||||
delayComponent: number;
|
||||
marketImpactComponent: number;
|
||||
timingComponent: number;
|
||||
commissionComponent: number;
|
||||
} {
|
||||
if (executionPrices.length !== volumes.length) {
|
||||
throw new Error('Execution prices and volumes must have same length');
|
||||
}
|
||||
|
||||
const totalVolume = volumes.reduce((sum, vol) => sum + vol, 0);
|
||||
const weightedExecutionPrice = executionPrices.reduce((sum, price, i) =>
|
||||
sum + price * volumes[i], 0) / totalVolume;
|
||||
|
||||
const totalCommissions = commissions.reduce((sum, comm) => sum + comm, 0);
|
||||
const totalMarketImpact = marketImpact.reduce((sum, impact, i) =>
|
||||
sum + impact * volumes[i], 0);
|
||||
|
||||
const delayComponent = weightedExecutionPrice - decisionPrice;
|
||||
const marketImpactComponent = totalMarketImpact / totalVolume;
|
||||
const timingComponent = 0; // Simplified - would need benchmark price evolution
|
||||
const commissionComponent = totalCommissions / totalVolume;
|
||||
|
||||
const totalShortfall = delayComponent + marketImpactComponent +
|
||||
timingComponent + commissionComponent;
|
||||
|
||||
return {
|
||||
totalShortfall,
|
||||
delayComponent,
|
||||
marketImpactComponent,
|
||||
timingComponent,
|
||||
commissionComponent
|
||||
};
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
|
||||
function calculateVolatility(returns: number[]): number {
|
||||
function Volatility(returns: number[]): number {
|
||||
if (returns.length < 2) return 0;
|
||||
|
||||
const mean = returns.reduce((sum, ret) => sum + ret, 0) / returns.length;
|
||||
|
|
@ -478,7 +551,7 @@ function calculateVolatility(returns: number[]): number {
|
|||
return Math.sqrt(variance);
|
||||
}
|
||||
|
||||
function calculateCorrelation(x: number[], y: number[]): number {
|
||||
function Correlation(x: number[], y: number[]): number {
|
||||
if (x.length !== y.length || x.length < 2) return 0;
|
||||
|
||||
const n = x.length;
|
||||
|
|
@ -503,14 +576,14 @@ function calculateCorrelation(x: number[], y: number[]): number {
|
|||
return denominator > 0 ? numerator / denominator : 0;
|
||||
}
|
||||
|
||||
function calculateVariance(values: number[]): number {
|
||||
function Variance(values: number[]): number {
|
||||
if (values.length < 2) return 0;
|
||||
|
||||
const mean = values.reduce((sum, val) => sum + val, 0) / values.length;
|
||||
return values.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / (values.length - 1);
|
||||
}
|
||||
|
||||
function calculateCovariance(x: number[], y: number[]): number {
|
||||
function Covariance(x: number[], y: number[]): number {
|
||||
if (x.length !== y.length || x.length < 2) return 0;
|
||||
|
||||
const n = x.length;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue