mirror of
https://github.com/multipleof4/KalBot.git
synced 2026-03-17 05:51:02 +00:00
Feat: Add martingale-alpha, per-strategy state output
This commit is contained in:
25
worker.js
25
worker.js
@@ -1,51 +1,48 @@
|
||||
import { MarketTracker } from './lib/market/tracker.js';
|
||||
import { PaperEngine } from './lib/paper/engine.js';
|
||||
import { MartingaleStrategy } from './lib/strategies/martingale.js';
|
||||
import { MartingaleAlphaStrategy } from './lib/strategies/martingale-alpha.js';
|
||||
import { ThresholdStrategy } from './lib/strategies/threshold.js';
|
||||
import { db } from './lib/db.js';
|
||||
import { notify } from './lib/notify.js';
|
||||
import fs from 'fs';
|
||||
|
||||
// Shared state file for the Next.js frontend to read
|
||||
const STATE_FILE = '/tmp/kalbot-state.json';
|
||||
const HEARTBEAT_MS = 2000;
|
||||
|
||||
async function main() {
|
||||
console.log('=== Kalbot Worker Starting ===');
|
||||
|
||||
// Connect to SurrealDB
|
||||
await db.connect();
|
||||
|
||||
// Initialize paper engine
|
||||
const paper = new PaperEngine(1000);
|
||||
await paper.init();
|
||||
|
||||
// Initialize strategies
|
||||
const strategies = [
|
||||
new MartingaleStrategy({ threshold: 70, baseBet: 1, maxDoublings: 5 }),
|
||||
new MartingaleAlphaStrategy({ minPct: 40, maxPct: 60, baseBet: 1, maxRounds: 3 }),
|
||||
new ThresholdStrategy({ triggerPct: 65, betSize: 1 })
|
||||
];
|
||||
|
||||
// Ensure each strategy has a paper account initialized
|
||||
for (const s of strategies) {
|
||||
paper._getAccount(s.name);
|
||||
}
|
||||
|
||||
console.log(`[Worker] Loaded ${strategies.length} strategies: ${strategies.map((s) => s.name).join(', ')}`);
|
||||
|
||||
// Initialize market tracker
|
||||
const tracker = new MarketTracker();
|
||||
let latestMarketState = null;
|
||||
let heartbeatTimer = null;
|
||||
|
||||
// Write initial heartbeat immediately so dashboard never shows "Updated: never"
|
||||
writeState(latestMarketState, paper, strategies);
|
||||
|
||||
// On every market update, run strategies
|
||||
tracker.on('update', async (state) => {
|
||||
latestMarketState = state || null;
|
||||
|
||||
// Write state to file for frontend
|
||||
writeState(latestMarketState, paper, strategies);
|
||||
|
||||
if (!state) return;
|
||||
|
||||
// Run each strategy
|
||||
for (const strategy of strategies) {
|
||||
if (!strategy.enabled) continue;
|
||||
|
||||
@@ -56,21 +53,17 @@ async function main() {
|
||||
if (strategy.mode === 'paper') {
|
||||
await paper.executeTrade(signal, state);
|
||||
}
|
||||
// TODO: Live mode — use placeOrder() from rest.js
|
||||
}
|
||||
}
|
||||
|
||||
// Update state file after potential trades
|
||||
writeState(latestMarketState, paper, strategies);
|
||||
});
|
||||
|
||||
// On market settlement, settle paper positions and notify strategies
|
||||
tracker.on('settled', async ({ ticker, result }) => {
|
||||
console.log(`[Worker] Market ${ticker} settled: ${result}`);
|
||||
|
||||
const settledPositions = await paper.settle(ticker, result);
|
||||
|
||||
// Notify strategies about settlement
|
||||
for (const strategy of strategies) {
|
||||
if (!settledPositions) continue;
|
||||
for (const trade of settledPositions) {
|
||||
@@ -88,11 +81,9 @@ async function main() {
|
||||
writeState(latestMarketState, paper, strategies);
|
||||
});
|
||||
|
||||
// Start tracking
|
||||
await tracker.start();
|
||||
await notify('🤖 Kalbot Worker started!', 'Kalbot Online', 'low', 'robot,green_circle');
|
||||
|
||||
// Keep state fresh even if market API is temporarily quiet
|
||||
heartbeatTimer = setInterval(() => {
|
||||
writeState(latestMarketState, paper, strategies);
|
||||
}, HEARTBEAT_MS);
|
||||
@@ -107,7 +98,6 @@ async function main() {
|
||||
process.exit(0);
|
||||
};
|
||||
|
||||
// Graceful shutdown
|
||||
process.on('SIGINT', () => shutdown('SIGINT'));
|
||||
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
||||
}
|
||||
@@ -116,6 +106,7 @@ function writeState(marketState, paper, strategies) {
|
||||
const data = {
|
||||
market: marketState,
|
||||
paper: paper.getStats(),
|
||||
paperByStrategy: paper.getPerStrategyStats(),
|
||||
strategies: strategies.map((s) => s.toJSON()),
|
||||
workerUptime: process.uptime(),
|
||||
lastUpdate: Date.now()
|
||||
|
||||
Reference in New Issue
Block a user