adding data-services
This commit is contained in:
parent
e3bfd05b90
commit
405b818c86
139 changed files with 55943 additions and 416 deletions
51
libs/utils/README.md
Normal file
51
libs/utils/README.md
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# Utils Library
|
||||
|
||||
Common utility functions shared across services in the stock-bot project.
|
||||
|
||||
## Included Utilities
|
||||
|
||||
### Date Utilities
|
||||
|
||||
Helper functions for working with market dates:
|
||||
|
||||
```typescript
|
||||
import { dateUtils } from '@stock-bot/utils';
|
||||
|
||||
// Check if a date is a trading day
|
||||
const isTradingDay = dateUtils.isTradingDay(new Date());
|
||||
|
||||
// Get the next trading day
|
||||
const nextTradingDay = dateUtils.getNextTradingDay(new Date());
|
||||
```
|
||||
|
||||
### Financial Utilities
|
||||
|
||||
Mathematical functions for financial calculations:
|
||||
|
||||
```typescript
|
||||
import { financialUtils } from '@stock-bot/utils';
|
||||
|
||||
// Calculate Sharpe ratio
|
||||
const returns = [0.05, 0.03, -0.01, 0.04, 0.02];
|
||||
const sharpeRatio = financialUtils.calculateSharpeRatio(returns, 0.02);
|
||||
|
||||
// Calculate maximum drawdown
|
||||
const equityCurve = [10000, 10500, 10200, 10800, 10300];
|
||||
const maxDrawdown = financialUtils.calculateMaxDrawdown(equityCurve);
|
||||
```
|
||||
|
||||
### Logger
|
||||
|
||||
Standardized logging service:
|
||||
|
||||
```typescript
|
||||
import { createLogger, LogLevel } from '@stock-bot/utils';
|
||||
|
||||
// Create a logger for your service
|
||||
const logger = createLogger('strategy-orchestrator', LogLevel.INFO);
|
||||
|
||||
// Log at different levels
|
||||
logger.info('Strategy initialized');
|
||||
logger.warn('Position size exceeds recommended limit');
|
||||
logger.error('Failed to execute order', { orderId: '123', reason: 'Insufficient funds' });
|
||||
```
|
||||
22
libs/utils/package.json
Normal file
22
libs/utils/package.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "@stock-bot/utils",
|
||||
"version": "1.0.0",
|
||||
"description": "Common utility functions for stock-bot services",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"dev": "tsc --watch",
|
||||
"clean": "rm -rf dist",
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@stock-bot/shared-types": "workspace:*",
|
||||
"date-fns": "^2.30.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.2",
|
||||
"jest": "^29.5.0",
|
||||
"typescript": "^5.4.5"
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
13
libs/utils/tsconfig.json
Normal file
13
libs/utils/tsconfig.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"esModuleInterop": true,
|
||||
"declaration": true,
|
||||
"outDir": "dist",
|
||||
"strict": true,
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue