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 { 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); }) ); } }