Add bot orchestrator, wire up index.ts, remove old runDay

Bot validates strategy capital allocations, waits for market open,
runs all strategies concurrently, and passes signals to the executor.
The main loop in index.ts now delegates to Bot.runDay().

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jon
2026-01-30 14:09:30 -07:00
parent d0d3d7254a
commit ecdffab950
5 changed files with 179 additions and 73 deletions

View File

@@ -1,5 +1,5 @@
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { printAsset, accountBalance, waitForNextOpen, runDay } from './trading';
import { printAsset, accountBalance, waitForNextOpen } from './trading';
import type { Alpaca } from './alpaca';
function mockAlpaca(overrides: Partial<Alpaca> = {}): Alpaca {
@@ -73,53 +73,3 @@ describe('waitForNextOpen', () => {
});
});
describe('runDay', () => {
beforeEach(() => {
vi.spyOn(console, 'log').mockImplementation(() => {});
});
it('logs up day when second quote ask price is higher', async () => {
const alpaca = mockAlpaca({
getClock: vi.fn().mockResolvedValue({ is_open: false, next_open: new Date().toISOString(), next_close: new Date().toISOString() }),
getLatestQuote: vi.fn()
.mockResolvedValueOnce({ ap: 50.00, bp: 49.90 })
.mockResolvedValueOnce({ ap: 50.50, bp: 50.40 }),
});
const promise = runDay(alpaca);
await vi.advanceTimersByTimeAsync(61000);
await promise;
expect(console.log).toHaveBeenCalledWith('up day: ', expect.any(Date));
});
it('logs down day when second quote ask price is lower', async () => {
const alpaca = mockAlpaca({
getClock: vi.fn().mockResolvedValue({ is_open: false, next_open: new Date().toISOString(), next_close: new Date().toISOString() }),
getLatestQuote: vi.fn()
.mockResolvedValueOnce({ ap: 50.00, bp: 49.90 })
.mockResolvedValueOnce({ ap: 49.50, bp: 49.40 }),
});
const promise = runDay(alpaca);
await vi.advanceTimersByTimeAsync(61000);
await promise;
expect(console.log).toHaveBeenCalledWith('down day', expect.any(Date));
});
it('logs down day when prices are equal', async () => {
const alpaca = mockAlpaca({
getClock: vi.fn().mockResolvedValue({ is_open: false, next_open: new Date().toISOString(), next_close: new Date().toISOString() }),
getLatestQuote: vi.fn()
.mockResolvedValueOnce({ ap: 50.00, bp: 49.90 })
.mockResolvedValueOnce({ ap: 50.00, bp: 49.90 }),
});
const promise = runDay(alpaca);
await vi.advanceTimersByTimeAsync(61000);
await promise;
expect(console.log).toHaveBeenCalledWith('down day', expect.any(Date));
});
});