This commit is contained in:
Boki 2025-06-22 17:55:51 -04:00
parent d858222af7
commit 7d9044ab29
202 changed files with 10755 additions and 10972 deletions

View file

@ -3,7 +3,7 @@
* These functions demonstrate how to use generic types with OHLCV data
*/
import type { OHLCV, HasClose, HasOHLC, HasVolume } from '@stock-bot/types';
import type { HasClose, HasOHLC, HasVolume, OHLCV } from '@stock-bot/types';
/**
* Extract close prices from any data structure that has a close field
@ -16,7 +16,9 @@ export function extractCloses<T extends HasClose>(data: T[]): number[] {
/**
* Extract OHLC prices from any data structure that has OHLC fields
*/
export function extractOHLC<T extends HasOHLC>(data: T[]): {
export function extractOHLC<T extends HasOHLC>(
data: T[]
): {
opens: number[];
highs: number[];
lows: number[];
@ -43,12 +45,12 @@ export function extractVolumes<T extends HasVolume>(data: T[]): number[] {
export function calculateSMA<T extends HasClose>(data: T[], period: number): number[] {
const closes = extractCloses(data);
const result: number[] = [];
for (let i = period - 1; i < closes.length; i++) {
const sum = closes.slice(i - period + 1, i + 1).reduce((a, b) => a + b, 0);
result.push(sum / period);
}
return result;
}
@ -64,7 +66,7 @@ export function calculateTypicalPrice<T extends HasOHLC>(data: T[]): number[] {
*/
export function calculateTrueRange<T extends HasOHLC>(data: T[]): number[] {
const result: number[] = [];
for (let i = 0; i < data.length; i++) {
if (i === 0) {
result.push(data[i]!.high - data[i]!.low);
@ -79,7 +81,7 @@ export function calculateTrueRange<T extends HasOHLC>(data: T[]): number[] {
result.push(tr);
}
}
return result;
}
@ -89,7 +91,7 @@ export function calculateTrueRange<T extends HasOHLC>(data: T[]): number[] {
export function calculateReturns<T extends HasClose>(data: T[]): number[] {
const closes = extractCloses(data);
const returns: number[] = [];
for (let i = 1; i < closes.length; i++) {
const current = closes[i]!;
const previous = closes[i - 1]!;
@ -99,7 +101,7 @@ export function calculateReturns<T extends HasClose>(data: T[]): number[] {
returns.push(0);
}
}
return returns;
}
@ -109,7 +111,7 @@ export function calculateReturns<T extends HasClose>(data: T[]): number[] {
export function calculateLogReturns<T extends HasClose>(data: T[]): number[] {
const closes = extractCloses(data);
const logReturns: number[] = [];
for (let i = 1; i < closes.length; i++) {
const current = closes[i]!;
const previous = closes[i - 1]!;
@ -119,7 +121,7 @@ export function calculateLogReturns<T extends HasClose>(data: T[]): number[] {
logReturns.push(0);
}
}
return logReturns;
}
@ -130,19 +132,19 @@ export function calculateVWAP<T extends HasOHLC & HasVolume>(data: T[]): number[
const result: number[] = [];
let cumulativeVolumePrice = 0;
let cumulativeVolume = 0;
for (const item of data) {
const typicalPrice = (item.high + item.low + item.close) / 3;
cumulativeVolumePrice += typicalPrice * item.volume;
cumulativeVolume += item.volume;
if (cumulativeVolume > 0) {
result.push(cumulativeVolumePrice / cumulativeVolume);
} else {
result.push(typicalPrice);
}
}
return result;
}
@ -156,11 +158,7 @@ export function filterBySymbol(data: OHLCV[], symbol: string): OHLCV[] {
/**
* Filter OHLCV data by time range
*/
export function filterByTimeRange(
data: OHLCV[],
startTime: number,
endTime: number
): OHLCV[] {
export function filterByTimeRange(data: OHLCV[], startTime: number, endTime: number): OHLCV[] {
return data.filter(item => item.timestamp >= startTime && item.timestamp <= endTime);
}
@ -169,14 +167,14 @@ export function filterByTimeRange(
*/
export function groupBySymbol(data: OHLCV[]): Record<string, OHLCV[]> {
const grouped: Record<string, OHLCV[]> = {};
for (const item of data) {
if (!grouped[item.symbol]) {
grouped[item.symbol] = [];
}
grouped[item.symbol]!.push(item);
}
return grouped;
}
@ -186,6 +184,6 @@ export function groupBySymbol(data: OHLCV[]): Record<string, OHLCV[]> {
export function convertTimestamps(data: OHLCV[]): Array<OHLCV & { date: Date }> {
return data.map(item => ({
...item,
date: new Date(item.timestamp)
date: new Date(item.timestamp),
}));
}
}