mirror of
https://github.com/mauricioabh/arbpulse.git
synced 2026-07-30 00:57:43 +00:00
2e8744ccf0
Real-time BTC cross-exchange arbitrage detection (Kraken, Bybit, OKX, Binance) with React dashboard, GitHub Actions CI, and documented Fly.io deploy workflow. Co-authored-by: Cursor <cursoragent@cursor.com>
118 lines
4.2 KiB
TypeScript
118 lines
4.2 KiB
TypeScript
import { createLogger } from "../infrastructure/logging/logger.js";
|
|
import { config } from "../infrastructure/config/config.js";
|
|
import { runtime } from "../infrastructure/config/runtime.js";
|
|
import { RuntimeTradingPolicy } from "../infrastructure/config/trading-policy.js";
|
|
import { ConnectorFactory } from "../infrastructure/exchanges/index.js";
|
|
import { SyntheticFeed } from "../infrastructure/demo/synthetic-feed.js";
|
|
import { FeedRecorder } from "../infrastructure/demo/recorder.js";
|
|
import { OrderBookManager } from "../infrastructure/state/order-book-manager.js";
|
|
import { WalletBook } from "../infrastructure/state/wallet-book.js";
|
|
import { Store } from "../infrastructure/state/store.js";
|
|
import { RiskManager } from "../infrastructure/simulation/risk-manager.js";
|
|
import { ExecutionSimulator } from "../infrastructure/simulation/execution-simulator.js";
|
|
import { Rebalancer } from "../infrastructure/rebalancing/rebalancer.js";
|
|
import { SystemClock } from "../infrastructure/time/clock.js";
|
|
import { IdGenerator } from "../infrastructure/ids/id-generator.js";
|
|
import { ArbitrageEngine } from "../domain/services/arbitrage-engine.js";
|
|
import { ExecuteArbitrage } from "../application/use-cases/execute-arbitrage.js";
|
|
import { ProcessOrderBookUpdate } from "../application/use-cases/process-order-book-update.js";
|
|
import { RebalanceInventory } from "../application/use-cases/rebalance-inventory.js";
|
|
import { TickRiskAndRebalance } from "../application/use-cases/tick-risk-and-rebalance.js";
|
|
import { StartMarketData } from "../application/use-cases/start-market-data.js";
|
|
import { StopMarketData } from "../application/use-cases/stop-market-data.js";
|
|
import { ControlService } from "../application/use-cases/control-service.js";
|
|
import { ApplicationService } from "./application-service.js";
|
|
import type { IClock, MarketDataFeedFactory } from "../domain/ports/ports.js";
|
|
|
|
const log = createLogger("bootstrap");
|
|
|
|
export interface BootstrapOptions {
|
|
feedFactory?: MarketDataFeedFactory;
|
|
demoFeed?: SyntheticFeed;
|
|
clock?: IClock;
|
|
}
|
|
|
|
export interface AppContext {
|
|
application: ApplicationService;
|
|
start(): void;
|
|
stop(): void;
|
|
}
|
|
|
|
export function bootstrap(options: BootstrapOptions = {}): AppContext {
|
|
const obm = new OrderBookManager();
|
|
const wallets = new WalletBook();
|
|
const store = new Store();
|
|
const policy = new RuntimeTradingPolicy();
|
|
const clock = options.clock ?? new SystemClock();
|
|
const ids = new IdGenerator();
|
|
const risk = new RiskManager(store, policy);
|
|
const exec = new ExecutionSimulator(wallets, policy, ids);
|
|
const executeArbitrage = new ExecuteArbitrage(exec, store, risk);
|
|
const engine = new ArbitrageEngine({
|
|
quotes: obm,
|
|
inventory: wallets,
|
|
store,
|
|
risk,
|
|
opportunityExecutor: executeArbitrage,
|
|
policy,
|
|
clock,
|
|
ids,
|
|
});
|
|
const rebalancer = new Rebalancer(wallets, store, policy, ids);
|
|
const rebalanceInventory = new RebalanceInventory(rebalancer);
|
|
const tickRisk = new TickRiskAndRebalance(engine, rebalanceInventory);
|
|
const recorder = new FeedRecorder();
|
|
|
|
const processBook = new ProcessOrderBookUpdate(
|
|
engine,
|
|
recorder,
|
|
(exchange) => runtime.activeExchanges[exchange],
|
|
);
|
|
|
|
const demoFeed = options.demoFeed ?? new SyntheticFeed();
|
|
demoFeed.onBook((book) => processBook.run(book));
|
|
|
|
const feedFactory = options.feedFactory ?? new ConnectorFactory();
|
|
const marketData = new StartMarketData(
|
|
feedFactory,
|
|
demoFeed,
|
|
(book) => processBook.run(book),
|
|
() => runtime.demoMode,
|
|
(id) => runtime.activeExchanges[id],
|
|
);
|
|
|
|
const controls = new ControlService(
|
|
runtime,
|
|
risk,
|
|
obm,
|
|
() => {
|
|
store.reset();
|
|
wallets.reset();
|
|
log.info("state and wallets reset");
|
|
},
|
|
marketData,
|
|
recorder,
|
|
);
|
|
|
|
const application = new ApplicationService(store, obm, wallets, controls);
|
|
const stopMarket = new StopMarketData(marketData);
|
|
|
|
let tickTimer: NodeJS.Timeout | null = null;
|
|
|
|
return {
|
|
application,
|
|
start() {
|
|
marketData.start();
|
|
tickTimer = setInterval(() => tickRisk.tick(Date.now()), 1000);
|
|
log.info(`engine started (demo=${runtime.demoMode})`);
|
|
},
|
|
stop() {
|
|
if (tickTimer) clearInterval(tickTimer);
|
|
stopMarket.run();
|
|
recorder.close();
|
|
},
|
|
};
|
|
}
|
|
|
|
export { config };
|