import { Alpaca } from "./alpaca";
import { Strategy } from "./strategy";
import { Executor } from "./executor";
import { waitForNextOpen } from "./trading";

export class Bot {
    private alpaca: Alpaca;
    private strategies: Strategy[];
    private executor: Executor;

    constructor(alpaca: Alpaca, strategies: Strategy[]) {
        const totalAllocation = strategies.reduce((sum, s) => sum + s.capitalAllocation, 0);
        if (totalAllocation > 1.0) {
            throw new Error(
                `Capital allocations sum to ${totalAllocation}, which exceeds 1.0`
            );
        }
        this.alpaca = alpaca;
        this.strategies = strategies;
        this.executor = new Executor(alpaca);
    }

    async runDay(): Promise<void> {
        console.log('waiting for open');
        await waitForNextOpen(this.alpaca);

        const account = await this.alpaca.getAccount();
        const totalCapital = parseFloat(account.cash);

        await Promise.all(
            this.strategies.map(async (strategy) => {
                const signals = await strategy.execute(this.alpaca);
                await this.executor.executeSignals(strategy, signals, totalCapital);
            })
        );
    }
}
