@timmeck/trading-brain 2.31.12 → 2.31.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard.html +13 -0
- package/dist/cli/commands/dashboard.js +20 -0
- package/dist/cli/commands/dashboard.js.map +1 -1
- package/dist/cli/commands/status.js +29 -1
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/config.js +8 -8
- package/dist/config.js.map +1 -1
- package/dist/dashboard/renderer.js +3 -2
- package/dist/dashboard/renderer.js.map +1 -1
- package/dist/ipc/router.d.ts +1 -0
- package/dist/ipc/router.js +24 -0
- package/dist/ipc/router.js.map +1 -1
- package/dist/market/__tests__/market-data-service.test.d.ts +1 -0
- package/dist/market/__tests__/market-data-service.test.js +231 -0
- package/dist/market/__tests__/market-data-service.test.js.map +1 -0
- package/dist/market/ccxt-provider.d.ts +59 -0
- package/dist/market/ccxt-provider.js +231 -0
- package/dist/market/ccxt-provider.js.map +1 -0
- package/dist/market/coingecko-provider.d.ts +18 -0
- package/dist/market/coingecko-provider.js +78 -0
- package/dist/market/coingecko-provider.js.map +1 -0
- package/dist/market/market-data-provider.d.ts +70 -0
- package/dist/market/market-data-provider.js +32 -0
- package/dist/market/market-data-provider.js.map +1 -0
- package/dist/market/market-data-service.d.ts +60 -0
- package/dist/market/market-data-service.js +215 -0
- package/dist/market/market-data-service.js.map +1 -0
- package/dist/market/yahoo-provider.d.ts +17 -0
- package/dist/market/yahoo-provider.js +92 -0
- package/dist/market/yahoo-provider.js.map +1 -0
- package/dist/paper/__tests__/decision-engine.test.d.ts +1 -0
- package/dist/paper/__tests__/decision-engine.test.js +131 -0
- package/dist/paper/__tests__/decision-engine.test.js.map +1 -0
- package/dist/paper/__tests__/paper-engine.test.d.ts +1 -0
- package/dist/paper/__tests__/paper-engine.test.js +128 -0
- package/dist/paper/__tests__/paper-engine.test.js.map +1 -0
- package/dist/paper/__tests__/price-fetcher.test.d.ts +1 -0
- package/dist/paper/__tests__/price-fetcher.test.js +88 -0
- package/dist/paper/__tests__/price-fetcher.test.js.map +1 -0
- package/dist/paper/decision-engine.d.ts +0 -3
- package/dist/paper/decision-engine.js +8 -18
- package/dist/paper/decision-engine.js.map +1 -1
- package/dist/paper/paper-engine.d.ts +4 -0
- package/dist/paper/paper-engine.js +25 -5
- package/dist/paper/paper-engine.js.map +1 -1
- package/dist/paper/paper.service.js +2 -0
- package/dist/paper/paper.service.js.map +1 -1
- package/dist/paper/portfolio-manager.d.ts +1 -1
- package/dist/paper/portfolio-manager.js +6 -6
- package/dist/paper/portfolio-manager.js.map +1 -1
- package/dist/paper/price-fetcher.d.ts +6 -0
- package/dist/paper/price-fetcher.js +54 -8
- package/dist/paper/price-fetcher.js.map +1 -1
- package/dist/paper/types.d.ts +2 -0
- package/dist/trading-core.js +28 -6
- package/dist/trading-core.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import { PriceFetcher } from '../price-fetcher.js';
|
|
3
|
+
const mockConfig = {
|
|
4
|
+
enabled: true,
|
|
5
|
+
intervalMs: 300_000,
|
|
6
|
+
startingBalance: 10_000,
|
|
7
|
+
maxPositionPct: 5,
|
|
8
|
+
maxPositions: 10,
|
|
9
|
+
stopLossPct: -2.5,
|
|
10
|
+
takeProfitPct: 4,
|
|
11
|
+
trailingStopActivation: 3,
|
|
12
|
+
trailingStopDistance: 1.5,
|
|
13
|
+
confidenceThreshold: 0.60,
|
|
14
|
+
scoreThreshold: 80,
|
|
15
|
+
timeExitHours: 24,
|
|
16
|
+
cryptoIds: ['bitcoin'],
|
|
17
|
+
stockSymbols: ['AAPL'],
|
|
18
|
+
};
|
|
19
|
+
function createMockRepo() {
|
|
20
|
+
return {
|
|
21
|
+
getRecentPrices: vi.fn().mockReturnValue([]),
|
|
22
|
+
savePrices: vi.fn(),
|
|
23
|
+
pruneOldPrices: vi.fn(),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
describe('PriceFetcher', () => {
|
|
27
|
+
describe('Rate limiting', () => {
|
|
28
|
+
it('should have rate limiting properties initialized', () => {
|
|
29
|
+
const repo = createMockRepo();
|
|
30
|
+
const fetcher = new PriceFetcher(mockConfig, repo);
|
|
31
|
+
// Verify internal state
|
|
32
|
+
expect(fetcher.consecutiveErrors).toBe(0);
|
|
33
|
+
expect(fetcher.backoffMs).toBe(0);
|
|
34
|
+
expect(fetcher.MAX_CONSECUTIVE_ERRORS).toBe(5);
|
|
35
|
+
});
|
|
36
|
+
it('should track consecutive errors and compute backoff', () => {
|
|
37
|
+
const repo = createMockRepo();
|
|
38
|
+
const fetcher = new PriceFetcher(mockConfig, repo);
|
|
39
|
+
// Simulate errors
|
|
40
|
+
for (let i = 0; i < 5; i++) {
|
|
41
|
+
fetcher.recordError();
|
|
42
|
+
}
|
|
43
|
+
expect(fetcher.consecutiveErrors).toBe(5);
|
|
44
|
+
expect(fetcher.backoffMs).toBeGreaterThan(0);
|
|
45
|
+
});
|
|
46
|
+
it('should reset error tracking on success', () => {
|
|
47
|
+
const repo = createMockRepo();
|
|
48
|
+
const fetcher = new PriceFetcher(mockConfig, repo);
|
|
49
|
+
// Simulate errors then success
|
|
50
|
+
for (let i = 0; i < 5; i++) {
|
|
51
|
+
fetcher.recordError();
|
|
52
|
+
}
|
|
53
|
+
expect(fetcher.consecutiveErrors).toBe(5);
|
|
54
|
+
fetcher.recordSuccess();
|
|
55
|
+
expect(fetcher.consecutiveErrors).toBe(0);
|
|
56
|
+
expect(fetcher.backoffMs).toBe(0);
|
|
57
|
+
});
|
|
58
|
+
it('should cap backoff at 30 seconds', () => {
|
|
59
|
+
const repo = createMockRepo();
|
|
60
|
+
const fetcher = new PriceFetcher(mockConfig, repo);
|
|
61
|
+
// Simulate many errors
|
|
62
|
+
for (let i = 0; i < 20; i++) {
|
|
63
|
+
fetcher.recordError();
|
|
64
|
+
}
|
|
65
|
+
expect(fetcher.backoffMs).toBeLessThanOrEqual(30_000);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe('Cache', () => {
|
|
69
|
+
it('should load candle cache from database on construction', () => {
|
|
70
|
+
const repo = createMockRepo();
|
|
71
|
+
repo.getRecentPrices.mockReturnValue([
|
|
72
|
+
{ timestamp: 1000, open: 50000, high: 51000, low: 49000, close: 50500, volume: 100 },
|
|
73
|
+
]);
|
|
74
|
+
const fetcher = new PriceFetcher(mockConfig, repo);
|
|
75
|
+
expect(repo.getRecentPrices).toHaveBeenCalled();
|
|
76
|
+
expect(fetcher.getCandles('bitcoin').length).toBe(1);
|
|
77
|
+
expect(fetcher.getPrice('bitcoin')).toBe(50500);
|
|
78
|
+
});
|
|
79
|
+
it('should return all configured symbols', () => {
|
|
80
|
+
const repo = createMockRepo();
|
|
81
|
+
const fetcher = new PriceFetcher(mockConfig, repo);
|
|
82
|
+
const symbols = fetcher.getAllSymbols();
|
|
83
|
+
expect(symbols).toContain('bitcoin');
|
|
84
|
+
expect(symbols).toContain('AAPL');
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
//# sourceMappingURL=price-fetcher.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"price-fetcher.test.js","sourceRoot":"","sources":["../../../src/paper/__tests__/price-fetcher.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,10 +19,7 @@ export declare class DecisionEngine {
|
|
|
19
19
|
private config;
|
|
20
20
|
private signalService;
|
|
21
21
|
private logger;
|
|
22
|
-
private totalClosedTrades;
|
|
23
22
|
constructor(config: PaperConfig, signalService: SignalService);
|
|
24
|
-
/** Update closed trade count for cold-start logic. */
|
|
25
|
-
setTradeCount(count: number): void;
|
|
26
23
|
/**
|
|
27
24
|
* Detect market regime from indicators.
|
|
28
25
|
*/
|
|
@@ -4,15 +4,10 @@ export class DecisionEngine {
|
|
|
4
4
|
config;
|
|
5
5
|
signalService;
|
|
6
6
|
logger = getLogger();
|
|
7
|
-
totalClosedTrades = 0;
|
|
8
7
|
constructor(config, signalService) {
|
|
9
8
|
this.config = config;
|
|
10
9
|
this.signalService = signalService;
|
|
11
10
|
}
|
|
12
|
-
/** Update closed trade count for cold-start logic. */
|
|
13
|
-
setTradeCount(count) {
|
|
14
|
-
this.totalClosedTrades = count;
|
|
15
|
-
}
|
|
16
11
|
/**
|
|
17
12
|
* Detect market regime from indicators.
|
|
18
13
|
*/
|
|
@@ -112,31 +107,26 @@ export class DecisionEngine {
|
|
|
112
107
|
// Don't enter in bearish regime
|
|
113
108
|
if (regime === 'bearish_trend')
|
|
114
109
|
return false;
|
|
115
|
-
// Cold-start
|
|
116
|
-
const coldStart =
|
|
117
|
-
const confThreshold = coldStart ? 0.
|
|
110
|
+
// Cold-start: when brain has no data, confidence is 0 — use a lower threshold
|
|
111
|
+
const coldStart = confidence === 0;
|
|
112
|
+
const confThreshold = coldStart ? 0.3 : this.config.confidenceThreshold;
|
|
118
113
|
// Confidence threshold
|
|
119
114
|
if (confidence < confThreshold) {
|
|
115
|
+
// Still allow if strong technical signal
|
|
120
116
|
const hasBullishDiv = indicators.rsi14 < 30 && indicators.macd.line > 0;
|
|
121
117
|
const hasStrongTrend = indicators.trendScore > 2 && indicators.volatility < 60;
|
|
122
118
|
if (!hasBullishDiv && !hasStrongTrend)
|
|
123
119
|
return false;
|
|
124
120
|
}
|
|
125
|
-
// Score threshold (
|
|
126
|
-
if (
|
|
121
|
+
// Score threshold (if brain has enough data)
|
|
122
|
+
if (score > 0 && score < this.config.scoreThreshold) {
|
|
123
|
+
// Allow entry if very strong technical signal
|
|
127
124
|
const hasBullishDiv = indicators.rsi14 < 30 && indicators.macd.line > 0;
|
|
128
125
|
if (!hasBullishDiv)
|
|
129
126
|
return false;
|
|
130
127
|
}
|
|
131
128
|
// At least one bullish condition must be true
|
|
132
|
-
|
|
133
|
-
const conditions = coldStart ? [
|
|
134
|
-
indicators.rsi14 < 45 && indicators.macd.line > 0, // Moderate RSI + MACD positive
|
|
135
|
-
indicators.trendScore > 1 && indicators.volatility < 80, // Mild trend, not too volatile
|
|
136
|
-
indicators.rsi14 < 35 && indicators.trendScore > 0, // Low RSI + any uptrend
|
|
137
|
-
indicators.macd.histogram > 0 && indicators.trendScore > 0, // MACD bullish + trend
|
|
138
|
-
indicators.rsi14 < 50 && indicators.trendScore > 2, // Normal RSI + strong trend
|
|
139
|
-
] : [
|
|
129
|
+
const conditions = [
|
|
140
130
|
indicators.rsi14 < 30 && indicators.macd.line > 0, // Bullish divergence
|
|
141
131
|
indicators.trendScore > 2 && indicators.volatility < 60, // Strong trend, low vol
|
|
142
132
|
indicators.rsi14 < 40 && indicators.trendScore > 1, // Low RSI + uptrend
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decision-engine.js","sourceRoot":"","sources":["../../src/paper/decision-engine.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAoB,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAmB/C,MAAM,OAAO,cAAc;
|
|
1
|
+
{"version":3,"file":"decision-engine.js","sourceRoot":"","sources":["../../src/paper/decision-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import type { PaperConfig } from './types.js';
|
|
|
2
2
|
import type { TradeService } from '../services/trade.service.js';
|
|
3
3
|
import type { SignalService } from '../services/signal.service.js';
|
|
4
4
|
import type { PaperRepository } from '../db/repositories/paper.repository.js';
|
|
5
|
+
import type { CrossBrainNotifier } from '@timmeck/brain-core';
|
|
5
6
|
export declare class PaperEngine {
|
|
6
7
|
private config;
|
|
7
8
|
private tradeService;
|
|
@@ -14,7 +15,9 @@ export declare class PaperEngine {
|
|
|
14
15
|
private lastCycleAt;
|
|
15
16
|
private paused;
|
|
16
17
|
private running;
|
|
18
|
+
private cycleInProgress;
|
|
17
19
|
private logger;
|
|
20
|
+
private notifier;
|
|
18
21
|
constructor(config: PaperConfig, tradeService: TradeService, signalService: SignalService, repo: PaperRepository);
|
|
19
22
|
start(): void;
|
|
20
23
|
stop(): void;
|
|
@@ -24,6 +27,7 @@ export declare class PaperEngine {
|
|
|
24
27
|
isRunning(): boolean;
|
|
25
28
|
getCycleCount(): number;
|
|
26
29
|
getLastCycleAt(): string | null;
|
|
30
|
+
setNotifier(notifier: CrossBrainNotifier): void;
|
|
27
31
|
runCycle(): Promise<{
|
|
28
32
|
entries: number;
|
|
29
33
|
exits: number;
|
|
@@ -15,7 +15,9 @@ export class PaperEngine {
|
|
|
15
15
|
lastCycleAt = null;
|
|
16
16
|
paused = false;
|
|
17
17
|
running = false;
|
|
18
|
+
cycleInProgress = false;
|
|
18
19
|
logger = getLogger();
|
|
20
|
+
notifier = null;
|
|
19
21
|
constructor(config, tradeService, signalService, repo) {
|
|
20
22
|
this.config = config;
|
|
21
23
|
this.tradeService = tradeService;
|
|
@@ -71,7 +73,15 @@ export class PaperEngine {
|
|
|
71
73
|
getLastCycleAt() {
|
|
72
74
|
return this.lastCycleAt;
|
|
73
75
|
}
|
|
76
|
+
setNotifier(notifier) {
|
|
77
|
+
this.notifier = notifier;
|
|
78
|
+
}
|
|
74
79
|
async runCycle() {
|
|
80
|
+
if (this.cycleInProgress) {
|
|
81
|
+
this.logger.warn('Paper cycle skipped: previous cycle still in progress');
|
|
82
|
+
return { entries: 0, exits: 0 };
|
|
83
|
+
}
|
|
84
|
+
this.cycleInProgress = true;
|
|
75
85
|
const start = Date.now();
|
|
76
86
|
let entries = 0;
|
|
77
87
|
let exits = 0;
|
|
@@ -90,9 +100,7 @@ export class PaperEngine {
|
|
|
90
100
|
indicatorMap.set(symbol, calcAllIndicators(candles));
|
|
91
101
|
}
|
|
92
102
|
}
|
|
93
|
-
// 3.
|
|
94
|
-
const perf = this.portfolio.getPerformanceSummary();
|
|
95
|
-
this.decision.setTradeCount(perf.totalTrades);
|
|
103
|
+
// 3. Mark-to-market
|
|
96
104
|
this.portfolio.updatePositionPrices(prices);
|
|
97
105
|
// 4. Check exits
|
|
98
106
|
const positions = this.portfolio.getOpenPositions();
|
|
@@ -119,6 +127,14 @@ export class PaperEngine {
|
|
|
119
127
|
catch (err) {
|
|
120
128
|
this.logger.error(`Failed to record paper trade outcome: ${err}`);
|
|
121
129
|
}
|
|
130
|
+
// Notify Brain about closed position
|
|
131
|
+
this.notifier?.notify('position:closed', {
|
|
132
|
+
symbol: closedTrade.symbol,
|
|
133
|
+
pnl: closedTrade.pnlUsdt,
|
|
134
|
+
pnlPct: closedTrade.pnlPct,
|
|
135
|
+
reason: exit.reason,
|
|
136
|
+
summary: `${closedTrade.symbol} closed: ${closedTrade.pnlUsdt >= 0 ? '+' : ''}$${closedTrade.pnlUsdt.toFixed(2)} (${closedTrade.pnlPct >= 0 ? '+' : ''}${closedTrade.pnlPct.toFixed(1)}%)`,
|
|
137
|
+
});
|
|
122
138
|
exits++;
|
|
123
139
|
}
|
|
124
140
|
// 5. Check entries
|
|
@@ -150,9 +166,10 @@ export class PaperEngine {
|
|
|
150
166
|
openedAt: new Date().toISOString(),
|
|
151
167
|
};
|
|
152
168
|
this.portfolio.openPosition(position);
|
|
153
|
-
// Deduct from balance
|
|
169
|
+
// Deduct from balance, compute equity correctly (includes unrealized PnL)
|
|
154
170
|
const { balance } = this.portfolio.getBalance();
|
|
155
|
-
|
|
171
|
+
const newBalance = balance - positionSize;
|
|
172
|
+
this.repo.updateBalance(newBalance, this.portfolio.calcEquity(newBalance), 'open_position');
|
|
156
173
|
entries++;
|
|
157
174
|
}
|
|
158
175
|
}
|
|
@@ -169,6 +186,9 @@ export class PaperEngine {
|
|
|
169
186
|
catch (err) {
|
|
170
187
|
this.logger.error(`Paper cycle error: ${err instanceof Error ? err.message : String(err)}`);
|
|
171
188
|
}
|
|
189
|
+
finally {
|
|
190
|
+
this.cycleInProgress = false;
|
|
191
|
+
}
|
|
172
192
|
return { entries, exits };
|
|
173
193
|
}
|
|
174
194
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paper-engine.js","sourceRoot":"","sources":["../../src/paper/paper-engine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"paper-engine.js","sourceRoot":"","sources":["../../src/paper/paper-engine.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,OAAO,WAAW;IAcZ;IACA;IAEA;IAhBF,YAAY,CAAe;IAC3B,SAAS,CAAmB;IAC5B,QAAQ,CAAiB;IACzB,KAAK,GAA0C,IAAI,CAAC;IACpD,UAAU,GAAG,CAAC,CAAC;IACf,WAAW,GAAkB,IAAI,CAAC;IAClC,MAAM,GAAG,KAAK,CAAC;IACf,OAAO,GAAG,KAAK,CAAC;IAChB,eAAe,GAAG,KAAK,CAAC;IACxB,MAAM,GAAG,SAAS,EAAE,CAAC;IACrB,QAAQ,GAA8B,IAAI,CAAC;IAEnD,YACU,MAAmB,EACnB,YAA0B,EAClC,aAA4B,EACpB,IAAqB;QAHrB,WAAM,GAAN,MAAM,CAAa;QACnB,iBAAY,GAAZ,YAAY,CAAc;QAE1B,SAAI,GAAJ,IAAI,CAAiB;QAE7B,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,SAAS,GAAG,IAAI,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YAClD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,2CAA2C,IAAI,CAAC,MAAM,CAAC,UAAU,iBAAiB,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,CAAC,CAAC;QAEnI,iCAAiC;QACjC,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,IAAI,CAAC,OAAO;gBAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7G,CAAC,EAAE,MAAM,CAAC,CAAC;QAEX,mBAAmB;QACnB,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjC,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3F,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI;QACF,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACnD,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAClD,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACnD,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,WAAW,CAAC,QAA4B;QACtC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;YAC1E,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAClC,CAAC;QAED,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,IAAI,CAAC;YACH,kBAAkB;YAClB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YAElD,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;gBACrD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YAClC,CAAC;YAED,0CAA0C;YAC1C,MAAM,YAAY,GAAG,IAAI,GAAG,EAAgD,CAAC;YAC7E,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,EAAE,CAAC;gBACvD,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;gBACrD,IAAI,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;oBACzB,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC;YAED,oBAAoB;YACpB,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;YAE5C,iBAAiB;YACjB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC;YACpD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YAEhE,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;gBAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;gBAEhG,kCAAkC;gBAClC,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;oBACpD,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC;wBAC9B,OAAO,EAAE;4BACP,KAAK,EAAE,OAAO,CAAC,KAAK;4BACpB,IAAI,EAAE,OAAO,CAAC,IAAI;4BAClB,UAAU,EAAE,OAAO,CAAC,UAAU;4BAC9B,UAAU,EAAE,OAAO,CAAC,UAAU;yBAC/B;wBACD,MAAM,EAAE,WAAW,CAAC,MAAM;wBAC1B,SAAS,EAAE,WAAW,CAAC,MAAM;wBAC7B,GAAG,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC;wBAC3B,OAAO,EAAE,cAAc;wBACvB,IAAI,EAAE,GAAG,WAAW,CAAC,MAAM,OAAO;qBACnC,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,GAAG,EAAE,CAAC,CAAC;gBACpE,CAAC;gBAED,qCAAqC;gBACrC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,iBAAiB,EAAE;oBACvC,MAAM,EAAE,WAAW,CAAC,MAAM;oBAC1B,GAAG,EAAE,WAAW,CAAC,OAAO;oBACxB,MAAM,EAAE,WAAW,CAAC,MAAM;oBAC1B,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,OAAO,EAAE,GAAG,WAAW,CAAC,MAAM,YAAY,WAAW,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;iBAC3L,CAAC,CAAC;gBAEH,KAAK,EAAE,CAAC;YACV,CAAC;YAED,mBAAmB;YACnB,IAAI,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,EAAE,CAAC;gBACrC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC1D,uCAAuC;gBACvC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;oBAC/B,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAC3C,CAAC;gBAED,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAC7C,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,EACjC,MAAM,EACN,YAAY,EACZ,WAAW,CACZ,CAAC;gBAEF,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;oBACjC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE;wBAAE,MAAM;oBAE7C,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC;oBACvD,MAAM,QAAQ,GAAG,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC;oBAE5C,MAAM,QAAQ,GAAkB;wBAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,IAAI,EAAE,MAAM;wBACZ,UAAU,EAAE,KAAK,CAAC,KAAK;wBACvB,QAAQ;wBACR,UAAU,EAAE,YAAY;wBACxB,YAAY,EAAE,KAAK,CAAC,KAAK;wBACzB,MAAM,EAAE,CAAC;wBACT,aAAa,EAAE,KAAK,CAAC,KAAK;wBAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;wBAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;wBAC9B,UAAU,EAAE,KAAK,CAAC,UAAU;wBAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;qBACnC,CAAC;oBAEF,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;oBAEtC,0EAA0E;oBAC1E,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;oBAChD,MAAM,UAAU,GAAG,OAAO,GAAG,YAAY,CAAC;oBAC1C,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC,CAAC;oBAE5F,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC;YAED,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAE5C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YACnC,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,UAAU,KAAK,OAAO,aAAa,KAAK,WAAW,OAAO,KAAK,CAAC,CAAC;YACzG,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,UAAU,gBAAgB,OAAO,KAAK,CAAC,CAAC;YACjF,CAAC;QAEH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9F,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC/B,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;CACF"}
|
|
@@ -19,7 +19,9 @@ export class PaperService {
|
|
|
19
19
|
lastCycleAt: this.engine.getLastCycleAt(),
|
|
20
20
|
balance,
|
|
21
21
|
equity,
|
|
22
|
+
startingBalance: this.config.startingBalance,
|
|
22
23
|
openPositions: this.repo.countPositions(),
|
|
24
|
+
closedTrades: wr.total,
|
|
23
25
|
totalTrades: wr.total,
|
|
24
26
|
winRate: Math.round(wr.rate * 100),
|
|
25
27
|
totalPnl,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paper.service.js","sourceRoot":"","sources":["../../src/paper/paper.service.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,YAAY;IAEb;IACA;IACA;IAHV,YACU,MAAmB,EACnB,IAAqB,EACrB,MAAmB;QAFnB,WAAM,GAAN,MAAM,CAAa;QACnB,SAAI,GAAJ,IAAI,CAAiB;QACrB,WAAM,GAAN,MAAM,CAAa;IAC1B,CAAC;IAEJ,SAAS;QACP,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACnD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAEzC,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE;YAChC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;YAC9B,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE;YACvC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE;YACzC,OAAO;YACP,MAAM;YACN,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;YACzC,WAAW,EAAE,EAAE,CAAC,KAAK;YACrB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC;YAClC,QAAQ;YACR,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM;SACxE,CAAC;IACJ,CAAC;IAED,YAAY;QACV,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACnD,OAAO;YACL,OAAO;YACP,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;SACxC,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,QAAgB,EAAE;QAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;IAChC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACrB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAC7C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;IACjE,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"paper.service.js","sourceRoot":"","sources":["../../src/paper/paper.service.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,YAAY;IAEb;IACA;IACA;IAHV,YACU,MAAmB,EACnB,IAAqB,EACrB,MAAmB;QAFnB,WAAM,GAAN,MAAM,CAAa;QACnB,SAAI,GAAJ,IAAI,CAAiB;QACrB,WAAM,GAAN,MAAM,CAAa;IAC1B,CAAC;IAEJ,SAAS;QACP,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACnD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAEzC,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE;YAChC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;YAC9B,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE;YACvC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE;YACzC,OAAO;YACP,MAAM;YACN,eAAe,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe;YAC5C,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;YACzC,YAAY,EAAE,EAAE,CAAC,KAAK;YACtB,WAAW,EAAE,EAAE,CAAC,KAAK;YACrB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC;YAClC,QAAQ;YACR,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM;SACxE,CAAC;IACJ,CAAC;IAED,YAAY;QACV,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACnD,OAAO;YACL,OAAO;YACP,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;SACxC,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,QAAgB,EAAE;QAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;IAChC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACrB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAC7C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;IACjE,CAAC;CACF"}
|
|
@@ -58,9 +58,9 @@ export class PortfolioManager {
|
|
|
58
58
|
if (position.id) {
|
|
59
59
|
this.repo.deletePosition(position.id);
|
|
60
60
|
}
|
|
61
|
-
// Update balance
|
|
61
|
+
// Update balance: return principal + profit/loss
|
|
62
62
|
const { balance } = this.repo.getBalance();
|
|
63
|
-
const newBalance = balance + pnlUsdt;
|
|
63
|
+
const newBalance = balance + position.usdtAmount + pnlUsdt;
|
|
64
64
|
this.repo.updateBalance(newBalance, this.calcEquity(newBalance), `close_${exitReason}`);
|
|
65
65
|
this.logger.info(`Paper CLOSE: ${position.symbol} @ ${exitPrice.toFixed(4)} | ${exitReason} | PnL: ${pnlPct >= 0 ? '+' : ''}${pnlPct.toFixed(2)}% ($${pnlUsdt.toFixed(2)})`);
|
|
66
66
|
return trade;
|
|
@@ -102,12 +102,12 @@ export class PortfolioManager {
|
|
|
102
102
|
}
|
|
103
103
|
calcEquity(balance) {
|
|
104
104
|
const positions = this.repo.getOpenPositions();
|
|
105
|
-
let
|
|
105
|
+
let positionValue = 0;
|
|
106
106
|
for (const pos of positions) {
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
// Position value = principal + unrealized P&L
|
|
108
|
+
positionValue += pos.usdtAmount * (1 + pos.pnlPct / 100);
|
|
109
109
|
}
|
|
110
|
-
return balance +
|
|
110
|
+
return balance + positionValue;
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
//# sourceMappingURL=portfolio-manager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portfolio-manager.js","sourceRoot":"","sources":["../../src/paper/portfolio-manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,OAAO,gBAAgB;IAIjB;IACA;IAJF,MAAM,GAAG,SAAS,EAAE,CAAC;IAE7B,YACU,MAAmB,EACnB,IAAqB;QADrB,WAAM,GAAN,MAAM,CAAa;QACnB,SAAI,GAAJ,IAAI,CAAiB;IAC5B,CAAC;IAEJ,UAAU;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;IAChC,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACtC,CAAC;IAED,WAAW,CAAC,MAAc;QACxB,OAAO,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC;IAC7D,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QAC1C,OAAO,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,GAAG,GAAG,CAAC,CAAC;IACrD,CAAC;IAED,YAAY,CAAC,GAAkB;QAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACtI,OAAO,KAAK,CAAC;IACf,CAAC;IAED,aAAa,CAAC,QAAuB,EAAE,SAAiB,EAAE,UAAkB;QAC1E,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC;QAC/E,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;QAErD,MAAM,KAAK,GAAqB;YAC9B,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,SAAS;YACT,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,OAAO;YACP,MAAM;YACN,UAAU;YACV,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACnC,CAAC;QAEF,eAAe;QACf,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC7C,KAAK,CAAC,EAAE,GAAG,OAAO,CAAC;QAEnB,kBAAkB;QAClB,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACxC,CAAC;QAED,
|
|
1
|
+
{"version":3,"file":"portfolio-manager.js","sourceRoot":"","sources":["../../src/paper/portfolio-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,9 @@ export declare class PriceFetcher {
|
|
|
8
8
|
private lastOHLCVFetch;
|
|
9
9
|
private readonly OHLCV_INTERVAL;
|
|
10
10
|
private logger;
|
|
11
|
+
private consecutiveErrors;
|
|
12
|
+
private readonly MAX_CONSECUTIVE_ERRORS;
|
|
13
|
+
private backoffMs;
|
|
11
14
|
constructor(config: PaperConfig, repo: PaperRepository);
|
|
12
15
|
/**
|
|
13
16
|
* Fetch all prices (current spot + OHLCV if stale).
|
|
@@ -20,5 +23,8 @@ export declare class PriceFetcher {
|
|
|
20
23
|
private fetchStockPrices;
|
|
21
24
|
private fetchOHLCVData;
|
|
22
25
|
private mergeCandles;
|
|
26
|
+
private delay;
|
|
27
|
+
private recordError;
|
|
28
|
+
private recordSuccess;
|
|
23
29
|
private loadCacheFromDb;
|
|
24
30
|
}
|
|
@@ -7,6 +7,10 @@ export class PriceFetcher {
|
|
|
7
7
|
lastOHLCVFetch = 0;
|
|
8
8
|
OHLCV_INTERVAL = 900_000; // 15 minutes
|
|
9
9
|
logger = getLogger();
|
|
10
|
+
// Rate limiting
|
|
11
|
+
consecutiveErrors = 0;
|
|
12
|
+
MAX_CONSECUTIVE_ERRORS = 5;
|
|
13
|
+
backoffMs = 0;
|
|
10
14
|
constructor(config, repo) {
|
|
11
15
|
this.config = config;
|
|
12
16
|
this.repo = repo;
|
|
@@ -42,11 +46,14 @@ export class PriceFetcher {
|
|
|
42
46
|
async fetchCryptoPrices() {
|
|
43
47
|
if (this.config.cryptoIds.length === 0)
|
|
44
48
|
return;
|
|
49
|
+
if (this.backoffMs > 0)
|
|
50
|
+
await this.delay(this.backoffMs);
|
|
45
51
|
try {
|
|
46
52
|
const ids = this.config.cryptoIds.join(',');
|
|
47
53
|
const url = `https://api.coingecko.com/api/v3/simple/price?ids=${ids}&vs_currencies=usd`;
|
|
48
54
|
const response = await fetch(url);
|
|
49
55
|
if (!response.ok) {
|
|
56
|
+
this.recordError();
|
|
50
57
|
this.logger.warn(`CoinGecko price fetch failed: ${response.status}`);
|
|
51
58
|
return;
|
|
52
59
|
}
|
|
@@ -56,23 +63,30 @@ export class PriceFetcher {
|
|
|
56
63
|
this.priceCache.set(id, priceData.usd);
|
|
57
64
|
}
|
|
58
65
|
}
|
|
66
|
+
this.recordSuccess();
|
|
59
67
|
this.logger.debug(`Fetched ${Object.keys(data).length} crypto prices`);
|
|
60
68
|
}
|
|
61
69
|
catch (err) {
|
|
70
|
+
this.recordError();
|
|
62
71
|
this.logger.warn(`CoinGecko price error: ${err instanceof Error ? err.message : String(err)}`);
|
|
63
72
|
}
|
|
64
73
|
}
|
|
65
74
|
async fetchStockPrices() {
|
|
66
75
|
if (this.config.stockSymbols.length === 0)
|
|
67
76
|
return;
|
|
77
|
+
if (this.backoffMs > 0)
|
|
78
|
+
await this.delay(this.backoffMs);
|
|
68
79
|
for (const symbol of this.config.stockSymbols) {
|
|
69
80
|
try {
|
|
81
|
+
// Rate limit: 500ms between Yahoo calls
|
|
82
|
+
await this.delay(500);
|
|
70
83
|
const url = `https://query1.finance.yahoo.com/v8/finance/chart/${symbol}?range=1d&interval=5m`;
|
|
71
84
|
const response = await fetch(url, {
|
|
72
85
|
headers: { 'User-Agent': 'TradingBrain/1.0' },
|
|
73
86
|
});
|
|
74
87
|
if (!response.ok) {
|
|
75
|
-
this.
|
|
88
|
+
this.recordError();
|
|
89
|
+
this.logger.warn(`Yahoo Finance ${symbol}: ${response.status}`);
|
|
76
90
|
continue;
|
|
77
91
|
}
|
|
78
92
|
const data = await response.json();
|
|
@@ -88,21 +102,30 @@ export class PriceFetcher {
|
|
|
88
102
|
}
|
|
89
103
|
}
|
|
90
104
|
}
|
|
105
|
+
this.recordSuccess();
|
|
91
106
|
}
|
|
92
107
|
catch (err) {
|
|
93
|
-
this.
|
|
108
|
+
this.recordError();
|
|
109
|
+
this.logger.warn(`Yahoo ${symbol} error: ${err instanceof Error ? err.message : String(err)}`);
|
|
94
110
|
}
|
|
95
111
|
}
|
|
96
112
|
this.logger.debug(`Fetched stock prices for ${this.config.stockSymbols.length} symbols`);
|
|
97
113
|
}
|
|
98
114
|
async fetchOHLCVData() {
|
|
115
|
+
if (this.backoffMs > 0)
|
|
116
|
+
await this.delay(this.backoffMs);
|
|
99
117
|
// Crypto OHLCV from CoinGecko
|
|
100
118
|
for (const id of this.config.cryptoIds) {
|
|
101
119
|
try {
|
|
120
|
+
// Rate limit: 1.5s between CoinGecko OHLCV calls
|
|
121
|
+
await this.delay(1500);
|
|
102
122
|
const url = `https://api.coingecko.com/api/v3/coins/${id}/ohlc?vs_currency=usd&days=1`;
|
|
103
123
|
const response = await fetch(url);
|
|
104
|
-
if (!response.ok)
|
|
124
|
+
if (!response.ok) {
|
|
125
|
+
this.recordError();
|
|
126
|
+
this.logger.warn(`CoinGecko OHLCV ${id}: ${response.status}`);
|
|
105
127
|
continue;
|
|
128
|
+
}
|
|
106
129
|
const data = await response.json();
|
|
107
130
|
if (!Array.isArray(data))
|
|
108
131
|
continue;
|
|
@@ -118,20 +141,27 @@ export class PriceFetcher {
|
|
|
118
141
|
this.candleCache.set(id, this.mergeCandles(id, candles));
|
|
119
142
|
this.repo.savePrices(id, candles);
|
|
120
143
|
}
|
|
144
|
+
this.recordSuccess();
|
|
121
145
|
}
|
|
122
|
-
catch {
|
|
123
|
-
|
|
146
|
+
catch (err) {
|
|
147
|
+
this.recordError();
|
|
148
|
+
this.logger.warn(`CoinGecko OHLCV ${id} error: ${err instanceof Error ? err.message : String(err)}`);
|
|
124
149
|
}
|
|
125
150
|
}
|
|
126
151
|
// Stock OHLCV from Yahoo
|
|
127
152
|
for (const symbol of this.config.stockSymbols) {
|
|
128
153
|
try {
|
|
154
|
+
// Rate limit: 500ms between Yahoo calls
|
|
155
|
+
await this.delay(500);
|
|
129
156
|
const url = `https://query1.finance.yahoo.com/v8/finance/chart/${symbol}?range=5d&interval=5m`;
|
|
130
157
|
const response = await fetch(url, {
|
|
131
158
|
headers: { 'User-Agent': 'TradingBrain/1.0' },
|
|
132
159
|
});
|
|
133
|
-
if (!response.ok)
|
|
160
|
+
if (!response.ok) {
|
|
161
|
+
this.recordError();
|
|
162
|
+
this.logger.warn(`Yahoo OHLCV ${symbol}: ${response.status}`);
|
|
134
163
|
continue;
|
|
164
|
+
}
|
|
135
165
|
const data = await response.json();
|
|
136
166
|
const result = data?.chart?.result?.[0];
|
|
137
167
|
if (!result?.timestamp)
|
|
@@ -157,9 +187,11 @@ export class PriceFetcher {
|
|
|
157
187
|
this.candleCache.set(symbol, this.mergeCandles(symbol, candles));
|
|
158
188
|
this.repo.savePrices(symbol, candles);
|
|
159
189
|
}
|
|
190
|
+
this.recordSuccess();
|
|
160
191
|
}
|
|
161
|
-
catch {
|
|
162
|
-
|
|
192
|
+
catch (err) {
|
|
193
|
+
this.recordError();
|
|
194
|
+
this.logger.warn(`Yahoo OHLCV ${symbol} error: ${err instanceof Error ? err.message : String(err)}`);
|
|
163
195
|
}
|
|
164
196
|
}
|
|
165
197
|
// Prune old cache
|
|
@@ -175,6 +207,20 @@ export class PriceFetcher {
|
|
|
175
207
|
// Keep last 500 candles
|
|
176
208
|
return merged.slice(-500);
|
|
177
209
|
}
|
|
210
|
+
delay(ms) {
|
|
211
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
212
|
+
}
|
|
213
|
+
recordError() {
|
|
214
|
+
this.consecutiveErrors++;
|
|
215
|
+
if (this.consecutiveErrors >= this.MAX_CONSECUTIVE_ERRORS) {
|
|
216
|
+
this.backoffMs = Math.min(30_000, 2_000 * Math.pow(2, this.consecutiveErrors - this.MAX_CONSECUTIVE_ERRORS));
|
|
217
|
+
this.logger.warn(`API rate limit backoff: ${this.backoffMs}ms after ${this.consecutiveErrors} consecutive errors`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
recordSuccess() {
|
|
221
|
+
this.consecutiveErrors = 0;
|
|
222
|
+
this.backoffMs = 0;
|
|
223
|
+
}
|
|
178
224
|
loadCacheFromDb() {
|
|
179
225
|
const allSymbols = this.getAllSymbols();
|
|
180
226
|
for (const symbol of allSymbols) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"price-fetcher.js","sourceRoot":"","sources":["../../src/paper/price-fetcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAuB/C,MAAM,OAAO,YAAY;
|
|
1
|
+
{"version":3,"file":"price-fetcher.js","sourceRoot":"","sources":["../../src/paper/price-fetcher.ts"],"names":[],"mappings":"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"}
|
package/dist/paper/types.d.ts
CHANGED