adding data-services

This commit is contained in:
Bojan Kucera 2025-06-03 07:42:48 -04:00
parent e3bfd05b90
commit 405b818c86
139 changed files with 55943 additions and 416 deletions

View file

@ -0,0 +1,55 @@
/**
* Date and time utilities for working with market data
*/
export const dateUtils = {
/**
* Check if a date is a trading day (Monday-Friday, non-holiday)
* This is a simplified implementation - a real version would check market holidays
*/
isTradingDay(date: Date): boolean {
const day = date.getDay();
return day > 0 && day < 6; // Mon-Fri
},
/**
* Get the next trading day from a given date
*/
getNextTradingDay(date: Date): Date {
const nextDay = new Date(date);
nextDay.setDate(nextDay.getDate() + 1);
while (!this.isTradingDay(nextDay)) {
nextDay.setDate(nextDay.getDate() + 1);
}
return nextDay;
},
/**
* Get the previous trading day from a given date
*/
getPreviousTradingDay(date: Date): Date {
const prevDay = new Date(date);
prevDay.setDate(prevDay.getDate() - 1);
while (!this.isTradingDay(prevDay)) {
prevDay.setDate(prevDay.getDate() - 1);
}
return prevDay;
},
/**
* Format a date as YYYY-MM-DD
*/
formatDate(date: Date): string {
return date.toISOString().split('T')[0];
},
/**
* Parse a date string in YYYY-MM-DD format
*/
parseDate(dateStr: string): Date {
return new Date(dateStr);
}
};

View file

@ -0,0 +1,67 @@
/**
* Financial calculation utilities
*/
export const financialUtils = {
/**
* Calculate the Sharpe ratio
* @param returns Array of period returns
* @param riskFreeRate The risk-free rate (e.g. 0.02 for 2%)
*/
calculateSharpeRatio(returns: number[], riskFreeRate: number = 0.02): number {
if (returns.length < 2) {
return 0;
}
// Calculate average return
const avgReturn = returns.reduce((sum, val) => sum + val, 0) / returns.length;
// Calculate standard deviation
const squaredDiffs = returns.map(val => Math.pow(val - avgReturn, 2));
const avgSquaredDiff = squaredDiffs.reduce((sum, val) => sum + val, 0) / squaredDiffs.length;
const stdDev = Math.sqrt(avgSquaredDiff);
// Avoid division by zero
if (stdDev === 0) return 0;
// Calculate Sharpe ratio
return (avgReturn - riskFreeRate) / stdDev;
},
/**
* Calculate the maximum drawdown
* @param equityCurve Array of equity values over time
*/
calculateMaxDrawdown(equityCurve: number[]): number {
if (equityCurve.length < 2) {
return 0;
}
let maxDrawdown = 0;
let peak = equityCurve[0];
for (let i = 1; i < equityCurve.length; i++) {
if (equityCurve[i] > peak) {
peak = equityCurve[i];
} else {
const drawdown = (peak - equityCurve[i]) / peak;
maxDrawdown = Math.max(maxDrawdown, drawdown);
}
}
return maxDrawdown;
},
/**
* Calculate the Compound Annual Growth Rate (CAGR)
* @param startValue Initial investment value
* @param endValue Final investment value
* @param years Number of years
*/
calculateCAGR(startValue: number, endValue: number, years: number): number {
if (years <= 0 || startValue <= 0 || endValue <= 0) {
return 0;
}
return Math.pow(endValue / startValue, 1 / years) - 1;
}
};

3
libs/utils/src/index.ts Normal file
View file

@ -0,0 +1,3 @@
export * from './dateUtils';
export * from './financialUtils';
export * from './logger';

65
libs/utils/src/logger.ts Normal file
View file

@ -0,0 +1,65 @@
/**
* Logger utility with consistent formatting and log levels
*/
export class Logger {
constructor(private serviceName: string, private level: LogLevel = LogLevel.INFO) {}
debug(message: string, ...args: any[]): void {
this.log(LogLevel.DEBUG, message, ...args);
}
info(message: string, ...args: any[]): void {
this.log(LogLevel.INFO, message, ...args);
}
warn(message: string, ...args: any[]): void {
this.log(LogLevel.WARN, message, ...args);
}
error(message: string, ...args: any[]): void {
this.log(LogLevel.ERROR, message, ...args);
}
private log(level: LogLevel, message: string, ...args: any[]): void {
if (level < this.level) return;
const timestamp = new Date().toISOString();
const levelStr = LogLevel[level].padEnd(5);
const logMessage = `[${timestamp}] [${levelStr}] [${this.serviceName}] ${message}`;
switch (level) {
case LogLevel.ERROR:
console.error(logMessage, ...args);
break;
case LogLevel.WARN:
console.warn(logMessage, ...args);
break;
case LogLevel.INFO:
console.info(logMessage, ...args);
break;
case LogLevel.DEBUG:
default:
console.debug(logMessage, ...args);
break;
}
}
setLevel(level: LogLevel): void {
this.level = level;
}
}
export enum LogLevel {
DEBUG = 0,
INFO = 1,
WARN = 2,
ERROR = 3
}
/**
* Create a new logger instance
*/
export function createLogger(serviceName: string, level: LogLevel = LogLevel.INFO): Logger {
return new Logger(serviceName, level);
}