adding data-services
This commit is contained in:
parent
e3bfd05b90
commit
405b818c86
139 changed files with 55943 additions and 416 deletions
55
libs/utils/src/dateUtils.ts
Normal file
55
libs/utils/src/dateUtils.ts
Normal 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);
|
||||
}
|
||||
};
|
||||
67
libs/utils/src/financialUtils.ts
Normal file
67
libs/utils/src/financialUtils.ts
Normal 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
3
libs/utils/src/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from './dateUtils';
|
||||
export * from './financialUtils';
|
||||
export * from './logger';
|
||||
65
libs/utils/src/logger.ts
Normal file
65
libs/utils/src/logger.ts
Normal 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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue