Introduce logger infrastructure and add structured logging to every layer: alpaca.ts (buy/sell/quote/clock), momentum-indicator.ts (evaluate flow), momentum-strategy.ts (poll loop), index.ts (startup/cycle), and trading.ts (market timing). Replace raw console.log calls with leveled logger. Update all tests with appropriate console spies. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
46 lines
1.5 KiB
TypeScript
46 lines
1.5 KiB
TypeScript
import { Alpaca } from "./alpaca";
|
|
import { logger } from "./logger";
|
|
import { Strategy } from "./strategy";
|
|
import { isMarketOpen, waitForNextOpen } from "./trading";
|
|
|
|
export interface StrategyAllocation {
|
|
strategy: Strategy;
|
|
capitalAllocation: number;
|
|
}
|
|
|
|
export class Bot {
|
|
private alpaca: Alpaca;
|
|
private allocations: StrategyAllocation[];
|
|
|
|
constructor(alpaca: Alpaca, allocations: StrategyAllocation[]) {
|
|
const totalAllocation = allocations.reduce((sum, a) => sum + a.capitalAllocation, 0);
|
|
if (totalAllocation > 1.0) {
|
|
throw new Error(
|
|
`Capital allocations sum to ${totalAllocation}, which exceeds 1.0`
|
|
);
|
|
}
|
|
this.alpaca = alpaca;
|
|
this.allocations = allocations;
|
|
}
|
|
|
|
async runDay(): Promise<void> {
|
|
const open = await isMarketOpen(this.alpaca);
|
|
if (!open) {
|
|
logger.info('waiting for open');
|
|
await waitForNextOpen(this.alpaca);
|
|
}
|
|
logger.info('market is open, running strategies');
|
|
const account = await this.alpaca.getAccount();
|
|
logger.debug(`got account: ${JSON.stringify(account)}`);
|
|
const totalCapital = parseFloat(account.cash);
|
|
logger.debug(`total capital: ${totalCapital}`);
|
|
|
|
await Promise.all(
|
|
this.allocations.map(async ({ strategy, capitalAllocation }) => {
|
|
const capitalAmount = totalCapital * capitalAllocation;
|
|
await strategy.execute(this.alpaca, capitalAmount);
|
|
})
|
|
);
|
|
}
|
|
}
|