@backtest-kit/signals 0.0.1 → 0.0.3
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/README.md +1 -0
- package/build/index.cjs +2055 -5
- package/build/index.mjs +2055 -5
- package/package.json +16 -11
- package/types.d.ts +1512 -0
package/build/index.mjs
CHANGED
|
@@ -3,31 +3,97 @@ import { getCandles, getDate, formatPrice, formatQuantity, getOrderBook, Cache,
|
|
|
3
3
|
import { createActivator } from 'di-kit';
|
|
4
4
|
import { trycatch, str } from 'functools-kit';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Dependency injection container for signals library.
|
|
8
|
+
*
|
|
9
|
+
* Creates an isolated DI container using di-kit for managing service instances.
|
|
10
|
+
* Provides methods for dependency registration, injection, and initialization.
|
|
11
|
+
*
|
|
12
|
+
* @module lib/core/di
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* DI container exports for signals library.
|
|
16
|
+
*
|
|
17
|
+
* - provide: Register service factory in DI container
|
|
18
|
+
* - inject: Retrieve service instance from container
|
|
19
|
+
* - init: Initialize all registered services
|
|
20
|
+
* - override: Replace existing service registration
|
|
21
|
+
*/
|
|
6
22
|
const { provide, inject, init, override } = createActivator("signal");
|
|
7
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Dependency injection type symbols for signals library.
|
|
26
|
+
*
|
|
27
|
+
* Defines unique symbols for service registration and retrieval in the DI container.
|
|
28
|
+
* Organized by service category: common, math, and history services.
|
|
29
|
+
*
|
|
30
|
+
* @module lib/core/types
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* Common service symbols.
|
|
34
|
+
*/
|
|
8
35
|
const commonServices$1 = {
|
|
36
|
+
/** Logger service for diagnostic output */
|
|
9
37
|
loggerService: Symbol("loggerService"),
|
|
10
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* Technical analysis service symbols.
|
|
41
|
+
*/
|
|
11
42
|
const mathServices$1 = {
|
|
43
|
+
/** 1-hour (LongTerm) technical analysis service */
|
|
12
44
|
longTermMathService: Symbol('longTermMathService'),
|
|
45
|
+
/** 30-minute (SwingTerm) technical analysis service */
|
|
13
46
|
swingTermMathService: Symbol('swingTermMathService'),
|
|
47
|
+
/** 15-minute (ShortTerm) technical analysis service */
|
|
14
48
|
shortTermMathService: Symbol('shortTermMathService'),
|
|
49
|
+
/** 1-minute (MicroTerm) technical analysis service */
|
|
15
50
|
microTermMathService: Symbol('microTermMathService'),
|
|
51
|
+
/** Order book analysis service */
|
|
16
52
|
bookDataMathService: Symbol('bookDataMathService'),
|
|
17
53
|
};
|
|
54
|
+
/**
|
|
55
|
+
* Candle history service symbols.
|
|
56
|
+
*/
|
|
18
57
|
const historyServices$1 = {
|
|
58
|
+
/** 15-minute candle history service */
|
|
19
59
|
fifteenMinuteCandleHistoryService: Symbol('fifteenMinuteCandleHistoryService'),
|
|
60
|
+
/** 1-hour candle history service */
|
|
20
61
|
hourCandleHistoryService: Symbol('hourCandleHistoryService'),
|
|
62
|
+
/** 1-minute candle history service */
|
|
21
63
|
oneMinuteCandleHistoryService: Symbol('oneMinuteCandleHistoryService'),
|
|
64
|
+
/** 30-minute candle history service */
|
|
22
65
|
thirtyMinuteCandleHistoryService: Symbol('thirtyMinuteCandleHistoryService'),
|
|
23
66
|
};
|
|
67
|
+
/**
|
|
68
|
+
* All service type symbols combined.
|
|
69
|
+
*/
|
|
24
70
|
const TYPES = {
|
|
25
71
|
...commonServices$1,
|
|
26
72
|
...mathServices$1,
|
|
27
73
|
...historyServices$1,
|
|
28
74
|
};
|
|
29
75
|
|
|
76
|
+
/**
|
|
77
|
+
* LongTerm (1-hour) technical analysis service for trend trading.
|
|
78
|
+
*
|
|
79
|
+
* Generates 30+ indicators on 1-hour candles with 48-candle lookback (48 hours).
|
|
80
|
+
* Optimized for multi-day trend trading and position management.
|
|
81
|
+
*
|
|
82
|
+
* Indicators: RSI(14), StochRSI(14), MACD(12,26,9), Bollinger(20,2), Stochastic(14,3,3),
|
|
83
|
+
* ADX(14), ATR(14,20), CCI(20), Momentum(10), SMA(50), EMA(20,34), DEMA(21), WMA(20),
|
|
84
|
+
* Support/Resistance, Fibonacci levels, Volume trends.
|
|
85
|
+
*
|
|
86
|
+
* Used by commitLongTermMath().
|
|
87
|
+
*/
|
|
88
|
+
/**
|
|
89
|
+
* Maximum number of historical rows to return in analysis results.
|
|
90
|
+
* Limits memory usage and table size for markdown reports.
|
|
91
|
+
*/
|
|
30
92
|
const TABLE_ROWS_LIMIT$3 = 48;
|
|
93
|
+
/**
|
|
94
|
+
* Minimum number of candles required before generating analysis rows.
|
|
95
|
+
* Ensures all technical indicators (especially SMA(50)) have sufficient data.
|
|
96
|
+
*/
|
|
31
97
|
const WARMUP_PERIOD$3 = 50;
|
|
32
98
|
const columns$3 = [
|
|
33
99
|
{
|
|
@@ -212,6 +278,23 @@ const columns$3 = [
|
|
|
212
278
|
format: (v) => new Date(v).toISOString(),
|
|
213
279
|
},
|
|
214
280
|
];
|
|
281
|
+
/**
|
|
282
|
+
* Validates whether a numeric value is safe for calculations.
|
|
283
|
+
*
|
|
284
|
+
* Checks if value is a valid finite number. Returns true if value is null,
|
|
285
|
+
* NaN, Infinity, or not a number type.
|
|
286
|
+
*
|
|
287
|
+
* @param value - Value to validate
|
|
288
|
+
* @returns True if value is unsafe (null/NaN/Infinity), false if valid number
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* ```typescript
|
|
292
|
+
* isUnsafe(42) // false - valid number
|
|
293
|
+
* isUnsafe(null) // true - null value
|
|
294
|
+
* isUnsafe(NaN) // true - not a number
|
|
295
|
+
* isUnsafe(Infinity) // true - infinite value
|
|
296
|
+
* ```
|
|
297
|
+
*/
|
|
215
298
|
function isUnsafe$4(value) {
|
|
216
299
|
if (typeof value !== "number") {
|
|
217
300
|
return true;
|
|
@@ -224,6 +307,25 @@ function isUnsafe$4(value) {
|
|
|
224
307
|
}
|
|
225
308
|
return false;
|
|
226
309
|
}
|
|
310
|
+
/**
|
|
311
|
+
* Calculates Fibonacci retracement levels and finds nearest level to current price.
|
|
312
|
+
*
|
|
313
|
+
* Computes standard Fibonacci levels (0%, 23.6%, 38.2%, 50%, 61.8%, 78.6%, 100%)
|
|
314
|
+
* plus extension levels (127.2%, 161.8%) based on high-low range over lookback period.
|
|
315
|
+
* Returns the level closest to current price with distance in USD.
|
|
316
|
+
*
|
|
317
|
+
* @param candles - Array of candle data
|
|
318
|
+
* @param endIndex - Index of current candle in array
|
|
319
|
+
* @returns Object with nearest level name, price, and distance in USD
|
|
320
|
+
*
|
|
321
|
+
* @example
|
|
322
|
+
* ```typescript
|
|
323
|
+
* const candles = await getCandles('BTCUSDT', '1h', 100);
|
|
324
|
+
* const fib = calculateFibonacciLevels(candles, 99);
|
|
325
|
+
* console.log(fib);
|
|
326
|
+
* // { level: "61.8%", price: 42500.50, distance: 125.30 }
|
|
327
|
+
* ```
|
|
328
|
+
*/
|
|
227
329
|
function calculateFibonacciLevels$2(candles, endIndex) {
|
|
228
330
|
const lookbackPeriod = Math.min(24, endIndex + 1);
|
|
229
331
|
const startIndex = endIndex + 1 - lookbackPeriod;
|
|
@@ -256,6 +358,31 @@ function calculateFibonacciLevels$2(candles, endIndex) {
|
|
|
256
358
|
});
|
|
257
359
|
return nearestLevel;
|
|
258
360
|
}
|
|
361
|
+
/**
|
|
362
|
+
* Generates comprehensive technical analysis for 1-hour candles (long-term trading).
|
|
363
|
+
*
|
|
364
|
+
* Calculates 30+ technical indicators per candle including:
|
|
365
|
+
* - Momentum: RSI(14), Stochastic RSI(14), MACD(12,26,9), Momentum(10)
|
|
366
|
+
* - Trend: SMA(50), EMA(20,34), DEMA(21), WMA(20), ADX(14), +DI/-DI
|
|
367
|
+
* - Volatility: ATR(14,20), Bollinger Bands(20,2.0), CCI(20)
|
|
368
|
+
* - Volume: Volume trend analysis
|
|
369
|
+
* - Support/Resistance: Pivot points, Fibonacci levels
|
|
370
|
+
*
|
|
371
|
+
* Skips first WARMUP_PERIOD (50) candles to ensure indicator stability.
|
|
372
|
+
* Returns last TABLE_ROWS_LIMIT (48) rows for memory efficiency.
|
|
373
|
+
*
|
|
374
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
375
|
+
* @param candles - Array of 1-hour candle data
|
|
376
|
+
* @returns Array of technical analysis rows with all indicators
|
|
377
|
+
*
|
|
378
|
+
* @example
|
|
379
|
+
* ```typescript
|
|
380
|
+
* const candles = await getCandles('BTCUSDT', '1h', 100);
|
|
381
|
+
* const analysis = generateAnalysis('BTCUSDT', candles);
|
|
382
|
+
* console.log(analysis[0].rsi14); // 52.45
|
|
383
|
+
* console.log(analysis[0].support); // 42000.50
|
|
384
|
+
* ```
|
|
385
|
+
*/
|
|
259
386
|
function generateAnalysis$3(symbol, candles) {
|
|
260
387
|
const closes = candles.map((candle) => Number(candle.close));
|
|
261
388
|
const highs = candles.map((candle) => Number(candle.high));
|
|
@@ -437,6 +564,32 @@ function generateAnalysis$3(symbol, candles) {
|
|
|
437
564
|
});
|
|
438
565
|
return results;
|
|
439
566
|
}
|
|
567
|
+
/**
|
|
568
|
+
* Generates markdown table with long-term technical analysis history.
|
|
569
|
+
*
|
|
570
|
+
* Creates comprehensive markdown report with:
|
|
571
|
+
* - Formatted table of all technical indicators
|
|
572
|
+
* - Column headers with indicator names and parameters
|
|
573
|
+
* - Formatted values (prices in USD, percentages, decimals)
|
|
574
|
+
* - Data sources section explaining each indicator's calculation
|
|
575
|
+
* - Timeframe and lookback period documentation (1h candles, 48h lookback)
|
|
576
|
+
*
|
|
577
|
+
* Output is optimized for LLM consumption in long-term trading signal generation.
|
|
578
|
+
*
|
|
579
|
+
* @param indicators - Array of analysis rows from generateAnalysis()
|
|
580
|
+
* @param symbol - Trading pair symbol for price formatting
|
|
581
|
+
* @returns Markdown-formatted technical analysis report
|
|
582
|
+
*
|
|
583
|
+
* @example
|
|
584
|
+
* ```typescript
|
|
585
|
+
* const rows = await service.getData('BTCUSDT', candles);
|
|
586
|
+
* const markdown = await generateHistoryTable(rows, 'BTCUSDT');
|
|
587
|
+
* console.log(markdown);
|
|
588
|
+
* // # 1-Hour Candles Trading Analysis for BTCUSDT (Historical Data)
|
|
589
|
+
* // > Current time: 2025-01-14T10:30:00.000Z
|
|
590
|
+
* // | RSI(14) | MACD(12,26,9) | Support Level | ... |
|
|
591
|
+
* ```
|
|
592
|
+
*/
|
|
440
593
|
async function generateHistoryTable$3(indicators, symbol) {
|
|
441
594
|
let markdown = "";
|
|
442
595
|
const currentData = await getDate();
|
|
@@ -517,9 +670,61 @@ async function generateHistoryTable$3(indicators, symbol) {
|
|
|
517
670
|
"- **Close Price**: close price at row timestamp (Min: 0 USD, Max: +∞ USD)\n";
|
|
518
671
|
return markdown;
|
|
519
672
|
}
|
|
673
|
+
/**
|
|
674
|
+
* Service for long-term (1-hour) technical analysis and markdown report generation.
|
|
675
|
+
*
|
|
676
|
+
* Provides comprehensive technical analysis for 1-hour candles with 30+ indicators
|
|
677
|
+
* including momentum (RSI, MACD), trend (EMA, SMA), volatility (ATR, Bollinger Bands),
|
|
678
|
+
* support/resistance levels, and Fibonacci retracements.
|
|
679
|
+
*
|
|
680
|
+
* Key features:
|
|
681
|
+
* - 30+ technical indicators (RSI, MACD, Bollinger Bands, Stochastic, ADX, etc.)
|
|
682
|
+
* - Support/resistance level detection
|
|
683
|
+
* - Fibonacci retracement analysis
|
|
684
|
+
* - Volume trend analysis
|
|
685
|
+
* - Markdown table generation for LLM consumption
|
|
686
|
+
* - Intelligent indicator warmup (skips first 50 candles)
|
|
687
|
+
* - Memory-efficient output (last 48 rows only)
|
|
688
|
+
* - Dependency injection support
|
|
689
|
+
*
|
|
690
|
+
* @example
|
|
691
|
+
* ```typescript
|
|
692
|
+
* import { LongTermHistoryService } from '@backtest-kit/signals';
|
|
693
|
+
*
|
|
694
|
+
* const service = new LongTermHistoryService();
|
|
695
|
+
*
|
|
696
|
+
* // Get markdown report for symbol (fetches candles internally)
|
|
697
|
+
* const report = await service.getReport('BTCUSDT');
|
|
698
|
+
* console.log(report); // Markdown table with all indicators
|
|
699
|
+
*
|
|
700
|
+
* // Or analyze custom candles
|
|
701
|
+
* const candles = await getCandles('ETHUSDT', '1h', 100);
|
|
702
|
+
* const rows = await service.getData('ETHUSDT', candles);
|
|
703
|
+
* console.log(rows[0].rsi14); // 52.45
|
|
704
|
+
* ```
|
|
705
|
+
*/
|
|
520
706
|
class LongTermHistoryService {
|
|
521
707
|
constructor() {
|
|
522
708
|
this.loggerService = inject(TYPES.loggerService);
|
|
709
|
+
/**
|
|
710
|
+
* Analyzes candle data and returns technical indicator rows.
|
|
711
|
+
*
|
|
712
|
+
* Calculates all technical indicators for provided candles, skips first WARMUP_PERIOD
|
|
713
|
+
* rows to ensure stability, and returns last TABLE_ROWS_LIMIT rows.
|
|
714
|
+
*
|
|
715
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
716
|
+
* @param candles - Array of 1-hour candle data
|
|
717
|
+
* @returns Array of technical analysis rows with all indicators
|
|
718
|
+
*
|
|
719
|
+
* @example
|
|
720
|
+
* ```typescript
|
|
721
|
+
* const candles = await getCandles('BTCUSDT', '1h', 100);
|
|
722
|
+
* const rows = await service.getData('BTCUSDT', candles);
|
|
723
|
+
* console.log(rows.length); // Up to 48 rows
|
|
724
|
+
* console.log(rows[0].rsi14); // 52.45
|
|
725
|
+
* console.log(rows[0].support); // 42000.50
|
|
726
|
+
* ```
|
|
727
|
+
*/
|
|
523
728
|
this.getData = async (symbol, candles) => {
|
|
524
729
|
this.loggerService.log("longTermHistoryService getData", {
|
|
525
730
|
symbol,
|
|
@@ -527,6 +732,26 @@ class LongTermHistoryService {
|
|
|
527
732
|
});
|
|
528
733
|
return generateAnalysis$3(symbol, candles);
|
|
529
734
|
};
|
|
735
|
+
/**
|
|
736
|
+
* Generates complete markdown technical analysis report for a symbol.
|
|
737
|
+
*
|
|
738
|
+
* Fetches 100 1-hour candles (100 hours) from exchange, calculates all indicators,
|
|
739
|
+
* and formats last 48 rows as markdown table optimized for LLM consumption.
|
|
740
|
+
*
|
|
741
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
742
|
+
* @returns Markdown-formatted technical analysis report with table and explanations
|
|
743
|
+
*
|
|
744
|
+
* @example
|
|
745
|
+
* ```typescript
|
|
746
|
+
* const report = await service.getReport('BTCUSDT');
|
|
747
|
+
* console.log(report);
|
|
748
|
+
* // # 1-Hour Candles Trading Analysis for BTCUSDT (Historical Data)
|
|
749
|
+
* // > Current time: 2025-01-14T10:30:00.000Z
|
|
750
|
+
* //
|
|
751
|
+
* // | RSI(14) | MACD(12,26,9) | Support Level | ...
|
|
752
|
+
* // | 52.45 | 0.0023 | 42000.50 USD | ...
|
|
753
|
+
* ```
|
|
754
|
+
*/
|
|
530
755
|
this.getReport = async (symbol) => {
|
|
531
756
|
this.loggerService.log("longTermHistoryService getReport", { symbol });
|
|
532
757
|
const fullCandles = await getCandles(symbol, "1h", 100);
|
|
@@ -535,6 +760,24 @@ class LongTermHistoryService {
|
|
|
535
760
|
const rows = allRows.slice(-TABLE_ROWS_LIMIT$3);
|
|
536
761
|
return generateHistoryTable$3(rows, symbol);
|
|
537
762
|
};
|
|
763
|
+
/**
|
|
764
|
+
* Converts analysis rows into markdown table format.
|
|
765
|
+
*
|
|
766
|
+
* Takes pre-calculated indicator rows and formats them as markdown table
|
|
767
|
+
* with column headers, formatted values, and data source explanations.
|
|
768
|
+
*
|
|
769
|
+
* @param symbol - Trading pair symbol for price formatting
|
|
770
|
+
* @param rows - Array of technical analysis rows from getData()
|
|
771
|
+
* @returns Markdown-formatted table with all indicators
|
|
772
|
+
*
|
|
773
|
+
* @example
|
|
774
|
+
* ```typescript
|
|
775
|
+
* const candles = await getCandles('BTCUSDT', '1h', 100);
|
|
776
|
+
* const rows = await service.getData('BTCUSDT', candles);
|
|
777
|
+
* const markdown = await service.generateHistoryTable('BTCUSDT', rows);
|
|
778
|
+
* console.log(markdown); // Markdown table
|
|
779
|
+
* ```
|
|
780
|
+
*/
|
|
538
781
|
this.generateHistoryTable = async (symbol, rows) => {
|
|
539
782
|
this.loggerService.log("longTermHistoryService generateHistoryTable", {
|
|
540
783
|
symbol,
|
|
@@ -545,7 +788,27 @@ class LongTermHistoryService {
|
|
|
545
788
|
}
|
|
546
789
|
}
|
|
547
790
|
|
|
791
|
+
/**
|
|
792
|
+
* MicroTerm (1-minute) technical analysis service for scalping strategies.
|
|
793
|
+
*
|
|
794
|
+
* Generates 40+ indicators on 1-minute candles with 60-candle lookback.
|
|
795
|
+
* Optimized for high-frequency trading and sub-5 minute positions.
|
|
796
|
+
*
|
|
797
|
+
* Indicators: RSI(9,14), StochRSI(9,14), MACD(8,21,5), Bollinger(8,2), Stochastic(3,5),
|
|
798
|
+
* ADX(9), ATR(5,9), CCI(9), Momentum(5,10), ROC(1,3,5), EMA(3,8,13,21), SMA(8), DEMA(8),
|
|
799
|
+
* WMA(5), Support/Resistance, Volume analysis, Squeeze momentum.
|
|
800
|
+
*
|
|
801
|
+
* Used by commitMicroTermMath().
|
|
802
|
+
*/
|
|
803
|
+
/**
|
|
804
|
+
* Minimum number of candles required before generating analysis rows.
|
|
805
|
+
* Ensures all technical indicators (especially EMA(21)) have sufficient data.
|
|
806
|
+
*/
|
|
548
807
|
const WARMUP_PERIOD$2 = 21;
|
|
808
|
+
/**
|
|
809
|
+
* Maximum number of historical rows to return in analysis results.
|
|
810
|
+
* Limits memory usage and table size for markdown reports.
|
|
811
|
+
*/
|
|
549
812
|
const TABLE_ROWS_LIMIT$2 = 40;
|
|
550
813
|
const columns$2 = [
|
|
551
814
|
{
|
|
@@ -823,6 +1086,23 @@ const columns$2 = [
|
|
|
823
1086
|
format: (v) => new Date(v).toISOString(),
|
|
824
1087
|
},
|
|
825
1088
|
];
|
|
1089
|
+
/**
|
|
1090
|
+
* Validates whether a numeric value is safe for calculations.
|
|
1091
|
+
*
|
|
1092
|
+
* Checks if value is a valid finite number. Returns true if value is null,
|
|
1093
|
+
* NaN, Infinity, or not a number type.
|
|
1094
|
+
*
|
|
1095
|
+
* @param value - Value to validate
|
|
1096
|
+
* @returns True if value is unsafe (null/NaN/Infinity), false if valid number
|
|
1097
|
+
*
|
|
1098
|
+
* @example
|
|
1099
|
+
* ```typescript
|
|
1100
|
+
* isUnsafe(42) // false - valid number
|
|
1101
|
+
* isUnsafe(null) // true - null value
|
|
1102
|
+
* isUnsafe(NaN) // true - not a number
|
|
1103
|
+
* isUnsafe(Infinity) // true - infinite value
|
|
1104
|
+
* ```
|
|
1105
|
+
*/
|
|
826
1106
|
function isUnsafe$3(value) {
|
|
827
1107
|
if (typeof value !== "number") {
|
|
828
1108
|
return true;
|
|
@@ -835,6 +1115,25 @@ function isUnsafe$3(value) {
|
|
|
835
1115
|
}
|
|
836
1116
|
return false;
|
|
837
1117
|
}
|
|
1118
|
+
/**
|
|
1119
|
+
* Calculates volume metrics including SMA, ratio, and trend.
|
|
1120
|
+
*
|
|
1121
|
+
* Computes volume SMA(5), current volume to average ratio, and volume trend
|
|
1122
|
+
* by comparing recent 3 candles to previous 3 candles. Returns "increasing"
|
|
1123
|
+
* if recent average > 120% of previous, "decreasing" if < 80%, else "stable".
|
|
1124
|
+
*
|
|
1125
|
+
* @param candles - Array of candle data
|
|
1126
|
+
* @param endIndex - Index of current candle in array
|
|
1127
|
+
* @returns Object with volumeSma5, volumeRatio, and volumeTrend
|
|
1128
|
+
*
|
|
1129
|
+
* @example
|
|
1130
|
+
* ```typescript
|
|
1131
|
+
* const candles = await getCandles('BTCUSDT', '1m', 60);
|
|
1132
|
+
* const metrics = calculateVolumeMetrics(candles, 59);
|
|
1133
|
+
* console.log(metrics);
|
|
1134
|
+
* // { volumeSma5: 1500000, volumeRatio: 1.25, volumeTrend: "increasing" }
|
|
1135
|
+
* ```
|
|
1136
|
+
*/
|
|
838
1137
|
function calculateVolumeMetrics(candles, endIndex) {
|
|
839
1138
|
const volumes = candles.slice(0, endIndex + 1).map((c) => Number(c.volume));
|
|
840
1139
|
if (volumes.length < 5) {
|
|
@@ -861,6 +1160,24 @@ function calculateVolumeMetrics(candles, endIndex) {
|
|
|
861
1160
|
}
|
|
862
1161
|
return { volumeSma5: avgVolume, volumeRatio, volumeTrend };
|
|
863
1162
|
}
|
|
1163
|
+
/**
|
|
1164
|
+
* Calculates price change percentages over 1, 3, and 5 minute periods.
|
|
1165
|
+
*
|
|
1166
|
+
* Computes percentage price changes from current price to prices at
|
|
1167
|
+
* 1, 3, and 5 candles ago. Returns null for periods with insufficient data.
|
|
1168
|
+
*
|
|
1169
|
+
* @param candles - Array of candle data
|
|
1170
|
+
* @param endIndex - Index of current candle in array
|
|
1171
|
+
* @returns Object with priceChange1m, priceChange3m, and priceChange5m percentages
|
|
1172
|
+
*
|
|
1173
|
+
* @example
|
|
1174
|
+
* ```typescript
|
|
1175
|
+
* const candles = await getCandles('BTCUSDT', '1m', 60);
|
|
1176
|
+
* const changes = calculatePriceChanges(candles, 59);
|
|
1177
|
+
* console.log(changes);
|
|
1178
|
+
* // { priceChange1m: 0.05, priceChange3m: 0.12, priceChange5m: -0.08 }
|
|
1179
|
+
* ```
|
|
1180
|
+
*/
|
|
864
1181
|
function calculatePriceChanges(candles, endIndex) {
|
|
865
1182
|
const closes = candles.slice(0, endIndex + 1).map((c) => Number(c.close));
|
|
866
1183
|
if (closes.length < 2) {
|
|
@@ -881,6 +1198,26 @@ function calculatePriceChanges(candles, endIndex) {
|
|
|
881
1198
|
: null;
|
|
882
1199
|
return { priceChange1m, priceChange3m, priceChange5m };
|
|
883
1200
|
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Calculates support and resistance levels from recent high/low prices.
|
|
1203
|
+
*
|
|
1204
|
+
* Identifies support (minimum low) and resistance (maximum high) levels
|
|
1205
|
+
* over last 30 candles. Uses minimum distance threshold (0.3% of current price)
|
|
1206
|
+
* to filter significant levels. Falls back to current price if insufficient data.
|
|
1207
|
+
*
|
|
1208
|
+
* @param candles - Array of candle data
|
|
1209
|
+
* @param endIndex - Index of current candle in array
|
|
1210
|
+
* @param currentPrice - Current price for distance calculations
|
|
1211
|
+
* @returns Object with support and resistance price levels
|
|
1212
|
+
*
|
|
1213
|
+
* @example
|
|
1214
|
+
* ```typescript
|
|
1215
|
+
* const candles = await getCandles('BTCUSDT', '1m', 60);
|
|
1216
|
+
* const levels = calculateSupportResistance(candles, 59, 42500);
|
|
1217
|
+
* console.log(levels);
|
|
1218
|
+
* // { support: 42400.50, resistance: 42600.75 }
|
|
1219
|
+
* ```
|
|
1220
|
+
*/
|
|
884
1221
|
function calculateSupportResistance$1(candles, endIndex, currentPrice) {
|
|
885
1222
|
const recentPeriod = Math.min(30, endIndex + 1);
|
|
886
1223
|
const startIdx = endIndex + 1 - recentPeriod;
|
|
@@ -911,6 +1248,32 @@ function calculateSupportResistance$1(candles, endIndex, currentPrice) {
|
|
|
911
1248
|
: currentPrice;
|
|
912
1249
|
return { support, resistance };
|
|
913
1250
|
}
|
|
1251
|
+
/**
|
|
1252
|
+
* Generates comprehensive technical analysis for 1-minute candles (scalping).
|
|
1253
|
+
*
|
|
1254
|
+
* Calculates 40+ technical indicators per candle including:
|
|
1255
|
+
* - Momentum: RSI(9,14), Stochastic RSI(9,14), MACD(8,21,5), Momentum(5,10), ROC(1,3,5)
|
|
1256
|
+
* - Trend: EMA(3,8,13,21), SMA(8), DEMA(8), WMA(5), ADX(9), +DI/-DI
|
|
1257
|
+
* - Volatility: ATR(5,9), Bollinger Bands(8,2.0), volatility(5), true range
|
|
1258
|
+
* - Volume: Volume SMA(5), volume ratio, volume trend
|
|
1259
|
+
* - Support/Resistance: Pivot points over 30 candles
|
|
1260
|
+
* - Special: Squeeze momentum, pressure index, Bollinger position
|
|
1261
|
+
*
|
|
1262
|
+
* Skips first WARMUP_PERIOD (21) candles to ensure indicator stability.
|
|
1263
|
+
* Returns last TABLE_ROWS_LIMIT (40) rows for memory efficiency.
|
|
1264
|
+
*
|
|
1265
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
1266
|
+
* @param candles - Array of 1-minute candle data
|
|
1267
|
+
* @returns Array of technical analysis rows with all indicators
|
|
1268
|
+
*
|
|
1269
|
+
* @example
|
|
1270
|
+
* ```typescript
|
|
1271
|
+
* const candles = await getCandles('BTCUSDT', '1m', 60);
|
|
1272
|
+
* const analysis = generateAnalysis('BTCUSDT', candles);
|
|
1273
|
+
* console.log(analysis[0].rsi9); // 45.23
|
|
1274
|
+
* console.log(analysis[0].squeezeMomentum); // 1.25
|
|
1275
|
+
* ```
|
|
1276
|
+
*/
|
|
914
1277
|
function generateAnalysis$2(symbol, candles) {
|
|
915
1278
|
const closes = candles.map((candle) => Number(candle.close));
|
|
916
1279
|
const highs = candles.map((candle) => Number(candle.high));
|
|
@@ -1155,6 +1518,32 @@ function generateAnalysis$2(symbol, candles) {
|
|
|
1155
1518
|
// Return only the last TABLE_ROWS_LIMIT rows
|
|
1156
1519
|
return results.slice(-TABLE_ROWS_LIMIT$2);
|
|
1157
1520
|
}
|
|
1521
|
+
/**
|
|
1522
|
+
* Generates markdown table with micro-term technical analysis history.
|
|
1523
|
+
*
|
|
1524
|
+
* Creates comprehensive markdown report with:
|
|
1525
|
+
* - Formatted table of all 40+ technical indicators
|
|
1526
|
+
* - Column headers with indicator names and parameters
|
|
1527
|
+
* - Formatted values (prices in USD, percentages, decimals)
|
|
1528
|
+
* - Data sources section explaining each indicator's calculation
|
|
1529
|
+
* - Timeframe and lookback period documentation (1m candles, 60m lookback)
|
|
1530
|
+
*
|
|
1531
|
+
* Output is optimized for LLM consumption in scalping signal generation.
|
|
1532
|
+
*
|
|
1533
|
+
* @param indicators - Array of analysis rows from generateAnalysis()
|
|
1534
|
+
* @param symbol - Trading pair symbol for price formatting
|
|
1535
|
+
* @returns Markdown-formatted technical analysis report
|
|
1536
|
+
*
|
|
1537
|
+
* @example
|
|
1538
|
+
* ```typescript
|
|
1539
|
+
* const rows = await service.getData('BTCUSDT', candles);
|
|
1540
|
+
* const markdown = await generateHistoryTable(rows, 'BTCUSDT');
|
|
1541
|
+
* console.log(markdown);
|
|
1542
|
+
* // # 1-Minute Candles Trading Analysis for BTCUSDT (Historical Data)
|
|
1543
|
+
* // > Current time: 2025-01-14T10:30:00.000Z
|
|
1544
|
+
* // | RSI(9) | MACD(8,21,5) | Squeeze Momentum | ... |
|
|
1545
|
+
* ```
|
|
1546
|
+
*/
|
|
1158
1547
|
async function generateHistoryTable$2(indicators, symbol) {
|
|
1159
1548
|
let markdown = "";
|
|
1160
1549
|
const currentData = await getDate();
|
|
@@ -1269,9 +1658,64 @@ async function generateHistoryTable$2(indicators, symbol) {
|
|
|
1269
1658
|
"- **Close Price**: close price at row timestamp (Min: 0 USD, Max: +∞ USD)\n";
|
|
1270
1659
|
return markdown;
|
|
1271
1660
|
}
|
|
1661
|
+
/**
|
|
1662
|
+
* Service for micro-term (1-minute) technical analysis and markdown report generation.
|
|
1663
|
+
*
|
|
1664
|
+
* Provides comprehensive technical analysis for 1-minute candles with 40+ indicators
|
|
1665
|
+
* including momentum (RSI, MACD), trend (EMA, SMA), volatility (ATR, Bollinger Bands),
|
|
1666
|
+
* support/resistance levels, volume analysis, and specialized scalping indicators.
|
|
1667
|
+
*
|
|
1668
|
+
* Key features:
|
|
1669
|
+
* - 40+ technical indicators (RSI, MACD, Bollinger Bands, Stochastic, ADX, etc.)
|
|
1670
|
+
* - Support/resistance level detection (30-candle lookback)
|
|
1671
|
+
* - Volume analysis (SMA, ratio, trend)
|
|
1672
|
+
* - Price change tracking (1m, 3m, 5m)
|
|
1673
|
+
* - Specialized scalping indicators (squeeze momentum, pressure index, Bollinger position)
|
|
1674
|
+
* - Volatility and true range calculations
|
|
1675
|
+
* - Markdown table generation for LLM consumption
|
|
1676
|
+
* - Intelligent indicator warmup (skips first 21 candles)
|
|
1677
|
+
* - Memory-efficient output (last 40 rows only)
|
|
1678
|
+
* - Dependency injection support
|
|
1679
|
+
*
|
|
1680
|
+
* @example
|
|
1681
|
+
* ```typescript
|
|
1682
|
+
* import { MicroTermHistoryService } from '@backtest-kit/signals';
|
|
1683
|
+
*
|
|
1684
|
+
* const service = new MicroTermHistoryService();
|
|
1685
|
+
*
|
|
1686
|
+
* // Get markdown report for symbol (fetches candles internally)
|
|
1687
|
+
* const report = await service.getReport('BTCUSDT');
|
|
1688
|
+
* console.log(report); // Markdown table with all indicators
|
|
1689
|
+
*
|
|
1690
|
+
* // Or analyze custom candles
|
|
1691
|
+
* const candles = await getCandles('ETHUSDT', '1m', 60);
|
|
1692
|
+
* const rows = await service.getData('ETHUSDT', candles);
|
|
1693
|
+
* console.log(rows[0].rsi9); // 45.23
|
|
1694
|
+
* console.log(rows[0].squeezeMomentum); // 1.25
|
|
1695
|
+
* ```
|
|
1696
|
+
*/
|
|
1272
1697
|
class MicroTermHistoryService {
|
|
1273
1698
|
constructor() {
|
|
1274
1699
|
this.loggerService = inject(TYPES.loggerService);
|
|
1700
|
+
/**
|
|
1701
|
+
* Analyzes candle data and returns technical indicator rows.
|
|
1702
|
+
*
|
|
1703
|
+
* Calculates all technical indicators for provided candles, skips first WARMUP_PERIOD
|
|
1704
|
+
* rows to ensure stability, and returns last TABLE_ROWS_LIMIT rows.
|
|
1705
|
+
*
|
|
1706
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
1707
|
+
* @param candles - Array of 1-minute candle data
|
|
1708
|
+
* @returns Array of technical analysis rows with all indicators
|
|
1709
|
+
*
|
|
1710
|
+
* @example
|
|
1711
|
+
* ```typescript
|
|
1712
|
+
* const candles = await getCandles('BTCUSDT', '1m', 60);
|
|
1713
|
+
* const rows = await service.getData('BTCUSDT', candles);
|
|
1714
|
+
* console.log(rows.length); // Up to 40 rows
|
|
1715
|
+
* console.log(rows[0].rsi9); // 45.23
|
|
1716
|
+
* console.log(rows[0].volumeRatio); // 1.25
|
|
1717
|
+
* ```
|
|
1718
|
+
*/
|
|
1275
1719
|
this.getData = async (symbol, candles) => {
|
|
1276
1720
|
this.loggerService.log("microTermHistoryService getData", {
|
|
1277
1721
|
symbol,
|
|
@@ -1279,12 +1723,50 @@ class MicroTermHistoryService {
|
|
|
1279
1723
|
});
|
|
1280
1724
|
return generateAnalysis$2(symbol, candles);
|
|
1281
1725
|
};
|
|
1726
|
+
/**
|
|
1727
|
+
* Generates complete markdown technical analysis report for a symbol.
|
|
1728
|
+
*
|
|
1729
|
+
* Fetches 60 1-minute candles (60 minutes) from exchange, calculates all indicators,
|
|
1730
|
+
* and formats results as markdown table optimized for LLM consumption.
|
|
1731
|
+
*
|
|
1732
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
1733
|
+
* @returns Markdown-formatted technical analysis report with table and explanations
|
|
1734
|
+
*
|
|
1735
|
+
* @example
|
|
1736
|
+
* ```typescript
|
|
1737
|
+
* const report = await service.getReport('BTCUSDT');
|
|
1738
|
+
* console.log(report);
|
|
1739
|
+
* // # 1-Minute Candles Trading Analysis for BTCUSDT (Historical Data)
|
|
1740
|
+
* // > Current time: 2025-01-14T10:30:00.000Z
|
|
1741
|
+
* //
|
|
1742
|
+
* // | RSI(9) | MACD(8,21,5) | Squeeze Momentum | ...
|
|
1743
|
+
* // | 45.23 | 0.0012 | 1.25 | ...
|
|
1744
|
+
* ```
|
|
1745
|
+
*/
|
|
1282
1746
|
this.getReport = async (symbol) => {
|
|
1283
1747
|
this.loggerService.log("microTermHistoryService getReport", { symbol });
|
|
1284
1748
|
const candles = await getCandles(symbol, "1m", 60);
|
|
1285
1749
|
const rows = await this.getData(symbol, candles);
|
|
1286
1750
|
return generateHistoryTable$2(rows, symbol);
|
|
1287
1751
|
};
|
|
1752
|
+
/**
|
|
1753
|
+
* Converts analysis rows into markdown table format.
|
|
1754
|
+
*
|
|
1755
|
+
* Takes pre-calculated indicator rows and formats them as markdown table
|
|
1756
|
+
* with column headers, formatted values, and data source explanations.
|
|
1757
|
+
*
|
|
1758
|
+
* @param symbol - Trading pair symbol for price formatting
|
|
1759
|
+
* @param rows - Array of technical analysis rows from getData()
|
|
1760
|
+
* @returns Markdown-formatted table with all indicators
|
|
1761
|
+
*
|
|
1762
|
+
* @example
|
|
1763
|
+
* ```typescript
|
|
1764
|
+
* const candles = await getCandles('BTCUSDT', '1m', 60);
|
|
1765
|
+
* const rows = await service.getData('BTCUSDT', candles);
|
|
1766
|
+
* const markdown = await service.generateHistoryTable('BTCUSDT', rows);
|
|
1767
|
+
* console.log(markdown); // Markdown table
|
|
1768
|
+
* ```
|
|
1769
|
+
*/
|
|
1288
1770
|
this.generateHistoryTable = async (symbol, rows) => {
|
|
1289
1771
|
this.loggerService.log("microTermHistoryService generateHistoryTable", {
|
|
1290
1772
|
symbol,
|
|
@@ -1295,7 +1777,15 @@ class MicroTermHistoryService {
|
|
|
1295
1777
|
}
|
|
1296
1778
|
}
|
|
1297
1779
|
|
|
1780
|
+
/**
|
|
1781
|
+
* Maximum number of historical rows to return in analysis results.
|
|
1782
|
+
* Limits memory usage and table size for markdown reports.
|
|
1783
|
+
*/
|
|
1298
1784
|
const TABLE_ROWS_LIMIT$1 = 48;
|
|
1785
|
+
/**
|
|
1786
|
+
* Minimum number of candles required before generating analysis rows.
|
|
1787
|
+
* Ensures all technical indicators (especially SMA(50)) have sufficient data.
|
|
1788
|
+
*/
|
|
1299
1789
|
const WARMUP_PERIOD$1 = 50;
|
|
1300
1790
|
const columns$1 = [
|
|
1301
1791
|
{
|
|
@@ -1483,6 +1973,23 @@ const columns$1 = [
|
|
|
1483
1973
|
format: (v) => new Date(v).toISOString(),
|
|
1484
1974
|
},
|
|
1485
1975
|
];
|
|
1976
|
+
/**
|
|
1977
|
+
* Validates whether a numeric value is safe for calculations.
|
|
1978
|
+
*
|
|
1979
|
+
* Checks if value is a valid finite number. Returns true if value is null,
|
|
1980
|
+
* NaN, Infinity, or not a number type.
|
|
1981
|
+
*
|
|
1982
|
+
* @param value - Value to validate
|
|
1983
|
+
* @returns True if value is unsafe (null/NaN/Infinity), false if valid number
|
|
1984
|
+
*
|
|
1985
|
+
* @example
|
|
1986
|
+
* ```typescript
|
|
1987
|
+
* isUnsafe(42) // false - valid number
|
|
1988
|
+
* isUnsafe(null) // true - null value
|
|
1989
|
+
* isUnsafe(NaN) // true - not a number
|
|
1990
|
+
* isUnsafe(Infinity) // true - infinite value
|
|
1991
|
+
* ```
|
|
1992
|
+
*/
|
|
1486
1993
|
function isUnsafe$2(value) {
|
|
1487
1994
|
if (typeof value !== "number") {
|
|
1488
1995
|
return true;
|
|
@@ -1495,6 +2002,25 @@ function isUnsafe$2(value) {
|
|
|
1495
2002
|
}
|
|
1496
2003
|
return false;
|
|
1497
2004
|
}
|
|
2005
|
+
/**
|
|
2006
|
+
* Calculates Fibonacci retracement levels and finds nearest level to current price.
|
|
2007
|
+
*
|
|
2008
|
+
* Computes standard Fibonacci levels (0%, 23.6%, 38.2%, 50%, 61.8%, 78.6%, 100%)
|
|
2009
|
+
* plus extension levels (127.2%, 161.8%) based on high-low range over lookback period.
|
|
2010
|
+
* Returns the level closest to current price with distance in USD.
|
|
2011
|
+
*
|
|
2012
|
+
* @param candles - Array of candle data
|
|
2013
|
+
* @param endIndex - Index of current candle in array
|
|
2014
|
+
* @returns Object with nearest level name, price, and distance in USD
|
|
2015
|
+
*
|
|
2016
|
+
* @example
|
|
2017
|
+
* ```typescript
|
|
2018
|
+
* const candles = await getCandles('BTCUSDT', '15m', 300);
|
|
2019
|
+
* const fib = calculateFibonacciLevels(candles, 299);
|
|
2020
|
+
* console.log(fib);
|
|
2021
|
+
* // { level: "61.8%", price: 42500.50, distance: 125.30 }
|
|
2022
|
+
* ```
|
|
2023
|
+
*/
|
|
1498
2024
|
function calculateFibonacciLevels$1(candles, endIndex) {
|
|
1499
2025
|
const lookbackPeriod = Math.min(288, endIndex + 1);
|
|
1500
2026
|
const startIndex = endIndex + 1 - lookbackPeriod;
|
|
@@ -1527,6 +2053,24 @@ function calculateFibonacciLevels$1(candles, endIndex) {
|
|
|
1527
2053
|
});
|
|
1528
2054
|
return nearestLevel;
|
|
1529
2055
|
}
|
|
2056
|
+
/**
|
|
2057
|
+
* Analyzes volume trend by comparing recent vs older volume averages.
|
|
2058
|
+
*
|
|
2059
|
+
* Compares average volume of last 8 candles against previous 8 candles.
|
|
2060
|
+
* Returns "increasing" if recent volume > 120% of older volume,
|
|
2061
|
+
* "decreasing" if recent < 80% of older volume, otherwise "stable".
|
|
2062
|
+
*
|
|
2063
|
+
* @param candles - Array of candle data
|
|
2064
|
+
* @param endIndex - Index of current candle in array
|
|
2065
|
+
* @returns Volume trend: "increasing", "decreasing", or "stable"
|
|
2066
|
+
*
|
|
2067
|
+
* @example
|
|
2068
|
+
* ```typescript
|
|
2069
|
+
* const candles = await getCandles('ETHUSDT', '15m', 100);
|
|
2070
|
+
* const trend = calculateVolumeTrend(candles, 99);
|
|
2071
|
+
* console.log(trend); // "increasing" | "decreasing" | "stable"
|
|
2072
|
+
* ```
|
|
2073
|
+
*/
|
|
1530
2074
|
function calculateVolumeTrend(candles, endIndex) {
|
|
1531
2075
|
const volumes = candles.slice(0, endIndex + 1).map((c) => Number(c.volume));
|
|
1532
2076
|
if (volumes.length < 16)
|
|
@@ -1543,6 +2087,31 @@ function calculateVolumeTrend(candles, endIndex) {
|
|
|
1543
2087
|
return "decreasing";
|
|
1544
2088
|
return "stable";
|
|
1545
2089
|
}
|
|
2090
|
+
/**
|
|
2091
|
+
* Generates comprehensive technical analysis for 15-minute candles.
|
|
2092
|
+
*
|
|
2093
|
+
* Calculates 30+ technical indicators per candle including:
|
|
2094
|
+
* - Momentum: RSI(9), Stochastic RSI(9), MACD(8,21,5), Momentum(8), ROC(5,10)
|
|
2095
|
+
* - Trend: SMA(50), EMA(8,21), DEMA(21), WMA(20), ADX(14), +DI/-DI
|
|
2096
|
+
* - Volatility: ATR(9), Bollinger Bands(10,2.0)
|
|
2097
|
+
* - Volume: Volume trend analysis
|
|
2098
|
+
* - Support/Resistance: Pivot points, Fibonacci levels
|
|
2099
|
+
*
|
|
2100
|
+
* Skips first WARMUP_PERIOD (50) candles to ensure indicator stability.
|
|
2101
|
+
* Returns last TABLE_ROWS_LIMIT (48) rows for memory efficiency.
|
|
2102
|
+
*
|
|
2103
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
2104
|
+
* @param candles - Array of 15-minute candle data
|
|
2105
|
+
* @returns Array of technical analysis rows with all indicators
|
|
2106
|
+
*
|
|
2107
|
+
* @example
|
|
2108
|
+
* ```typescript
|
|
2109
|
+
* const candles = await getCandles('BTCUSDT', '15m', 144);
|
|
2110
|
+
* const analysis = generateAnalysis('BTCUSDT', candles);
|
|
2111
|
+
* console.log(analysis[0].rsi9); // 45.23
|
|
2112
|
+
* console.log(analysis[0].support); // 42000.50
|
|
2113
|
+
* ```
|
|
2114
|
+
*/
|
|
1546
2115
|
function generateAnalysis$1(symbol, candles) {
|
|
1547
2116
|
const closes = candles.map((candle) => Number(candle.close));
|
|
1548
2117
|
const highs = candles.map((candle) => Number(candle.high));
|
|
@@ -1720,6 +2289,32 @@ function generateAnalysis$1(symbol, candles) {
|
|
|
1720
2289
|
// Return only the last TABLE_ROWS_LIMIT rows
|
|
1721
2290
|
return results.slice(-TABLE_ROWS_LIMIT$1);
|
|
1722
2291
|
}
|
|
2292
|
+
/**
|
|
2293
|
+
* Generates markdown table with technical analysis history.
|
|
2294
|
+
*
|
|
2295
|
+
* Creates comprehensive markdown report with:
|
|
2296
|
+
* - Formatted table of all technical indicators
|
|
2297
|
+
* - Column headers with indicator names and parameters
|
|
2298
|
+
* - Formatted values (prices in USD, percentages, decimals)
|
|
2299
|
+
* - Data sources section explaining each indicator's calculation
|
|
2300
|
+
* - Timeframe and lookback period documentation
|
|
2301
|
+
*
|
|
2302
|
+
* Output is optimized for LLM consumption in trading signal generation.
|
|
2303
|
+
*
|
|
2304
|
+
* @param indicators - Array of analysis rows from generateAnalysis()
|
|
2305
|
+
* @param symbol - Trading pair symbol for price formatting
|
|
2306
|
+
* @returns Markdown-formatted technical analysis report
|
|
2307
|
+
*
|
|
2308
|
+
* @example
|
|
2309
|
+
* ```typescript
|
|
2310
|
+
* const rows = await service.getData('BTCUSDT', candles);
|
|
2311
|
+
* const markdown = await generateHistoryTable(rows, 'BTCUSDT');
|
|
2312
|
+
* console.log(markdown);
|
|
2313
|
+
* // # 15-Minute Candles Trading Analysis for BTCUSDT (Historical Data)
|
|
2314
|
+
* // > Current time: 2025-01-14T10:30:00.000Z
|
|
2315
|
+
* // | RSI(9) | MACD(8,21,5) | ... |
|
|
2316
|
+
* ```
|
|
2317
|
+
*/
|
|
1723
2318
|
async function generateHistoryTable$1(indicators, symbol) {
|
|
1724
2319
|
let markdown = "";
|
|
1725
2320
|
const currentData = await getDate();
|
|
@@ -1802,9 +2397,61 @@ async function generateHistoryTable$1(indicators, symbol) {
|
|
|
1802
2397
|
"- **Close Price**: close price at row timestamp (Min: 0 USD, Max: +∞ USD)\n";
|
|
1803
2398
|
return markdown;
|
|
1804
2399
|
}
|
|
2400
|
+
/**
|
|
2401
|
+
* Service for short-term (15-minute) technical analysis and markdown report generation.
|
|
2402
|
+
*
|
|
2403
|
+
* Provides comprehensive technical analysis for 15-minute candles with 30+ indicators
|
|
2404
|
+
* including momentum (RSI, MACD), trend (EMA, SMA), volatility (ATR, Bollinger Bands),
|
|
2405
|
+
* support/resistance levels, and Fibonacci retracements.
|
|
2406
|
+
*
|
|
2407
|
+
* Key features:
|
|
2408
|
+
* - 30+ technical indicators (RSI, MACD, Bollinger Bands, Stochastic, ADX, etc.)
|
|
2409
|
+
* - Support/resistance level detection
|
|
2410
|
+
* - Fibonacci retracement analysis
|
|
2411
|
+
* - Volume trend analysis
|
|
2412
|
+
* - Markdown table generation for LLM consumption
|
|
2413
|
+
* - Intelligent indicator warmup (skips first 50 candles)
|
|
2414
|
+
* - Memory-efficient output (last 48 rows only)
|
|
2415
|
+
* - Dependency injection support
|
|
2416
|
+
*
|
|
2417
|
+
* @example
|
|
2418
|
+
* ```typescript
|
|
2419
|
+
* import { ShortTermHistoryService } from '@backtest-kit/signals';
|
|
2420
|
+
*
|
|
2421
|
+
* const service = new ShortTermHistoryService();
|
|
2422
|
+
*
|
|
2423
|
+
* // Get markdown report for symbol (fetches candles internally)
|
|
2424
|
+
* const report = await service.getReport('BTCUSDT');
|
|
2425
|
+
* console.log(report); // Markdown table with all indicators
|
|
2426
|
+
*
|
|
2427
|
+
* // Or analyze custom candles
|
|
2428
|
+
* const candles = await getCandles('ETHUSDT', '15m', 144);
|
|
2429
|
+
* const rows = await service.getData('ETHUSDT', candles);
|
|
2430
|
+
* console.log(rows[0].rsi9); // 45.23
|
|
2431
|
+
* ```
|
|
2432
|
+
*/
|
|
1805
2433
|
class ShortTermHistoryService {
|
|
1806
2434
|
constructor() {
|
|
1807
2435
|
this.loggerService = inject(TYPES.loggerService);
|
|
2436
|
+
/**
|
|
2437
|
+
* Analyzes candle data and returns technical indicator rows.
|
|
2438
|
+
*
|
|
2439
|
+
* Calculates all technical indicators for provided candles, skips first WARMUP_PERIOD
|
|
2440
|
+
* rows to ensure stability, and returns last TABLE_ROWS_LIMIT rows.
|
|
2441
|
+
*
|
|
2442
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
2443
|
+
* @param candles - Array of 15-minute candle data
|
|
2444
|
+
* @returns Array of technical analysis rows with all indicators
|
|
2445
|
+
*
|
|
2446
|
+
* @example
|
|
2447
|
+
* ```typescript
|
|
2448
|
+
* const candles = await getCandles('BTCUSDT', '15m', 144);
|
|
2449
|
+
* const rows = await service.getData('BTCUSDT', candles);
|
|
2450
|
+
* console.log(rows.length); // Up to 48 rows
|
|
2451
|
+
* console.log(rows[0].rsi9); // 45.23
|
|
2452
|
+
* console.log(rows[0].support); // 42000.50
|
|
2453
|
+
* ```
|
|
2454
|
+
*/
|
|
1808
2455
|
this.getData = async (symbol, candles) => {
|
|
1809
2456
|
this.loggerService.log("shortTermHistoryService getData", {
|
|
1810
2457
|
symbol,
|
|
@@ -1812,12 +2459,50 @@ class ShortTermHistoryService {
|
|
|
1812
2459
|
});
|
|
1813
2460
|
return generateAnalysis$1(symbol, candles);
|
|
1814
2461
|
};
|
|
2462
|
+
/**
|
|
2463
|
+
* Generates complete markdown technical analysis report for a symbol.
|
|
2464
|
+
*
|
|
2465
|
+
* Fetches 144 15-minute candles (36 hours) from exchange, calculates all indicators,
|
|
2466
|
+
* and formats results as markdown table optimized for LLM consumption.
|
|
2467
|
+
*
|
|
2468
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
2469
|
+
* @returns Markdown-formatted technical analysis report with table and explanations
|
|
2470
|
+
*
|
|
2471
|
+
* @example
|
|
2472
|
+
* ```typescript
|
|
2473
|
+
* const report = await service.getReport('BTCUSDT');
|
|
2474
|
+
* console.log(report);
|
|
2475
|
+
* // # 15-Minute Candles Trading Analysis for BTCUSDT (Historical Data)
|
|
2476
|
+
* // > Current time: 2025-01-14T10:30:00.000Z
|
|
2477
|
+
* //
|
|
2478
|
+
* // | RSI(9) | MACD(8,21,5) | Support Level | ...
|
|
2479
|
+
* // | 45.23 | 0.0012 | 42000.50 USD | ...
|
|
2480
|
+
* ```
|
|
2481
|
+
*/
|
|
1815
2482
|
this.getReport = async (symbol) => {
|
|
1816
2483
|
this.loggerService.log("shortTermHistoryService getReport", { symbol });
|
|
1817
2484
|
const candles = await getCandles(symbol, "15m", 144);
|
|
1818
2485
|
const rows = await this.getData(symbol, candles);
|
|
1819
2486
|
return generateHistoryTable$1(rows, symbol);
|
|
1820
2487
|
};
|
|
2488
|
+
/**
|
|
2489
|
+
* Converts analysis rows into markdown table format.
|
|
2490
|
+
*
|
|
2491
|
+
* Takes pre-calculated indicator rows and formats them as markdown table
|
|
2492
|
+
* with column headers, formatted values, and data source explanations.
|
|
2493
|
+
*
|
|
2494
|
+
* @param symbol - Trading pair symbol for price formatting
|
|
2495
|
+
* @param rows - Array of technical analysis rows from getData()
|
|
2496
|
+
* @returns Markdown-formatted table with all indicators
|
|
2497
|
+
*
|
|
2498
|
+
* @example
|
|
2499
|
+
* ```typescript
|
|
2500
|
+
* const candles = await getCandles('BTCUSDT', '15m', 144);
|
|
2501
|
+
* const rows = await service.getData('BTCUSDT', candles);
|
|
2502
|
+
* const markdown = await service.generateHistoryTable('BTCUSDT', rows);
|
|
2503
|
+
* console.log(markdown); // Markdown table
|
|
2504
|
+
* ```
|
|
2505
|
+
*/
|
|
1821
2506
|
this.generateHistoryTable = async (symbol, rows) => {
|
|
1822
2507
|
this.loggerService.log("shortTermHistoryService generateHistoryTable", {
|
|
1823
2508
|
symbol,
|
|
@@ -1828,7 +2513,15 @@ class ShortTermHistoryService {
|
|
|
1828
2513
|
}
|
|
1829
2514
|
}
|
|
1830
2515
|
|
|
2516
|
+
/**
|
|
2517
|
+
* Maximum number of historical rows to return in analysis results.
|
|
2518
|
+
* Limits memory usage and table size for markdown reports.
|
|
2519
|
+
*/
|
|
1831
2520
|
const TABLE_ROWS_LIMIT = 30;
|
|
2521
|
+
/**
|
|
2522
|
+
* Minimum number of candles required before generating analysis rows.
|
|
2523
|
+
* Ensures all technical indicators (especially EMA(34)) have sufficient data.
|
|
2524
|
+
*/
|
|
1832
2525
|
const WARMUP_PERIOD = 34;
|
|
1833
2526
|
const columns = [
|
|
1834
2527
|
{
|
|
@@ -2027,6 +2720,23 @@ const columns = [
|
|
|
2027
2720
|
format: (v) => new Date(v).toISOString(),
|
|
2028
2721
|
},
|
|
2029
2722
|
];
|
|
2723
|
+
/**
|
|
2724
|
+
* Validates whether a numeric value is safe for calculations.
|
|
2725
|
+
*
|
|
2726
|
+
* Checks if value is a valid finite number. Returns true if value is null,
|
|
2727
|
+
* NaN, Infinity, or not a number type.
|
|
2728
|
+
*
|
|
2729
|
+
* @param value - Value to validate
|
|
2730
|
+
* @returns True if value is unsafe (null/NaN/Infinity), false if valid number
|
|
2731
|
+
*
|
|
2732
|
+
* @example
|
|
2733
|
+
* ```typescript
|
|
2734
|
+
* isUnsafe(42) // false - valid number
|
|
2735
|
+
* isUnsafe(null) // true - null value
|
|
2736
|
+
* isUnsafe(NaN) // true - not a number
|
|
2737
|
+
* isUnsafe(Infinity) // true - infinite value
|
|
2738
|
+
* ```
|
|
2739
|
+
*/
|
|
2030
2740
|
function isUnsafe$1(value) {
|
|
2031
2741
|
if (typeof value !== "number") {
|
|
2032
2742
|
return true;
|
|
@@ -2039,6 +2749,31 @@ function isUnsafe$1(value) {
|
|
|
2039
2749
|
}
|
|
2040
2750
|
return false;
|
|
2041
2751
|
}
|
|
2752
|
+
/**
|
|
2753
|
+
* Calculates Fibonacci levels and determines nearest support/resistance levels.
|
|
2754
|
+
*
|
|
2755
|
+
* Computes Fibonacci retracement levels (0%, 23.6%, 38.2%, 50%, 61.8%, 78.6%, 100%)
|
|
2756
|
+
* and extension levels (127.2%, 161.8%, 261.8%) over specified lookback period.
|
|
2757
|
+
* Identifies current price position relative to Fibonacci levels and finds
|
|
2758
|
+
* nearest support/resistance levels.
|
|
2759
|
+
*
|
|
2760
|
+
* @param candles - Array of candle data
|
|
2761
|
+
* @param endIndex - Index of current candle in array
|
|
2762
|
+
* @param period - Lookback period in candles (default: 48)
|
|
2763
|
+
* @returns Object with nearest support/resistance prices and current level description
|
|
2764
|
+
*
|
|
2765
|
+
* @example
|
|
2766
|
+
* ```typescript
|
|
2767
|
+
* const candles = await getCandles('BTCUSDT', '30m', 96);
|
|
2768
|
+
* const fib = calculateFibonacciLevels(candles, 95, 48);
|
|
2769
|
+
* console.log(fib);
|
|
2770
|
+
* // {
|
|
2771
|
+
* // nearestSupport: 42000.50,
|
|
2772
|
+
* // nearestResistance: 43500.25,
|
|
2773
|
+
* // currentLevel: "50.0% Retracement"
|
|
2774
|
+
* // }
|
|
2775
|
+
* ```
|
|
2776
|
+
*/
|
|
2042
2777
|
function calculateFibonacciLevels(candles, endIndex, period = 48) {
|
|
2043
2778
|
if (endIndex + 1 < period) {
|
|
2044
2779
|
return {
|
|
@@ -2125,6 +2860,25 @@ function calculateFibonacciLevels(candles, endIndex, period = 48) {
|
|
|
2125
2860
|
currentLevel,
|
|
2126
2861
|
};
|
|
2127
2862
|
}
|
|
2863
|
+
/**
|
|
2864
|
+
* Calculates support and resistance levels from recent high/low prices.
|
|
2865
|
+
*
|
|
2866
|
+
* Identifies support (minimum low) and resistance (maximum high) levels
|
|
2867
|
+
* over specified window period. Falls back to current price if insufficient data.
|
|
2868
|
+
*
|
|
2869
|
+
* @param candles - Array of candle data
|
|
2870
|
+
* @param endIndex - Index of current candle in array
|
|
2871
|
+
* @param window - Lookback window in candles (default: 20)
|
|
2872
|
+
* @returns Object with support and resistance price levels
|
|
2873
|
+
*
|
|
2874
|
+
* @example
|
|
2875
|
+
* ```typescript
|
|
2876
|
+
* const candles = await getCandles('ETHUSDT', '30m', 96);
|
|
2877
|
+
* const levels = calculateSupportResistance(candles, 95, 20);
|
|
2878
|
+
* console.log(levels);
|
|
2879
|
+
* // { support: 2200.50, resistance: 2350.75 }
|
|
2880
|
+
* ```
|
|
2881
|
+
*/
|
|
2128
2882
|
function calculateSupportResistance(candles, endIndex, window = 20) {
|
|
2129
2883
|
const startIdx = Math.max(0, endIndex + 1 - window);
|
|
2130
2884
|
const recentHighs = candles
|
|
@@ -2140,6 +2894,31 @@ function calculateSupportResistance(candles, endIndex, window = 20) {
|
|
|
2140
2894
|
const resistance = recentHighs.length > 0 ? Math.max(...recentHighs) : currentPrice;
|
|
2141
2895
|
return { support, resistance };
|
|
2142
2896
|
}
|
|
2897
|
+
/**
|
|
2898
|
+
* Generates comprehensive technical analysis for 30-minute candles (swing trading).
|
|
2899
|
+
*
|
|
2900
|
+
* Calculates 25+ technical indicators per candle including:
|
|
2901
|
+
* - Momentum: RSI(14), Stochastic RSI(14), MACD(12,26,9), Momentum(8), Price Momentum(6)
|
|
2902
|
+
* - Trend: SMA(20), EMA(13,34), DEMA(21), WMA(20), ADX(14), +DI/-DI
|
|
2903
|
+
* - Volatility: ATR(14), Bollinger Bands(20,2.0), calculated volatility
|
|
2904
|
+
* - Support/Resistance: Pivot points, Fibonacci levels with nearest support/resistance
|
|
2905
|
+
* - Volume analysis
|
|
2906
|
+
*
|
|
2907
|
+
* Skips first WARMUP_PERIOD (34) candles to ensure indicator stability.
|
|
2908
|
+
* Returns last TABLE_ROWS_LIMIT (30) rows for memory efficiency.
|
|
2909
|
+
*
|
|
2910
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
2911
|
+
* @param candles - Array of 30-minute candle data
|
|
2912
|
+
* @returns Array of technical analysis rows with all indicators
|
|
2913
|
+
*
|
|
2914
|
+
* @example
|
|
2915
|
+
* ```typescript
|
|
2916
|
+
* const candles = await getCandles('BTCUSDT', '30m', 96);
|
|
2917
|
+
* const analysis = generateAnalysis('BTCUSDT', candles);
|
|
2918
|
+
* console.log(analysis[0].rsi14); // 52.45
|
|
2919
|
+
* console.log(analysis[0].fibonacciCurrentLevel); // "50.0% Retracement"
|
|
2920
|
+
* ```
|
|
2921
|
+
*/
|
|
2143
2922
|
function generateAnalysis(symbol, candles) {
|
|
2144
2923
|
const closes = candles.map((candle) => Number(candle.close));
|
|
2145
2924
|
const highs = candles.map((candle) => Number(candle.high));
|
|
@@ -2316,6 +3095,32 @@ function generateAnalysis(symbol, candles) {
|
|
|
2316
3095
|
// Return only the last TABLE_ROWS_LIMIT rows
|
|
2317
3096
|
return results.slice(-TABLE_ROWS_LIMIT);
|
|
2318
3097
|
}
|
|
3098
|
+
/**
|
|
3099
|
+
* Generates markdown table with swing trading technical analysis history.
|
|
3100
|
+
*
|
|
3101
|
+
* Creates comprehensive markdown report with:
|
|
3102
|
+
* - Formatted table of all technical indicators
|
|
3103
|
+
* - Column headers with indicator names and parameters
|
|
3104
|
+
* - Formatted values (prices in USD, percentages, decimals)
|
|
3105
|
+
* - Data sources section explaining each indicator's calculation
|
|
3106
|
+
* - Timeframe and lookback period documentation (30m candles, 48h lookback)
|
|
3107
|
+
*
|
|
3108
|
+
* Output is optimized for LLM consumption in swing trading signal generation.
|
|
3109
|
+
*
|
|
3110
|
+
* @param indicators - Array of analysis rows from generateAnalysis()
|
|
3111
|
+
* @param symbol - Trading pair symbol for price formatting
|
|
3112
|
+
* @returns Markdown-formatted technical analysis report
|
|
3113
|
+
*
|
|
3114
|
+
* @example
|
|
3115
|
+
* ```typescript
|
|
3116
|
+
* const rows = await service.getData('BTCUSDT', candles);
|
|
3117
|
+
* const markdown = await generateHistoryTable(rows, 'BTCUSDT');
|
|
3118
|
+
* console.log(markdown);
|
|
3119
|
+
* // # 30-Min Candles Analysis for BTCUSDT (Historical Data)
|
|
3120
|
+
* // > Current time: 2025-01-14T10:30:00.000Z
|
|
3121
|
+
* // | RSI(14) | MACD(12,26,9) | Fibonacci Current Level | ... |
|
|
3122
|
+
* ```
|
|
3123
|
+
*/
|
|
2319
3124
|
async function generateHistoryTable(indicators, symbol) {
|
|
2320
3125
|
let markdown = "";
|
|
2321
3126
|
const currentData = await getDate();
|
|
@@ -2400,9 +3205,63 @@ async function generateHistoryTable(indicators, symbol) {
|
|
|
2400
3205
|
"- **Volatility**: volatility percentage at row timestamp (Min: 0%, Max: +∞)\n";
|
|
2401
3206
|
return markdown;
|
|
2402
3207
|
}
|
|
3208
|
+
/**
|
|
3209
|
+
* Service for swing-term (30-minute) technical analysis and markdown report generation.
|
|
3210
|
+
*
|
|
3211
|
+
* Provides comprehensive technical analysis for 30-minute candles with 25+ indicators
|
|
3212
|
+
* including momentum (RSI, MACD), trend (EMA, SMA), volatility (ATR, Bollinger Bands),
|
|
3213
|
+
* support/resistance levels, and Fibonacci analysis with nearest support/resistance.
|
|
3214
|
+
*
|
|
3215
|
+
* Key features:
|
|
3216
|
+
* - 25+ technical indicators (RSI, MACD, Bollinger Bands, Stochastic, ADX, etc.)
|
|
3217
|
+
* - Support/resistance level detection
|
|
3218
|
+
* - Fibonacci retracement and extension analysis with nearest levels
|
|
3219
|
+
* - Volume and volatility analysis
|
|
3220
|
+
* - Price momentum tracking
|
|
3221
|
+
* - Markdown table generation for LLM consumption
|
|
3222
|
+
* - Intelligent indicator warmup (skips first 34 candles)
|
|
3223
|
+
* - Memory-efficient output (last 30 rows only)
|
|
3224
|
+
* - Dependency injection support
|
|
3225
|
+
*
|
|
3226
|
+
* @example
|
|
3227
|
+
* ```typescript
|
|
3228
|
+
* import { SwingTermHistoryService } from '@backtest-kit/signals';
|
|
3229
|
+
*
|
|
3230
|
+
* const service = new SwingTermHistoryService();
|
|
3231
|
+
*
|
|
3232
|
+
* // Get markdown report for symbol (fetches candles internally)
|
|
3233
|
+
* const report = await service.getReport('BTCUSDT');
|
|
3234
|
+
* console.log(report); // Markdown table with all indicators
|
|
3235
|
+
*
|
|
3236
|
+
* // Or analyze custom candles
|
|
3237
|
+
* const candles = await getCandles('ETHUSDT', '30m', 96);
|
|
3238
|
+
* const rows = await service.getData('ETHUSDT', candles);
|
|
3239
|
+
* console.log(rows[0].rsi14); // 52.45
|
|
3240
|
+
* console.log(rows[0].fibonacciCurrentLevel); // "50.0% Retracement"
|
|
3241
|
+
* ```
|
|
3242
|
+
*/
|
|
2403
3243
|
class SwingTermHistoryService {
|
|
2404
3244
|
constructor() {
|
|
2405
3245
|
this.loggerService = inject(TYPES.loggerService);
|
|
3246
|
+
/**
|
|
3247
|
+
* Analyzes candle data and returns technical indicator rows.
|
|
3248
|
+
*
|
|
3249
|
+
* Calculates all technical indicators for provided candles, skips first WARMUP_PERIOD
|
|
3250
|
+
* rows to ensure stability, and returns last TABLE_ROWS_LIMIT rows.
|
|
3251
|
+
*
|
|
3252
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
3253
|
+
* @param candles - Array of 30-minute candle data
|
|
3254
|
+
* @returns Array of technical analysis rows with all indicators
|
|
3255
|
+
*
|
|
3256
|
+
* @example
|
|
3257
|
+
* ```typescript
|
|
3258
|
+
* const candles = await getCandles('BTCUSDT', '30m', 96);
|
|
3259
|
+
* const rows = await service.getData('BTCUSDT', candles);
|
|
3260
|
+
* console.log(rows.length); // Up to 30 rows
|
|
3261
|
+
* console.log(rows[0].rsi14); // 52.45
|
|
3262
|
+
* console.log(rows[0].fibonacciNearestSupport); // 42000.50
|
|
3263
|
+
* ```
|
|
3264
|
+
*/
|
|
2406
3265
|
this.getData = async (symbol, candles) => {
|
|
2407
3266
|
this.loggerService.log("swingTermHistoryService getData", {
|
|
2408
3267
|
symbol,
|
|
@@ -2410,12 +3269,50 @@ class SwingTermHistoryService {
|
|
|
2410
3269
|
});
|
|
2411
3270
|
return generateAnalysis(symbol, candles);
|
|
2412
3271
|
};
|
|
3272
|
+
/**
|
|
3273
|
+
* Generates complete markdown technical analysis report for a symbol.
|
|
3274
|
+
*
|
|
3275
|
+
* Fetches 96 30-minute candles (48 hours) from exchange, calculates all indicators,
|
|
3276
|
+
* and formats results as markdown table optimized for LLM consumption.
|
|
3277
|
+
*
|
|
3278
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
3279
|
+
* @returns Markdown-formatted technical analysis report with table and explanations
|
|
3280
|
+
*
|
|
3281
|
+
* @example
|
|
3282
|
+
* ```typescript
|
|
3283
|
+
* const report = await service.getReport('BTCUSDT');
|
|
3284
|
+
* console.log(report);
|
|
3285
|
+
* // # 30-Min Candles Analysis for BTCUSDT (Historical Data)
|
|
3286
|
+
* // > Current time: 2025-01-14T10:30:00.000Z
|
|
3287
|
+
* //
|
|
3288
|
+
* // | RSI(14) | MACD(12,26,9) | Fibonacci Current Level | ...
|
|
3289
|
+
* // | 52.45 | 0.0023 | 50.0% Retracement | ...
|
|
3290
|
+
* ```
|
|
3291
|
+
*/
|
|
2413
3292
|
this.getReport = async (symbol) => {
|
|
2414
3293
|
this.loggerService.log("swingTermHistoryService getReport", { symbol });
|
|
2415
3294
|
const candles = await getCandles(symbol, "30m", 96);
|
|
2416
3295
|
const rows = await this.getData(symbol, candles);
|
|
2417
3296
|
return generateHistoryTable(rows, symbol);
|
|
2418
3297
|
};
|
|
3298
|
+
/**
|
|
3299
|
+
* Converts analysis rows into markdown table format.
|
|
3300
|
+
*
|
|
3301
|
+
* Takes pre-calculated indicator rows and formats them as markdown table
|
|
3302
|
+
* with column headers, formatted values, and data source explanations.
|
|
3303
|
+
*
|
|
3304
|
+
* @param symbol - Trading pair symbol for price formatting
|
|
3305
|
+
* @param rows - Array of technical analysis rows from getData()
|
|
3306
|
+
* @returns Markdown-formatted table with all indicators
|
|
3307
|
+
*
|
|
3308
|
+
* @example
|
|
3309
|
+
* ```typescript
|
|
3310
|
+
* const candles = await getCandles('BTCUSDT', '30m', 96);
|
|
3311
|
+
* const rows = await service.getData('BTCUSDT', candles);
|
|
3312
|
+
* const markdown = await service.generateHistoryTable('BTCUSDT', rows);
|
|
3313
|
+
* console.log(markdown); // Markdown table
|
|
3314
|
+
* ```
|
|
3315
|
+
*/
|
|
2419
3316
|
this.generateHistoryTable = async (symbol, rows) => {
|
|
2420
3317
|
this.loggerService.log("swingTermHistoryService generateHistoryTable", {
|
|
2421
3318
|
symbol,
|
|
@@ -2426,14 +3323,102 @@ class SwingTermHistoryService {
|
|
|
2426
3323
|
}
|
|
2427
3324
|
}
|
|
2428
3325
|
|
|
3326
|
+
/**
|
|
3327
|
+
* Fifteen-minute candle history service for day trading analysis.
|
|
3328
|
+
*
|
|
3329
|
+
* Generates markdown reports of the last 8 fifteen-minute candles including:
|
|
3330
|
+
* - OHLCV data with high-volatility detection
|
|
3331
|
+
* - Candle type (Green/Red/Doji)
|
|
3332
|
+
* - Volatility percentage (flagged if >1.5x average)
|
|
3333
|
+
* - Body size percentage
|
|
3334
|
+
* - Timestamp
|
|
3335
|
+
*
|
|
3336
|
+
* Used by commitFifteenMinuteHistory() for LLM context injection.
|
|
3337
|
+
*/
|
|
3338
|
+
/**
|
|
3339
|
+
* Number of recent candles to include in history report.
|
|
3340
|
+
* Provides 2-hour price action context for day trading decisions.
|
|
3341
|
+
*/
|
|
2429
3342
|
const RECENT_CANDLES$3 = 8;
|
|
3343
|
+
/**
|
|
3344
|
+
* Service for generating 15-minute candle history reports for day trading analysis.
|
|
3345
|
+
*
|
|
3346
|
+
* Provides detailed OHLCV analysis for the last 8 fifteen-minute candles with
|
|
3347
|
+
* candle pattern identification, volatility metrics, high-volatility detection,
|
|
3348
|
+
* and body size calculations.
|
|
3349
|
+
*
|
|
3350
|
+
* Key features:
|
|
3351
|
+
* - Last 8 fifteen-minute candles (2 hours of price action)
|
|
3352
|
+
* - OHLCV data with formatted prices and volumes
|
|
3353
|
+
* - Candle type identification (Green/Red/Doji)
|
|
3354
|
+
* - Volatility percentage calculations
|
|
3355
|
+
* - High-volatility detection (>1.5x average volatility)
|
|
3356
|
+
* - Body size percentage relative to candle range
|
|
3357
|
+
* - ISO timestamp formatting
|
|
3358
|
+
* - Dependency injection support
|
|
3359
|
+
*
|
|
3360
|
+
* @example
|
|
3361
|
+
* ```typescript
|
|
3362
|
+
* import { FifteenMinuteCandleHistoryService } from '@backtest-kit/signals';
|
|
3363
|
+
*
|
|
3364
|
+
* const service = new FifteenMinuteCandleHistoryService();
|
|
3365
|
+
*
|
|
3366
|
+
* // Get markdown report
|
|
3367
|
+
* const report = await service.getReport('BTCUSDT');
|
|
3368
|
+
* console.log(report);
|
|
3369
|
+
* // ## 15-Minute Candles History (Last 8)
|
|
3370
|
+
* // ### 15m Candle 1 (Green) HIGH-VOLATILITY
|
|
3371
|
+
* // - **Open**: 42000.50 USD
|
|
3372
|
+
* // - **15m Volatility**: 0.85%
|
|
3373
|
+
*
|
|
3374
|
+
* // Or get raw candle data
|
|
3375
|
+
* const candles = await service.getData('ETHUSDT');
|
|
3376
|
+
* console.log(candles.length); // 8
|
|
3377
|
+
* ```
|
|
3378
|
+
*/
|
|
2430
3379
|
class FifteenMinuteCandleHistoryService {
|
|
2431
3380
|
constructor() {
|
|
2432
3381
|
this.loggerService = inject(TYPES.loggerService);
|
|
3382
|
+
/**
|
|
3383
|
+
* Fetches last 8 fifteen-minute candles for a symbol.
|
|
3384
|
+
*
|
|
3385
|
+
* Retrieves recent 15-minute candles from exchange for day trading analysis.
|
|
3386
|
+
*
|
|
3387
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
3388
|
+
* @returns Array of 8 fifteen-minute candles
|
|
3389
|
+
*
|
|
3390
|
+
* @example
|
|
3391
|
+
* ```typescript
|
|
3392
|
+
* const candles = await service.getData('BTCUSDT');
|
|
3393
|
+
* console.log(candles.length); // 8
|
|
3394
|
+
* console.log(candles[0].close); // Latest candle close price
|
|
3395
|
+
* ```
|
|
3396
|
+
*/
|
|
2433
3397
|
this.getData = async (symbol) => {
|
|
2434
3398
|
this.loggerService.log("fifteenMinuteCandleHistoryService getData", { symbol });
|
|
2435
3399
|
return getCandles(symbol, "15m", RECENT_CANDLES$3);
|
|
2436
3400
|
};
|
|
3401
|
+
/**
|
|
3402
|
+
* Generates markdown report from candle data with volatility detection.
|
|
3403
|
+
*
|
|
3404
|
+
* Creates detailed markdown report with OHLCV data, candle patterns,
|
|
3405
|
+
* volatility metrics, and HIGH-VOLATILITY flags for candles exceeding
|
|
3406
|
+
* 1.5x the average volatility of all candles.
|
|
3407
|
+
*
|
|
3408
|
+
* @param symbol - Trading pair symbol for price formatting
|
|
3409
|
+
* @param candles - Array of candle data to analyze
|
|
3410
|
+
* @returns Markdown-formatted candle history report with volatility flags
|
|
3411
|
+
*
|
|
3412
|
+
* @example
|
|
3413
|
+
* ```typescript
|
|
3414
|
+
* const candles = await service.getData('BTCUSDT');
|
|
3415
|
+
* const report = await service.generateReport('BTCUSDT', candles);
|
|
3416
|
+
* console.log(report);
|
|
3417
|
+
* // ## 15-Minute Candles History (Last 8)
|
|
3418
|
+
* // ### 15m Candle 1 (Green) HIGH-VOLATILITY
|
|
3419
|
+
* // - **Open**: 42000.50 USD
|
|
3420
|
+
* ```
|
|
3421
|
+
*/
|
|
2437
3422
|
this.generateReport = async (symbol, candles) => {
|
|
2438
3423
|
this.loggerService.log("fifteenMinuteCandleHistoryService generateReport", { symbol });
|
|
2439
3424
|
const averageVolatility = candles.reduce((sum, candle) => sum + ((candle.high - candle.low) / candle.close) * 100, 0) / candles.length;
|
|
@@ -2466,6 +3451,28 @@ class FifteenMinuteCandleHistoryService {
|
|
|
2466
3451
|
}
|
|
2467
3452
|
return report;
|
|
2468
3453
|
};
|
|
3454
|
+
/**
|
|
3455
|
+
* Generates complete markdown candle history report for a symbol.
|
|
3456
|
+
*
|
|
3457
|
+
* Fetches last 8 fifteen-minute candles and formats them as markdown report
|
|
3458
|
+
* with OHLCV data, patterns, volatility flags, and metrics.
|
|
3459
|
+
*
|
|
3460
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
3461
|
+
* @returns Markdown-formatted candle history report with high-volatility detection
|
|
3462
|
+
*
|
|
3463
|
+
* @example
|
|
3464
|
+
* ```typescript
|
|
3465
|
+
* const report = await service.getReport('BTCUSDT');
|
|
3466
|
+
* console.log(report);
|
|
3467
|
+
* // ## 15-Minute Candles History (Last 8)
|
|
3468
|
+
* // > Current time: 2025-01-14T10:30:00.000Z
|
|
3469
|
+
* //
|
|
3470
|
+
* // ### 15m Candle 1 (Green) HIGH-VOLATILITY
|
|
3471
|
+
* // - **Time**: 2025-01-14T10:15:00.000Z
|
|
3472
|
+
* // - **Open**: 42000.50 USD
|
|
3473
|
+
* // - **15m Volatility**: 0.85%
|
|
3474
|
+
* ```
|
|
3475
|
+
*/
|
|
2469
3476
|
this.getReport = async (symbol) => {
|
|
2470
3477
|
this.loggerService.log("fifteenMinuteCandleHistoryService getReport", { symbol });
|
|
2471
3478
|
const candles = await this.getData(symbol);
|
|
@@ -2474,14 +3481,99 @@ class FifteenMinuteCandleHistoryService {
|
|
|
2474
3481
|
}
|
|
2475
3482
|
}
|
|
2476
3483
|
|
|
3484
|
+
/**
|
|
3485
|
+
* Hourly candle history service for trend analysis.
|
|
3486
|
+
*
|
|
3487
|
+
* Generates markdown reports of the last 6 hourly candles including:
|
|
3488
|
+
* - OHLCV data
|
|
3489
|
+
* - Candle type (Green/Red/Doji)
|
|
3490
|
+
* - Volatility percentage
|
|
3491
|
+
* - Body size percentage
|
|
3492
|
+
* - Timestamp
|
|
3493
|
+
*
|
|
3494
|
+
* Used by commitHourHistory() for LLM context injection.
|
|
3495
|
+
*/
|
|
3496
|
+
/**
|
|
3497
|
+
* Number of recent candles to include in history report.
|
|
3498
|
+
* Provides 6-hour price action context for long-term trading decisions.
|
|
3499
|
+
*/
|
|
2477
3500
|
const RECENT_CANDLES$2 = 6;
|
|
3501
|
+
/**
|
|
3502
|
+
* Service for generating 1-hour candle history reports for trend analysis.
|
|
3503
|
+
*
|
|
3504
|
+
* Provides detailed OHLCV analysis for the last 6 hourly candles with
|
|
3505
|
+
* candle pattern identification, volatility metrics, and body size calculations.
|
|
3506
|
+
*
|
|
3507
|
+
* Key features:
|
|
3508
|
+
* - Last 6 hourly candles (6 hours of price action)
|
|
3509
|
+
* - OHLCV data with formatted prices and volumes
|
|
3510
|
+
* - Candle type identification (Green/Red/Doji)
|
|
3511
|
+
* - Volatility percentage calculations
|
|
3512
|
+
* - Body size percentage relative to candle range
|
|
3513
|
+
* - ISO timestamp formatting
|
|
3514
|
+
* - Dependency injection support
|
|
3515
|
+
*
|
|
3516
|
+
* @example
|
|
3517
|
+
* ```typescript
|
|
3518
|
+
* import { HourCandleHistoryService } from '@backtest-kit/signals';
|
|
3519
|
+
*
|
|
3520
|
+
* const service = new HourCandleHistoryService();
|
|
3521
|
+
*
|
|
3522
|
+
* // Get markdown report
|
|
3523
|
+
* const report = await service.getReport('BTCUSDT');
|
|
3524
|
+
* console.log(report);
|
|
3525
|
+
* // ## Hourly Candles History (Last 6)
|
|
3526
|
+
* // ### 1h Candle 1 (Green)
|
|
3527
|
+
* // - **Open**: 42000.50 USD
|
|
3528
|
+
* // - **1h Volatility**: 2.15%
|
|
3529
|
+
*
|
|
3530
|
+
* // Or get raw candle data
|
|
3531
|
+
* const candles = await service.getData('ETHUSDT');
|
|
3532
|
+
* console.log(candles.length); // 6
|
|
3533
|
+
* ```
|
|
3534
|
+
*/
|
|
2478
3535
|
class HourCandleHistoryService {
|
|
2479
3536
|
constructor() {
|
|
2480
3537
|
this.loggerService = inject(TYPES.loggerService);
|
|
3538
|
+
/**
|
|
3539
|
+
* Fetches last 6 hourly candles for a symbol.
|
|
3540
|
+
*
|
|
3541
|
+
* Retrieves recent 1-hour candles from exchange for trend analysis.
|
|
3542
|
+
*
|
|
3543
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
3544
|
+
* @returns Array of 6 hourly candles
|
|
3545
|
+
*
|
|
3546
|
+
* @example
|
|
3547
|
+
* ```typescript
|
|
3548
|
+
* const candles = await service.getData('BTCUSDT');
|
|
3549
|
+
* console.log(candles.length); // 6
|
|
3550
|
+
* console.log(candles[0].close); // Latest candle close price
|
|
3551
|
+
* ```
|
|
3552
|
+
*/
|
|
2481
3553
|
this.getData = async (symbol) => {
|
|
2482
3554
|
this.loggerService.log("hourCandleHistoryService getData", { symbol });
|
|
2483
3555
|
return getCandles(symbol, "1h", RECENT_CANDLES$2);
|
|
2484
3556
|
};
|
|
3557
|
+
/**
|
|
3558
|
+
* Generates markdown report from candle data.
|
|
3559
|
+
*
|
|
3560
|
+
* Creates detailed markdown report with OHLCV data, candle patterns,
|
|
3561
|
+
* volatility metrics, and body size percentages for each candle.
|
|
3562
|
+
*
|
|
3563
|
+
* @param symbol - Trading pair symbol for price formatting
|
|
3564
|
+
* @param candles - Array of candle data to analyze
|
|
3565
|
+
* @returns Markdown-formatted candle history report
|
|
3566
|
+
*
|
|
3567
|
+
* @example
|
|
3568
|
+
* ```typescript
|
|
3569
|
+
* const candles = await service.getData('BTCUSDT');
|
|
3570
|
+
* const report = await service.generateReport('BTCUSDT', candles);
|
|
3571
|
+
* console.log(report);
|
|
3572
|
+
* // ## Hourly Candles History (Last 6)
|
|
3573
|
+
* // ### 1h Candle 1 (Green)
|
|
3574
|
+
* // - **Open**: 42000.50 USD
|
|
3575
|
+
* ```
|
|
3576
|
+
*/
|
|
2485
3577
|
this.generateReport = async (symbol, candles) => {
|
|
2486
3578
|
this.loggerService.log("hourCandleHistoryService generateReport", { symbol });
|
|
2487
3579
|
let markdown = "";
|
|
@@ -2512,6 +3604,28 @@ class HourCandleHistoryService {
|
|
|
2512
3604
|
}
|
|
2513
3605
|
return markdown;
|
|
2514
3606
|
};
|
|
3607
|
+
/**
|
|
3608
|
+
* Generates complete markdown candle history report for a symbol.
|
|
3609
|
+
*
|
|
3610
|
+
* Fetches last 6 hourly candles and formats them as markdown report
|
|
3611
|
+
* with OHLCV data, patterns, and metrics.
|
|
3612
|
+
*
|
|
3613
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
3614
|
+
* @returns Markdown-formatted candle history report
|
|
3615
|
+
*
|
|
3616
|
+
* @example
|
|
3617
|
+
* ```typescript
|
|
3618
|
+
* const report = await service.getReport('BTCUSDT');
|
|
3619
|
+
* console.log(report);
|
|
3620
|
+
* // ## Hourly Candles History (Last 6)
|
|
3621
|
+
* // > Current time: 2025-01-14T10:30:00.000Z
|
|
3622
|
+
* //
|
|
3623
|
+
* // ### 1h Candle 1 (Green)
|
|
3624
|
+
* // - **Time**: 2025-01-14T10:00:00.000Z
|
|
3625
|
+
* // - **Open**: 42000.50 USD
|
|
3626
|
+
* // - **1h Volatility**: 2.15%
|
|
3627
|
+
* ```
|
|
3628
|
+
*/
|
|
2515
3629
|
this.getReport = async (symbol) => {
|
|
2516
3630
|
this.loggerService.log("hourCandleHistoryService getReport", { symbol });
|
|
2517
3631
|
const candles = await this.getData(symbol);
|
|
@@ -2520,14 +3634,99 @@ class HourCandleHistoryService {
|
|
|
2520
3634
|
}
|
|
2521
3635
|
}
|
|
2522
3636
|
|
|
3637
|
+
/**
|
|
3638
|
+
* One-minute candle history service for ultra-short term analysis.
|
|
3639
|
+
*
|
|
3640
|
+
* Generates markdown reports of the last 15 one-minute candles including:
|
|
3641
|
+
* - OHLCV data (Open, High, Low, Close, Volume)
|
|
3642
|
+
* - Candle type (Green/Red/Doji)
|
|
3643
|
+
* - Volatility percentage
|
|
3644
|
+
* - Body size percentage
|
|
3645
|
+
* - Timestamp
|
|
3646
|
+
*
|
|
3647
|
+
* Used by commitOneMinuteHistory() for LLM context injection.
|
|
3648
|
+
*/
|
|
3649
|
+
/**
|
|
3650
|
+
* Number of recent candles to include in history report.
|
|
3651
|
+
* Provides 15-minute price action context for scalping decisions.
|
|
3652
|
+
*/
|
|
2523
3653
|
const RECENT_CANDLES$1 = 15;
|
|
3654
|
+
/**
|
|
3655
|
+
* Service for generating 1-minute candle history reports for scalping analysis.
|
|
3656
|
+
*
|
|
3657
|
+
* Provides detailed OHLCV analysis for the last 15 one-minute candles with
|
|
3658
|
+
* candle pattern identification, volatility metrics, and body size calculations.
|
|
3659
|
+
*
|
|
3660
|
+
* Key features:
|
|
3661
|
+
* - Last 15 one-minute candles (15 minutes of price action)
|
|
3662
|
+
* - OHLCV data with formatted prices and volumes
|
|
3663
|
+
* - Candle type identification (Green/Red/Doji)
|
|
3664
|
+
* - Volatility percentage calculations
|
|
3665
|
+
* - Body size percentage relative to candle range
|
|
3666
|
+
* - ISO timestamp formatting
|
|
3667
|
+
* - Dependency injection support
|
|
3668
|
+
*
|
|
3669
|
+
* @example
|
|
3670
|
+
* ```typescript
|
|
3671
|
+
* import { OneMinuteCandleHistoryService } from '@backtest-kit/signals';
|
|
3672
|
+
*
|
|
3673
|
+
* const service = new OneMinuteCandleHistoryService();
|
|
3674
|
+
*
|
|
3675
|
+
* // Get markdown report
|
|
3676
|
+
* const report = await service.getReport('BTCUSDT');
|
|
3677
|
+
* console.log(report);
|
|
3678
|
+
* // ## One-Minute Candles History (Last 15)
|
|
3679
|
+
* // ### 1m Candle 1 (Green)
|
|
3680
|
+
* // - **Open**: 42000.50 USD
|
|
3681
|
+
* // - **1m Volatility**: 0.15%
|
|
3682
|
+
*
|
|
3683
|
+
* // Or get raw candle data
|
|
3684
|
+
* const candles = await service.getData('ETHUSDT');
|
|
3685
|
+
* console.log(candles.length); // 15
|
|
3686
|
+
* ```
|
|
3687
|
+
*/
|
|
2524
3688
|
class OneMinuteCandleHistoryService {
|
|
2525
3689
|
constructor() {
|
|
2526
3690
|
this.loggerService = inject(TYPES.loggerService);
|
|
3691
|
+
/**
|
|
3692
|
+
* Fetches last 15 one-minute candles for a symbol.
|
|
3693
|
+
*
|
|
3694
|
+
* Retrieves recent 1-minute candles from exchange for scalping analysis.
|
|
3695
|
+
*
|
|
3696
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
3697
|
+
* @returns Array of 15 one-minute candles
|
|
3698
|
+
*
|
|
3699
|
+
* @example
|
|
3700
|
+
* ```typescript
|
|
3701
|
+
* const candles = await service.getData('BTCUSDT');
|
|
3702
|
+
* console.log(candles.length); // 15
|
|
3703
|
+
* console.log(candles[0].close); // Latest candle close price
|
|
3704
|
+
* ```
|
|
3705
|
+
*/
|
|
2527
3706
|
this.getData = async (symbol) => {
|
|
2528
3707
|
this.loggerService.log("oneMinuteCandleHistoryService getData", { symbol });
|
|
2529
3708
|
return getCandles(symbol, "1m", RECENT_CANDLES$1);
|
|
2530
3709
|
};
|
|
3710
|
+
/**
|
|
3711
|
+
* Generates markdown report from candle data.
|
|
3712
|
+
*
|
|
3713
|
+
* Creates detailed markdown report with OHLCV data, candle patterns,
|
|
3714
|
+
* volatility metrics, and body size percentages for each candle.
|
|
3715
|
+
*
|
|
3716
|
+
* @param symbol - Trading pair symbol for price formatting
|
|
3717
|
+
* @param candles - Array of candle data to analyze
|
|
3718
|
+
* @returns Markdown-formatted candle history report
|
|
3719
|
+
*
|
|
3720
|
+
* @example
|
|
3721
|
+
* ```typescript
|
|
3722
|
+
* const candles = await service.getData('BTCUSDT');
|
|
3723
|
+
* const report = await service.generateReport('BTCUSDT', candles);
|
|
3724
|
+
* console.log(report);
|
|
3725
|
+
* // ## One-Minute Candles History (Last 15)
|
|
3726
|
+
* // ### 1m Candle 1 (Green)
|
|
3727
|
+
* // - **Open**: 42000.50 USD
|
|
3728
|
+
* ```
|
|
3729
|
+
*/
|
|
2531
3730
|
this.generateReport = async (symbol, candles) => {
|
|
2532
3731
|
this.loggerService.log("oneMinuteCandleHistoryService generateReport", { symbol });
|
|
2533
3732
|
let markdown = "";
|
|
@@ -2554,6 +3753,28 @@ class OneMinuteCandleHistoryService {
|
|
|
2554
3753
|
}
|
|
2555
3754
|
return markdown;
|
|
2556
3755
|
};
|
|
3756
|
+
/**
|
|
3757
|
+
* Generates complete markdown candle history report for a symbol.
|
|
3758
|
+
*
|
|
3759
|
+
* Fetches last 15 one-minute candles and formats them as markdown report
|
|
3760
|
+
* with OHLCV data, patterns, and metrics.
|
|
3761
|
+
*
|
|
3762
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
3763
|
+
* @returns Markdown-formatted candle history report
|
|
3764
|
+
*
|
|
3765
|
+
* @example
|
|
3766
|
+
* ```typescript
|
|
3767
|
+
* const report = await service.getReport('BTCUSDT');
|
|
3768
|
+
* console.log(report);
|
|
3769
|
+
* // ## One-Minute Candles History (Last 15)
|
|
3770
|
+
* // > Current time: 2025-01-14T10:30:00.000Z
|
|
3771
|
+
* //
|
|
3772
|
+
* // ### 1m Candle 1 (Green)
|
|
3773
|
+
* // - **Time**: 2025-01-14T10:29:00.000Z
|
|
3774
|
+
* // - **Open**: 42000.50 USD
|
|
3775
|
+
* // - **1m Volatility**: 0.15%
|
|
3776
|
+
* ```
|
|
3777
|
+
*/
|
|
2557
3778
|
this.getReport = async (symbol) => {
|
|
2558
3779
|
this.loggerService.log("oneMinuteCandleHistoryService getReport", { symbol });
|
|
2559
3780
|
const candles = await this.getData(symbol);
|
|
@@ -2562,14 +3783,99 @@ class OneMinuteCandleHistoryService {
|
|
|
2562
3783
|
}
|
|
2563
3784
|
}
|
|
2564
3785
|
|
|
3786
|
+
/**
|
|
3787
|
+
* Thirty-minute candle history service for swing trading analysis.
|
|
3788
|
+
*
|
|
3789
|
+
* Generates markdown reports of the last 6 thirty-minute candles including:
|
|
3790
|
+
* - OHLCV data
|
|
3791
|
+
* - Candle type (Green/Red/Doji)
|
|
3792
|
+
* - Volatility percentage
|
|
3793
|
+
* - Body size percentage
|
|
3794
|
+
* - Timestamp
|
|
3795
|
+
*
|
|
3796
|
+
* Used by commitThirtyMinuteHistory() for LLM context injection.
|
|
3797
|
+
*/
|
|
3798
|
+
/**
|
|
3799
|
+
* Number of recent candles to include in history report.
|
|
3800
|
+
* Provides 3-hour price action context for swing trading decisions.
|
|
3801
|
+
*/
|
|
2565
3802
|
const RECENT_CANDLES = 6;
|
|
3803
|
+
/**
|
|
3804
|
+
* Service for generating 30-minute candle history reports for swing trading analysis.
|
|
3805
|
+
*
|
|
3806
|
+
* Provides detailed OHLCV analysis for the last 6 thirty-minute candles with
|
|
3807
|
+
* candle pattern identification, volatility metrics, and body size calculations.
|
|
3808
|
+
*
|
|
3809
|
+
* Key features:
|
|
3810
|
+
* - Last 6 thirty-minute candles (3 hours of price action)
|
|
3811
|
+
* - OHLCV data with formatted prices and volumes
|
|
3812
|
+
* - Candle type identification (Green/Red/Doji)
|
|
3813
|
+
* - Volatility percentage calculations
|
|
3814
|
+
* - Body size percentage relative to candle range
|
|
3815
|
+
* - ISO timestamp formatting
|
|
3816
|
+
* - Dependency injection support
|
|
3817
|
+
*
|
|
3818
|
+
* @example
|
|
3819
|
+
* ```typescript
|
|
3820
|
+
* import { ThirtyMinuteCandleHistoryService } from '@backtest-kit/signals';
|
|
3821
|
+
*
|
|
3822
|
+
* const service = new ThirtyMinuteCandleHistoryService();
|
|
3823
|
+
*
|
|
3824
|
+
* // Get markdown report
|
|
3825
|
+
* const report = await service.getReport('BTCUSDT');
|
|
3826
|
+
* console.log(report);
|
|
3827
|
+
* // ## 30-Min Candles History (Last 6)
|
|
3828
|
+
* // ### 30m Candle 1 (Green)
|
|
3829
|
+
* // - **Open**: 42000.50 USD
|
|
3830
|
+
* // - **30m Volatility**: 1.25%
|
|
3831
|
+
*
|
|
3832
|
+
* // Or get raw candle data
|
|
3833
|
+
* const candles = await service.getData('ETHUSDT');
|
|
3834
|
+
* console.log(candles.length); // 6
|
|
3835
|
+
* ```
|
|
3836
|
+
*/
|
|
2566
3837
|
class ThirtyMinuteCandleHistoryService {
|
|
2567
3838
|
constructor() {
|
|
2568
3839
|
this.loggerService = inject(TYPES.loggerService);
|
|
3840
|
+
/**
|
|
3841
|
+
* Fetches last 6 thirty-minute candles for a symbol.
|
|
3842
|
+
*
|
|
3843
|
+
* Retrieves recent 30-minute candles from exchange for analysis.
|
|
3844
|
+
*
|
|
3845
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
3846
|
+
* @returns Array of 6 thirty-minute candles
|
|
3847
|
+
*
|
|
3848
|
+
* @example
|
|
3849
|
+
* ```typescript
|
|
3850
|
+
* const candles = await service.getData('BTCUSDT');
|
|
3851
|
+
* console.log(candles.length); // 6
|
|
3852
|
+
* console.log(candles[0].close); // Latest candle close price
|
|
3853
|
+
* ```
|
|
3854
|
+
*/
|
|
2569
3855
|
this.getData = async (symbol) => {
|
|
2570
3856
|
this.loggerService.log("thirtyMinuteCandleHistoryService getData", { symbol });
|
|
2571
3857
|
return getCandles(symbol, "30m", RECENT_CANDLES);
|
|
2572
3858
|
};
|
|
3859
|
+
/**
|
|
3860
|
+
* Generates markdown report from candle data.
|
|
3861
|
+
*
|
|
3862
|
+
* Creates detailed markdown report with OHLCV data, candle patterns,
|
|
3863
|
+
* volatility metrics, and body size percentages for each candle.
|
|
3864
|
+
*
|
|
3865
|
+
* @param symbol - Trading pair symbol for price formatting
|
|
3866
|
+
* @param candles - Array of candle data to analyze
|
|
3867
|
+
* @returns Markdown-formatted candle history report
|
|
3868
|
+
*
|
|
3869
|
+
* @example
|
|
3870
|
+
* ```typescript
|
|
3871
|
+
* const candles = await service.getData('BTCUSDT');
|
|
3872
|
+
* const report = await service.generateReport('BTCUSDT', candles);
|
|
3873
|
+
* console.log(report);
|
|
3874
|
+
* // ## 30-Min Candles History (Last 6)
|
|
3875
|
+
* // ### 30m Candle 1 (Green)
|
|
3876
|
+
* // - **Open**: 42000.50 USD
|
|
3877
|
+
* ```
|
|
3878
|
+
*/
|
|
2573
3879
|
this.generateReport = async (symbol, candles) => {
|
|
2574
3880
|
this.loggerService.log("thirtyMinuteCandleHistoryService generateReport", { symbol });
|
|
2575
3881
|
let report = "";
|
|
@@ -2600,6 +3906,28 @@ class ThirtyMinuteCandleHistoryService {
|
|
|
2600
3906
|
}
|
|
2601
3907
|
return report;
|
|
2602
3908
|
};
|
|
3909
|
+
/**
|
|
3910
|
+
* Generates complete markdown candle history report for a symbol.
|
|
3911
|
+
*
|
|
3912
|
+
* Fetches last 6 thirty-minute candles and formats them as markdown report
|
|
3913
|
+
* with OHLCV data, patterns, and metrics.
|
|
3914
|
+
*
|
|
3915
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
3916
|
+
* @returns Markdown-formatted candle history report
|
|
3917
|
+
*
|
|
3918
|
+
* @example
|
|
3919
|
+
* ```typescript
|
|
3920
|
+
* const report = await service.getReport('BTCUSDT');
|
|
3921
|
+
* console.log(report);
|
|
3922
|
+
* // ## 30-Min Candles History (Last 6)
|
|
3923
|
+
* // > Current time: 2025-01-14T10:30:00.000Z
|
|
3924
|
+
* //
|
|
3925
|
+
* // ### 30m Candle 1 (Green)
|
|
3926
|
+
* // - **Time**: 2025-01-14T10:00:00.000Z
|
|
3927
|
+
* // - **Open**: 42000.50 USD
|
|
3928
|
+
* // - **30m Volatility**: 1.25%
|
|
3929
|
+
* ```
|
|
3930
|
+
*/
|
|
2603
3931
|
this.getReport = async (symbol) => {
|
|
2604
3932
|
this.loggerService.log("thirtyMinuteCandleHistoryService getReport", { symbol });
|
|
2605
3933
|
const candles = await this.getData(symbol);
|
|
@@ -2608,6 +3936,46 @@ class ThirtyMinuteCandleHistoryService {
|
|
|
2608
3936
|
}
|
|
2609
3937
|
}
|
|
2610
3938
|
|
|
3939
|
+
/**
|
|
3940
|
+
* Order book analysis service for real-time market depth and liquidity assessment.
|
|
3941
|
+
*
|
|
3942
|
+
* Generates comprehensive order book reports including:
|
|
3943
|
+
* - Top 20 bid/ask levels sorted by volume percentage
|
|
3944
|
+
* - Best bid/ask prices
|
|
3945
|
+
* - Mid price and spread
|
|
3946
|
+
* - Depth imbalance (buy vs sell pressure indicator)
|
|
3947
|
+
*
|
|
3948
|
+
* Depth Imbalance Formula:
|
|
3949
|
+
* (Total Bid Volume - Total Ask Volume) / (Total Bid Volume + Total Ask Volume)
|
|
3950
|
+
* - Positive: Buy pressure (more bids)
|
|
3951
|
+
* - Negative: Sell pressure (more asks)
|
|
3952
|
+
* - Zero: Balanced market
|
|
3953
|
+
*
|
|
3954
|
+
* Used by commitBookDataReport() for LLM context injection.
|
|
3955
|
+
* Only available in live mode (skipped in backtest mode).
|
|
3956
|
+
*/
|
|
3957
|
+
/**
|
|
3958
|
+
* Maximum order book depth levels to fetch for accurate metrics.
|
|
3959
|
+
* Provides comprehensive liquidity view for depth imbalance calculation.
|
|
3960
|
+
*/
|
|
3961
|
+
const MAX_DEPTH_LEVELS = 1000;
|
|
3962
|
+
/**
|
|
3963
|
+
* Validates whether a numeric value is safe for calculations.
|
|
3964
|
+
*
|
|
3965
|
+
* Checks if value is a valid finite number. Returns true if value is null,
|
|
3966
|
+
* NaN, Infinity, or not a number type.
|
|
3967
|
+
*
|
|
3968
|
+
* @param value - Value to validate
|
|
3969
|
+
* @returns True if value is unsafe (null/NaN/Infinity), false if valid number
|
|
3970
|
+
*
|
|
3971
|
+
* @example
|
|
3972
|
+
* ```typescript
|
|
3973
|
+
* isUnsafe(42) // false - valid number
|
|
3974
|
+
* isUnsafe(null) // true - null value
|
|
3975
|
+
* isUnsafe(NaN) // true - not a number
|
|
3976
|
+
* isUnsafe(Infinity) // true - infinite value
|
|
3977
|
+
* ```
|
|
3978
|
+
*/
|
|
2611
3979
|
function isUnsafe(value) {
|
|
2612
3980
|
if (typeof value !== "number") {
|
|
2613
3981
|
return true;
|
|
@@ -2620,7 +3988,28 @@ function isUnsafe(value) {
|
|
|
2620
3988
|
}
|
|
2621
3989
|
return false;
|
|
2622
3990
|
}
|
|
2623
|
-
|
|
3991
|
+
/**
|
|
3992
|
+
* Processes one side of order book (bids or asks) and calculates volume percentages.
|
|
3993
|
+
*
|
|
3994
|
+
* Converts raw bid/ask data to structured entries with volume percentage calculations.
|
|
3995
|
+
* Each entry's percentage represents its share of total side volume.
|
|
3996
|
+
*
|
|
3997
|
+
* @param orders - Raw order book entries from exchange API
|
|
3998
|
+
* @returns Processed entries with price, quantity, and volume percentage
|
|
3999
|
+
*
|
|
4000
|
+
* @example
|
|
4001
|
+
* ```typescript
|
|
4002
|
+
* const rawBids = [
|
|
4003
|
+
* { price: "42000", quantity: "1.5" },
|
|
4004
|
+
* { price: "41999", quantity: "0.5" }
|
|
4005
|
+
* ];
|
|
4006
|
+
* const processed = processOrderBookSide(rawBids);
|
|
4007
|
+
* // [
|
|
4008
|
+
* // { price: 42000, quantity: 1.5, percentage: 75.0 },
|
|
4009
|
+
* // { price: 41999, quantity: 0.5, percentage: 25.0 }
|
|
4010
|
+
* // ]
|
|
4011
|
+
* ```
|
|
4012
|
+
*/
|
|
2624
4013
|
function processOrderBookSide(orders) {
|
|
2625
4014
|
const entries = orders.map((order) => ({
|
|
2626
4015
|
price: parseFloat(order.price),
|
|
@@ -2635,7 +4024,34 @@ function processOrderBookSide(orders) {
|
|
|
2635
4024
|
});
|
|
2636
4025
|
return entries;
|
|
2637
4026
|
}
|
|
2638
|
-
|
|
4027
|
+
/**
|
|
4028
|
+
* Generates markdown-formatted order book report with depth analysis.
|
|
4029
|
+
*
|
|
4030
|
+
* Creates comprehensive markdown report including:
|
|
4031
|
+
* - Order book summary (best bid/ask, mid price, spread, depth imbalance)
|
|
4032
|
+
* - Top 20 bid levels sorted by volume percentage
|
|
4033
|
+
* - Top 20 ask levels sorted by volume percentage
|
|
4034
|
+
* - Formatted prices and quantities with proper USD notation
|
|
4035
|
+
*
|
|
4036
|
+
* Output is optimized for LLM consumption in trading signal generation.
|
|
4037
|
+
*
|
|
4038
|
+
* @param self - Service instance for logging context
|
|
4039
|
+
* @param result - Order book analysis data with calculated metrics
|
|
4040
|
+
* @returns Markdown-formatted order book report
|
|
4041
|
+
*
|
|
4042
|
+
* @example
|
|
4043
|
+
* ```typescript
|
|
4044
|
+
* const analysis = await service.getData('BTCUSDT');
|
|
4045
|
+
* const report = await generateBookDataReport(service, analysis);
|
|
4046
|
+
* console.log(report);
|
|
4047
|
+
* // # Order Book Analysis for BTCUSDT
|
|
4048
|
+
* // > Current time: 2025-01-14T10:30:00.000Z
|
|
4049
|
+
* // ## Order Book Summary
|
|
4050
|
+
* // - **Best Bid**: 42000.50 USD
|
|
4051
|
+
* // - **Best Ask**: 42001.25 USD
|
|
4052
|
+
* // - **Depth Imbalance**: 12.5%
|
|
4053
|
+
* ```
|
|
4054
|
+
*/
|
|
2639
4055
|
const generateBookDataReport = async (self, result) => {
|
|
2640
4056
|
const currentData = await getDate();
|
|
2641
4057
|
let markdown = `# Order Book Analysis for ${result.symbol}\n`;
|
|
@@ -2700,15 +4116,88 @@ const generateBookDataReport = async (self, result) => {
|
|
|
2700
4116
|
markdown += `\n`;
|
|
2701
4117
|
return markdown;
|
|
2702
4118
|
};
|
|
4119
|
+
/**
|
|
4120
|
+
* Service for order book analysis and markdown report generation.
|
|
4121
|
+
*
|
|
4122
|
+
* Provides real-time order book depth analysis with market liquidity metrics
|
|
4123
|
+
* including bid/ask levels, depth imbalance, spread, and volume distribution.
|
|
4124
|
+
*
|
|
4125
|
+
* Key features:
|
|
4126
|
+
* - Fetches up to 1000 order book depth levels
|
|
4127
|
+
* - Calculates best bid/ask, mid price, and spread
|
|
4128
|
+
* - Computes depth imbalance (buy vs sell pressure)
|
|
4129
|
+
* - Analyzes volume distribution with percentage calculations
|
|
4130
|
+
* - Generates markdown reports with top 20 levels
|
|
4131
|
+
* - Only available in live mode (skipped in backtest)
|
|
4132
|
+
* - Dependency injection support
|
|
4133
|
+
*
|
|
4134
|
+
* @example
|
|
4135
|
+
* ```typescript
|
|
4136
|
+
* import { BookDataMathService } from '@backtest-kit/signals';
|
|
4137
|
+
*
|
|
4138
|
+
* const service = new BookDataMathService();
|
|
4139
|
+
*
|
|
4140
|
+
* // Get markdown report (fetches order book internally)
|
|
4141
|
+
* const report = await service.getReport('BTCUSDT');
|
|
4142
|
+
* console.log(report); // Markdown with top 20 bid/ask levels
|
|
4143
|
+
*
|
|
4144
|
+
* // Or analyze custom order book data
|
|
4145
|
+
* const analysis = await service.getData('ETHUSDT');
|
|
4146
|
+
* console.log(analysis.depthImbalance); // 0.125 (12.5% buy pressure)
|
|
4147
|
+
* console.log(analysis.bestBid); // 2300.50
|
|
4148
|
+
* ```
|
|
4149
|
+
*/
|
|
2703
4150
|
class BookDataMathService {
|
|
2704
4151
|
constructor() {
|
|
2705
4152
|
this.loggerService = inject(TYPES.loggerService);
|
|
4153
|
+
/**
|
|
4154
|
+
* Converts order book analysis into markdown report format.
|
|
4155
|
+
*
|
|
4156
|
+
* Takes pre-calculated order book analysis and formats it as markdown
|
|
4157
|
+
* with summary metrics and top 20 bid/ask levels sorted by volume.
|
|
4158
|
+
*
|
|
4159
|
+
* @param symbol - Trading pair symbol for header
|
|
4160
|
+
* @param bookData - Order book analysis from getData()
|
|
4161
|
+
* @returns Markdown-formatted order book report
|
|
4162
|
+
*
|
|
4163
|
+
* @example
|
|
4164
|
+
* ```typescript
|
|
4165
|
+
* const analysis = await service.getData('BTCUSDT');
|
|
4166
|
+
* const report = await service.generateReport('BTCUSDT', analysis);
|
|
4167
|
+
* console.log(report); // Markdown table with order book data
|
|
4168
|
+
* ```
|
|
4169
|
+
*/
|
|
2706
4170
|
this.generateReport = async (symbol, bookData) => {
|
|
2707
4171
|
this.loggerService.log("bookDataMathService generateReport", {
|
|
2708
4172
|
symbol,
|
|
2709
4173
|
});
|
|
2710
4174
|
return await generateBookDataReport(this, bookData);
|
|
2711
4175
|
};
|
|
4176
|
+
/**
|
|
4177
|
+
* Generates complete markdown order book report for a symbol.
|
|
4178
|
+
*
|
|
4179
|
+
* Fetches order book depth (up to 1000 levels) from exchange, calculates all metrics,
|
|
4180
|
+
* and formats results as markdown report optimized for LLM consumption.
|
|
4181
|
+
*
|
|
4182
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
4183
|
+
* @returns Markdown-formatted order book report with depth analysis
|
|
4184
|
+
*
|
|
4185
|
+
* @example
|
|
4186
|
+
* ```typescript
|
|
4187
|
+
* const report = await service.getReport('BTCUSDT');
|
|
4188
|
+
* console.log(report);
|
|
4189
|
+
* // # Order Book Analysis for BTCUSDT
|
|
4190
|
+
* // > Current time: 2025-01-14T10:30:00.000Z
|
|
4191
|
+
* //
|
|
4192
|
+
* // ## Order Book Summary
|
|
4193
|
+
* // - **Best Bid**: 42000.50 USD
|
|
4194
|
+
* // - **Depth Imbalance**: 12.5%
|
|
4195
|
+
* //
|
|
4196
|
+
* // ## Top 20 Order Book Levels
|
|
4197
|
+
* // ### Bids (Buy Orders)
|
|
4198
|
+
* // | Price | Quantity | % of Total |
|
|
4199
|
+
* ```
|
|
4200
|
+
*/
|
|
2712
4201
|
this.getReport = async (symbol) => {
|
|
2713
4202
|
this.loggerService.log("bookDataMathService getReport", {
|
|
2714
4203
|
symbol,
|
|
@@ -2716,6 +4205,26 @@ class BookDataMathService {
|
|
|
2716
4205
|
const bookData = await this.getData(symbol);
|
|
2717
4206
|
return await this.generateReport(symbol, bookData);
|
|
2718
4207
|
};
|
|
4208
|
+
/**
|
|
4209
|
+
* Fetches and analyzes order book data with depth metrics.
|
|
4210
|
+
*
|
|
4211
|
+
* Retrieves up to 1000 depth levels from exchange, processes bid/ask data,
|
|
4212
|
+
* calculates volume percentages, and computes market depth metrics including
|
|
4213
|
+
* best bid/ask, mid price, spread, and depth imbalance.
|
|
4214
|
+
*
|
|
4215
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
4216
|
+
* @returns Order book analysis with all calculated metrics
|
|
4217
|
+
*
|
|
4218
|
+
* @example
|
|
4219
|
+
* ```typescript
|
|
4220
|
+
* const analysis = await service.getData('BTCUSDT');
|
|
4221
|
+
* console.log(analysis.bestBid); // 42000.50
|
|
4222
|
+
* console.log(analysis.bestAsk); // 42001.25
|
|
4223
|
+
* console.log(analysis.spread); // 0.75
|
|
4224
|
+
* console.log(analysis.depthImbalance); // 0.125 (12.5% buy pressure)
|
|
4225
|
+
* console.log(analysis.bids.length); // Up to 1000 levels
|
|
4226
|
+
* ```
|
|
4227
|
+
*/
|
|
2719
4228
|
this.getData = async (symbol) => {
|
|
2720
4229
|
this.loggerService.log("bookDataMathService getBookDataAnalysis", {
|
|
2721
4230
|
symbol,
|
|
@@ -2749,6 +4258,28 @@ class BookDataMathService {
|
|
|
2749
4258
|
}
|
|
2750
4259
|
}
|
|
2751
4260
|
|
|
4261
|
+
/**
|
|
4262
|
+
* Logger service for signals library diagnostic output.
|
|
4263
|
+
*
|
|
4264
|
+
* Provides logging capabilities with a no-op default implementation.
|
|
4265
|
+
* Use setLogger() from the public API to enable actual logging output.
|
|
4266
|
+
*
|
|
4267
|
+
* @example
|
|
4268
|
+
* ```typescript
|
|
4269
|
+
* import { setLogger } from '@backtest-kit/signals';
|
|
4270
|
+
*
|
|
4271
|
+
* setLogger({
|
|
4272
|
+
* log: console.log,
|
|
4273
|
+
* debug: console.debug,
|
|
4274
|
+
* info: console.info,
|
|
4275
|
+
* warn: console.warn,
|
|
4276
|
+
* });
|
|
4277
|
+
* ```
|
|
4278
|
+
*/
|
|
4279
|
+
/**
|
|
4280
|
+
* No-op logger implementation that discards all log calls.
|
|
4281
|
+
* Used as default to avoid polluting console output.
|
|
4282
|
+
*/
|
|
2752
4283
|
const NOOP_LOGGER = {
|
|
2753
4284
|
log() {
|
|
2754
4285
|
},
|
|
@@ -2759,30 +4290,133 @@ const NOOP_LOGGER = {
|
|
|
2759
4290
|
warn() {
|
|
2760
4291
|
},
|
|
2761
4292
|
};
|
|
4293
|
+
/**
|
|
4294
|
+
* Logger service implementation with configurable backend.
|
|
4295
|
+
*
|
|
4296
|
+
* Delegates all logging calls to the configured logger implementation.
|
|
4297
|
+
* Defaults to NOOP_LOGGER which discards all output.
|
|
4298
|
+
*/
|
|
2762
4299
|
class LoggerService {
|
|
2763
4300
|
constructor() {
|
|
2764
4301
|
this._commonLogger = NOOP_LOGGER;
|
|
4302
|
+
/**
|
|
4303
|
+
* Logs general messages with topic and optional arguments.
|
|
4304
|
+
*
|
|
4305
|
+
* Delegates to configured logger implementation. Uses no-op logger by default
|
|
4306
|
+
* until setLogger() is called with custom implementation.
|
|
4307
|
+
*
|
|
4308
|
+
* @param topic - Log topic or category identifier
|
|
4309
|
+
* @param args - Additional arguments to log
|
|
4310
|
+
*
|
|
4311
|
+
* @example
|
|
4312
|
+
* ```typescript
|
|
4313
|
+
* const logger = new LoggerService();
|
|
4314
|
+
* await logger.log('user-action', { userId: '123', action: 'login' });
|
|
4315
|
+
* // Output depends on configured logger implementation
|
|
4316
|
+
* ```
|
|
4317
|
+
*/
|
|
2765
4318
|
this.log = async (topic, ...args) => {
|
|
2766
4319
|
await this._commonLogger.log(topic, ...args);
|
|
2767
4320
|
};
|
|
4321
|
+
/**
|
|
4322
|
+
* Logs debug-level messages with topic and optional arguments.
|
|
4323
|
+
*
|
|
4324
|
+
* Typically used for detailed diagnostic information during development.
|
|
4325
|
+
* Delegates to configured logger implementation.
|
|
4326
|
+
*
|
|
4327
|
+
* @param topic - Debug topic or category identifier
|
|
4328
|
+
* @param args - Additional arguments to log
|
|
4329
|
+
*
|
|
4330
|
+
* @example
|
|
4331
|
+
* ```typescript
|
|
4332
|
+
* const logger = new LoggerService();
|
|
4333
|
+
* await logger.debug('api-call', { endpoint: '/data', params: { limit: 10 } });
|
|
4334
|
+
* ```
|
|
4335
|
+
*/
|
|
2768
4336
|
this.debug = async (topic, ...args) => {
|
|
2769
4337
|
await this._commonLogger.debug(topic, ...args);
|
|
2770
4338
|
};
|
|
4339
|
+
/**
|
|
4340
|
+
* Logs informational messages with topic and optional arguments.
|
|
4341
|
+
*
|
|
4342
|
+
* Used for general informational messages about application state or progress.
|
|
4343
|
+
* Delegates to configured logger implementation.
|
|
4344
|
+
*
|
|
4345
|
+
* @param topic - Info topic or category identifier
|
|
4346
|
+
* @param args - Additional arguments to log
|
|
4347
|
+
*
|
|
4348
|
+
* @example
|
|
4349
|
+
* ```typescript
|
|
4350
|
+
* const logger = new LoggerService();
|
|
4351
|
+
* await logger.info('server-start', { port: 3000, env: 'production' });
|
|
4352
|
+
* ```
|
|
4353
|
+
*/
|
|
2771
4354
|
this.info = async (topic, ...args) => {
|
|
2772
4355
|
await this._commonLogger.info(topic, ...args);
|
|
2773
4356
|
};
|
|
4357
|
+
/**
|
|
4358
|
+
* Logs warning messages with topic and optional arguments.
|
|
4359
|
+
*
|
|
4360
|
+
* Used for potentially harmful situations that don't prevent execution.
|
|
4361
|
+
* Delegates to configured logger implementation.
|
|
4362
|
+
*
|
|
4363
|
+
* @param topic - Warning topic or category identifier
|
|
4364
|
+
* @param args - Additional arguments to log
|
|
4365
|
+
*
|
|
4366
|
+
* @example
|
|
4367
|
+
* ```typescript
|
|
4368
|
+
* const logger = new LoggerService();
|
|
4369
|
+
* await logger.warn('rate-limit', { limit: 100, current: 95 });
|
|
4370
|
+
* ```
|
|
4371
|
+
*/
|
|
2774
4372
|
this.warn = async (topic, ...args) => {
|
|
2775
4373
|
await this._commonLogger.warn(topic, ...args);
|
|
2776
4374
|
};
|
|
4375
|
+
/**
|
|
4376
|
+
* Sets custom logger implementation.
|
|
4377
|
+
*
|
|
4378
|
+
* Replaces the default no-op logger with a custom implementation that
|
|
4379
|
+
* conforms to the ILogger interface. Call this during application initialization
|
|
4380
|
+
* to enable actual logging output.
|
|
4381
|
+
*
|
|
4382
|
+
* @param logger - Custom logger conforming to ILogger interface
|
|
4383
|
+
*
|
|
4384
|
+
* @example
|
|
4385
|
+
* ```typescript
|
|
4386
|
+
* const logger = new LoggerService();
|
|
4387
|
+
* logger.setLogger({
|
|
4388
|
+
* log: console.log,
|
|
4389
|
+
* debug: console.debug,
|
|
4390
|
+
* info: console.info,
|
|
4391
|
+
* warn: console.warn,
|
|
4392
|
+
* });
|
|
4393
|
+
* await logger.log('test', 'now logging to console');
|
|
4394
|
+
* ```
|
|
4395
|
+
*/
|
|
2777
4396
|
this.setLogger = (logger) => {
|
|
2778
4397
|
this._commonLogger = logger;
|
|
2779
4398
|
};
|
|
2780
4399
|
}
|
|
2781
4400
|
}
|
|
2782
4401
|
|
|
4402
|
+
/**
|
|
4403
|
+
* Service registration for signals library DI container.
|
|
4404
|
+
*
|
|
4405
|
+
* Registers all service factories with the dependency injection container.
|
|
4406
|
+
* Services are lazily instantiated on first injection.
|
|
4407
|
+
*
|
|
4408
|
+
* Service categories:
|
|
4409
|
+
* - Common: Logger service
|
|
4410
|
+
* - Math: Technical analysis services (MicroTerm, ShortTerm, SwingTerm, LongTerm, OrderBook)
|
|
4411
|
+
* - History: Candle history services (1m, 15m, 30m, 1h)
|
|
4412
|
+
*
|
|
4413
|
+
* @module lib/core/provide
|
|
4414
|
+
*/
|
|
4415
|
+
// Register common services
|
|
2783
4416
|
{
|
|
2784
4417
|
provide(TYPES.loggerService, () => new LoggerService());
|
|
2785
4418
|
}
|
|
4419
|
+
// Register technical analysis services
|
|
2786
4420
|
{
|
|
2787
4421
|
provide(TYPES.swingTermMathService, () => new SwingTermHistoryService());
|
|
2788
4422
|
provide(TYPES.longTermMathService, () => new LongTermHistoryService());
|
|
@@ -2790,6 +4424,7 @@ class LoggerService {
|
|
|
2790
4424
|
provide(TYPES.microTermMathService, () => new MicroTermHistoryService());
|
|
2791
4425
|
provide(TYPES.bookDataMathService, () => new BookDataMathService());
|
|
2792
4426
|
}
|
|
4427
|
+
// Register candle history services
|
|
2793
4428
|
{
|
|
2794
4429
|
provide(TYPES.fifteenMinuteCandleHistoryService, () => new FifteenMinuteCandleHistoryService());
|
|
2795
4430
|
provide(TYPES.hourCandleHistoryService, () => new HourCandleHistoryService());
|
|
@@ -2797,9 +4432,30 @@ class LoggerService {
|
|
|
2797
4432
|
provide(TYPES.thirtyMinuteCandleHistoryService, () => new ThirtyMinuteCandleHistoryService());
|
|
2798
4433
|
}
|
|
2799
4434
|
|
|
4435
|
+
/**
|
|
4436
|
+
* Service container initialization and export for signals library.
|
|
4437
|
+
*
|
|
4438
|
+
* Initializes the DI container, injects all registered services,
|
|
4439
|
+
* and exports them as a unified 'signal' object for internal use.
|
|
4440
|
+
*
|
|
4441
|
+
* This module:
|
|
4442
|
+
* 1. Imports service registrations from './core/provide'
|
|
4443
|
+
* 2. Injects all services from DI container
|
|
4444
|
+
* 3. Initializes DI container
|
|
4445
|
+
* 4. Exports combined service object
|
|
4446
|
+
* 5. Attaches to globalThis for debugging (non-production only)
|
|
4447
|
+
*
|
|
4448
|
+
* @module lib/index
|
|
4449
|
+
*/
|
|
4450
|
+
/**
|
|
4451
|
+
* Common services.
|
|
4452
|
+
*/
|
|
2800
4453
|
const commonServices = {
|
|
2801
4454
|
loggerService: inject(TYPES.loggerService),
|
|
2802
4455
|
};
|
|
4456
|
+
/**
|
|
4457
|
+
* Technical analysis services.
|
|
4458
|
+
*/
|
|
2803
4459
|
const mathServices = {
|
|
2804
4460
|
swingTermMathService: inject(TYPES.swingTermMathService),
|
|
2805
4461
|
longTermMathService: inject(TYPES.longTermMathService),
|
|
@@ -2807,32 +4463,97 @@ const mathServices = {
|
|
|
2807
4463
|
microTermMathService: inject(TYPES.microTermMathService),
|
|
2808
4464
|
bookDataMathService: inject(TYPES.bookDataMathService),
|
|
2809
4465
|
};
|
|
4466
|
+
/**
|
|
4467
|
+
* Candle history services.
|
|
4468
|
+
*/
|
|
2810
4469
|
const historyServices = {
|
|
2811
4470
|
fifteenMinuteCandleHistoryService: inject(TYPES.fifteenMinuteCandleHistoryService),
|
|
2812
4471
|
hourCandleHistoryService: inject(TYPES.hourCandleHistoryService),
|
|
2813
4472
|
oneMinuteCandleHistoryService: inject(TYPES.oneMinuteCandleHistoryService),
|
|
2814
4473
|
thirtyMinuteCandleHistoryService: inject(TYPES.thirtyMinuteCandleHistoryService),
|
|
2815
4474
|
};
|
|
4475
|
+
/**
|
|
4476
|
+
* Combined service container for internal library use.
|
|
4477
|
+
* Contains all registered services: common, math, and history.
|
|
4478
|
+
*/
|
|
2816
4479
|
const signal = {
|
|
2817
4480
|
...commonServices,
|
|
2818
4481
|
...mathServices,
|
|
2819
4482
|
...historyServices,
|
|
2820
4483
|
};
|
|
4484
|
+
// Initialize DI container
|
|
2821
4485
|
init();
|
|
4486
|
+
// Attach to global for debugging (non-production)
|
|
2822
4487
|
Object.assign(globalThis, { signal });
|
|
2823
4488
|
|
|
4489
|
+
/**
|
|
4490
|
+
* Candle history report generation functions for multi-timeframe analysis.
|
|
4491
|
+
*
|
|
4492
|
+
* Provides cached functions to fetch and commit OHLCV candle history reports
|
|
4493
|
+
* across 4 timeframes (1m, 15m, 30m, 1h) formatted as markdown for LLM consumption.
|
|
4494
|
+
* Each function automatically handles caching, error recovery, and report formatting.
|
|
4495
|
+
*
|
|
4496
|
+
* Key features:
|
|
4497
|
+
* - Intelligent caching with timeframe-specific TTL (1m: 1min, 15m: 5min, 30m: 15min, 1h: 30min)
|
|
4498
|
+
* - Automatic cache clearing on errors for data freshness
|
|
4499
|
+
* - Formatted markdown tables with candle details (OHLCV, volatility, body size, candle type)
|
|
4500
|
+
* - User/assistant message pair format for LLM context
|
|
4501
|
+
*
|
|
4502
|
+
* @module function/history
|
|
4503
|
+
*/
|
|
4504
|
+
/**
|
|
4505
|
+
* Cached function to fetch 1-hour candle history report.
|
|
4506
|
+
* Cache TTL: 30 minutes
|
|
4507
|
+
*/
|
|
2824
4508
|
const fetchHourHistory = Cache.fn(signal.hourCandleHistoryService.getReport, {
|
|
2825
4509
|
interval: "30m",
|
|
2826
4510
|
});
|
|
4511
|
+
/**
|
|
4512
|
+
* Cached function to fetch 30-minute candle history report.
|
|
4513
|
+
* Cache TTL: 15 minutes
|
|
4514
|
+
*/
|
|
2827
4515
|
const fetchThirtyMinuteHistory = Cache.fn(signal.thirtyMinuteCandleHistoryService.getReport, {
|
|
2828
4516
|
interval: "15m",
|
|
2829
4517
|
});
|
|
4518
|
+
/**
|
|
4519
|
+
* Cached function to fetch 15-minute candle history report.
|
|
4520
|
+
* Cache TTL: 5 minutes
|
|
4521
|
+
*/
|
|
2830
4522
|
const fetchFifteenMinuteHistory = Cache.fn(signal.fifteenMinuteCandleHistoryService.getReport, {
|
|
2831
4523
|
interval: "5m",
|
|
2832
4524
|
});
|
|
4525
|
+
/**
|
|
4526
|
+
* Cached function to fetch 1-minute candle history report.
|
|
4527
|
+
* Cache TTL: 1 minute
|
|
4528
|
+
*/
|
|
2833
4529
|
const fetchOneMinuteHistory = Cache.fn(signal.oneMinuteCandleHistoryService.getReport, {
|
|
2834
4530
|
interval: "1m",
|
|
2835
4531
|
});
|
|
4532
|
+
/**
|
|
4533
|
+
* Commits 1-hour candle history report to history container.
|
|
4534
|
+
*
|
|
4535
|
+
* Fetches and appends a markdown-formatted report of the last 6 hourly candles
|
|
4536
|
+
* including OHLCV data, volatility, body size, and candle type (Green/Red/Doji).
|
|
4537
|
+
* Automatically clears cache on errors to ensure data freshness.
|
|
4538
|
+
*
|
|
4539
|
+
* @param symbol - Trading pair symbol (e.g., 'BTCUSDT')
|
|
4540
|
+
* @param history - History container to append report to
|
|
4541
|
+
* @returns Promise that resolves when report is committed
|
|
4542
|
+
*
|
|
4543
|
+
* @example
|
|
4544
|
+
* ```typescript
|
|
4545
|
+
* import { commitHourHistory } from '@backtest-kit/signals';
|
|
4546
|
+
*
|
|
4547
|
+
* const messages = [];
|
|
4548
|
+
* await commitHourHistory('BTCUSDT', messages);
|
|
4549
|
+
*
|
|
4550
|
+
* // messages now contains:
|
|
4551
|
+
* // [
|
|
4552
|
+
* // { role: 'user', content: '=== HOURLY CANDLES HISTORY (LAST 6) ===\n\n...' },
|
|
4553
|
+
* // { role: 'assistant', content: 'Hourly candles history received.' }
|
|
4554
|
+
* // ]
|
|
4555
|
+
* ```
|
|
4556
|
+
*/
|
|
2836
4557
|
const commitHourHistory = trycatch(async (symbol, history) => {
|
|
2837
4558
|
const hourHistory = await fetchHourHistory(symbol);
|
|
2838
4559
|
await history.push({
|
|
@@ -2845,6 +4566,25 @@ const commitHourHistory = trycatch(async (symbol, history) => {
|
|
|
2845
4566
|
}, {
|
|
2846
4567
|
fallback: () => Cache.clear(fetchHourHistory),
|
|
2847
4568
|
});
|
|
4569
|
+
/**
|
|
4570
|
+
* Commits 30-minute candle history report to history container.
|
|
4571
|
+
*
|
|
4572
|
+
* Fetches and appends a markdown-formatted report of the last 6 thirty-minute candles
|
|
4573
|
+
* including OHLCV data, volatility, body size, and candle type (Green/Red/Doji).
|
|
4574
|
+
* Automatically clears cache on errors to ensure data freshness.
|
|
4575
|
+
*
|
|
4576
|
+
* @param symbol - Trading pair symbol (e.g., 'BTCUSDT')
|
|
4577
|
+
* @param history - History container to append report to
|
|
4578
|
+
* @returns Promise that resolves when report is committed
|
|
4579
|
+
*
|
|
4580
|
+
* @example
|
|
4581
|
+
* ```typescript
|
|
4582
|
+
* import { commitThirtyMinuteHistory } from '@backtest-kit/signals';
|
|
4583
|
+
*
|
|
4584
|
+
* const messages = [];
|
|
4585
|
+
* await commitThirtyMinuteHistory('ETHUSDT', messages);
|
|
4586
|
+
* ```
|
|
4587
|
+
*/
|
|
2848
4588
|
const commitThirtyMinuteHistory = trycatch(async (symbol, history) => {
|
|
2849
4589
|
const thirtyMinuteHistory = await fetchThirtyMinuteHistory(symbol);
|
|
2850
4590
|
await history.push({
|
|
@@ -2857,6 +4597,25 @@ const commitThirtyMinuteHistory = trycatch(async (symbol, history) => {
|
|
|
2857
4597
|
}, {
|
|
2858
4598
|
fallback: () => Cache.clear(fetchThirtyMinuteHistory),
|
|
2859
4599
|
});
|
|
4600
|
+
/**
|
|
4601
|
+
* Commits 15-minute candle history report to history container.
|
|
4602
|
+
*
|
|
4603
|
+
* Fetches and appends a markdown-formatted report of the last 8 fifteen-minute candles
|
|
4604
|
+
* including OHLCV data, volatility, body size, and candle type (Green/Red/Doji).
|
|
4605
|
+
* Automatically clears cache on errors to ensure data freshness.
|
|
4606
|
+
*
|
|
4607
|
+
* @param symbol - Trading pair symbol (e.g., 'BTCUSDT')
|
|
4608
|
+
* @param history - History container to append report to
|
|
4609
|
+
* @returns Promise that resolves when report is committed
|
|
4610
|
+
*
|
|
4611
|
+
* @example
|
|
4612
|
+
* ```typescript
|
|
4613
|
+
* import { commitFifteenMinuteHistory } from '@backtest-kit/signals';
|
|
4614
|
+
*
|
|
4615
|
+
* const messages = [];
|
|
4616
|
+
* await commitFifteenMinuteHistory('BTCUSDT', messages);
|
|
4617
|
+
* ```
|
|
4618
|
+
*/
|
|
2860
4619
|
const commitFifteenMinuteHistory = trycatch(async (symbol, history) => {
|
|
2861
4620
|
const fifteenMinuteHistory = await fetchFifteenMinuteHistory(symbol);
|
|
2862
4621
|
await history.push({
|
|
@@ -2869,6 +4628,25 @@ const commitFifteenMinuteHistory = trycatch(async (symbol, history) => {
|
|
|
2869
4628
|
}, {
|
|
2870
4629
|
fallback: () => Cache.clear(fetchFifteenMinuteHistory),
|
|
2871
4630
|
});
|
|
4631
|
+
/**
|
|
4632
|
+
* Commits 1-minute candle history report to history container.
|
|
4633
|
+
*
|
|
4634
|
+
* Fetches and appends a markdown-formatted report of the last 15 one-minute candles
|
|
4635
|
+
* including OHLCV data, volatility, body size, and candle type (Green/Red/Doji).
|
|
4636
|
+
* Automatically clears cache on errors to ensure data freshness.
|
|
4637
|
+
*
|
|
4638
|
+
* @param symbol - Trading pair symbol (e.g., 'BTCUSDT')
|
|
4639
|
+
* @param history - History container to append report to
|
|
4640
|
+
* @returns Promise that resolves when report is committed
|
|
4641
|
+
*
|
|
4642
|
+
* @example
|
|
4643
|
+
* ```typescript
|
|
4644
|
+
* import { commitOneMinuteHistory } from '@backtest-kit/signals';
|
|
4645
|
+
*
|
|
4646
|
+
* const messages = [];
|
|
4647
|
+
* await commitOneMinuteHistory('BTCUSDT', messages);
|
|
4648
|
+
* ```
|
|
4649
|
+
*/
|
|
2872
4650
|
const commitOneMinuteHistory = trycatch(async (symbol, history) => {
|
|
2873
4651
|
const oneMinuteHistory = await fetchOneMinuteHistory(symbol);
|
|
2874
4652
|
await history.push({
|
|
@@ -2882,18 +4660,83 @@ const commitOneMinuteHistory = trycatch(async (symbol, history) => {
|
|
|
2882
4660
|
fallback: () => Cache.clear(fetchOneMinuteHistory),
|
|
2883
4661
|
});
|
|
2884
4662
|
|
|
4663
|
+
/**
|
|
4664
|
+
* Technical indicator report generation functions for multi-timeframe trading analysis.
|
|
4665
|
+
*
|
|
4666
|
+
* Provides cached functions to fetch and commit comprehensive technical indicator reports
|
|
4667
|
+
* across 4 trading timeframes (MicroTerm: 1m, ShortTerm: 15m, SwingTerm: 30m, LongTerm: 1h).
|
|
4668
|
+
* Each report includes 50+ indicators formatted as markdown tables for LLM consumption.
|
|
4669
|
+
*
|
|
4670
|
+
* Key features:
|
|
4671
|
+
* - MicroTerm (1m): RSI(9,14), MACD(8,21,5), Stochastic, ADX(9), Bollinger(8,2), ATR, CCI, Volume analysis, Squeeze momentum
|
|
4672
|
+
* - ShortTerm (15m): RSI(9), MACD(8,21,5), Stochastic(5,3,3), ADX(14), Bollinger(10,2), Fibonacci levels
|
|
4673
|
+
* - SwingTerm (30m): RSI(14), MACD(12,26,9), Stochastic(14,3,3), Bollinger(20,2), Support/Resistance, Fibonacci
|
|
4674
|
+
* - LongTerm (1h): RSI(14), MACD(12,26,9), ADX(14), Bollinger(20,2), SMA(50), DEMA, WMA, Volume trends
|
|
4675
|
+
* - Intelligent caching with timeframe-specific TTL
|
|
4676
|
+
* - Automatic cache clearing on errors
|
|
4677
|
+
*
|
|
4678
|
+
* @module function/math
|
|
4679
|
+
*/
|
|
4680
|
+
/**
|
|
4681
|
+
* Cached function to fetch MicroTerm (1-minute) technical analysis report.
|
|
4682
|
+
* Cache TTL: 1 minute
|
|
4683
|
+
*/
|
|
2885
4684
|
const fetchMicroTermMath = Cache.fn(signal.microTermMathService.getReport, {
|
|
2886
4685
|
interval: "1m",
|
|
2887
4686
|
});
|
|
4687
|
+
/**
|
|
4688
|
+
* Cached function to fetch ShortTerm (15-minute) technical analysis report.
|
|
4689
|
+
* Cache TTL: 5 minutes
|
|
4690
|
+
*/
|
|
2888
4691
|
const fetchShortTermMath = Cache.fn(signal.shortTermMathService.getReport, {
|
|
2889
4692
|
interval: "5m",
|
|
2890
4693
|
});
|
|
4694
|
+
/**
|
|
4695
|
+
* Cached function to fetch SwingTerm (30-minute) technical analysis report.
|
|
4696
|
+
* Cache TTL: 15 minutes
|
|
4697
|
+
*/
|
|
2891
4698
|
const fetchSwingTermMath = Cache.fn(signal.swingTermMathService.getReport, {
|
|
2892
4699
|
interval: "15m",
|
|
2893
4700
|
});
|
|
4701
|
+
/**
|
|
4702
|
+
* Cached function to fetch LongTerm (1-hour) technical analysis report.
|
|
4703
|
+
* Cache TTL: 30 minutes
|
|
4704
|
+
*/
|
|
2894
4705
|
const fetchLongTermMath = Cache.fn(signal.longTermMathService.getReport, {
|
|
2895
4706
|
interval: "30m",
|
|
2896
4707
|
});
|
|
4708
|
+
/**
|
|
4709
|
+
* Commits MicroTerm (1-minute) technical analysis report to history container.
|
|
4710
|
+
*
|
|
4711
|
+
* Generates comprehensive technical analysis for scalping and ultra-short term trading.
|
|
4712
|
+
* Includes 40+ indicators optimized for 1-minute timeframe with 60-candle lookback.
|
|
4713
|
+
*
|
|
4714
|
+
* Indicators included:
|
|
4715
|
+
* - Momentum: RSI(9,14), Stochastic RSI(9,14), MACD(8,21,5), Momentum(5,10), ROC(1,3,5)
|
|
4716
|
+
* - Trend: ADX(9), +DI/-DI(9), EMA(3,8,13,21), SMA(8), DEMA(8), WMA(5)
|
|
4717
|
+
* - Volatility: ATR(5,9), Bollinger Bands(8,2) with width/position, Squeeze momentum
|
|
4718
|
+
* - Volume: SMA(5), volume ratio, volume trend (increasing/decreasing/stable)
|
|
4719
|
+
* - Support/Resistance: Dynamic levels from 30-candle window
|
|
4720
|
+
* - Price Analysis: 1m/3m/5m price changes, volatility, true range, pressure index
|
|
4721
|
+
*
|
|
4722
|
+
* @param symbol - Trading pair symbol (e.g., 'BTCUSDT')
|
|
4723
|
+
* @param history - History container to append report to
|
|
4724
|
+
* @returns Promise that resolves when report is committed
|
|
4725
|
+
*
|
|
4726
|
+
* @example
|
|
4727
|
+
* ```typescript
|
|
4728
|
+
* import { commitMicroTermMath } from '@backtest-kit/signals';
|
|
4729
|
+
*
|
|
4730
|
+
* const messages = [];
|
|
4731
|
+
* await commitMicroTermMath('BTCUSDT', messages);
|
|
4732
|
+
*
|
|
4733
|
+
* // Use in LLM strategy for scalping signals
|
|
4734
|
+
* const signal = await llm([
|
|
4735
|
+
* { role: 'system', content: 'Analyze for scalping opportunities' },
|
|
4736
|
+
* ...messages
|
|
4737
|
+
* ]);
|
|
4738
|
+
* ```
|
|
4739
|
+
*/
|
|
2897
4740
|
const commitMicroTermMath = trycatch(async (symbol, history) => {
|
|
2898
4741
|
const microTermMath = await fetchMicroTermMath(symbol);
|
|
2899
4742
|
await history.push({
|
|
@@ -2906,6 +4749,32 @@ const commitMicroTermMath = trycatch(async (symbol, history) => {
|
|
|
2906
4749
|
}, {
|
|
2907
4750
|
fallback: () => Cache.clear(fetchMicroTermMath),
|
|
2908
4751
|
});
|
|
4752
|
+
/**
|
|
4753
|
+
* Commits LongTerm (1-hour) technical analysis report to history container.
|
|
4754
|
+
*
|
|
4755
|
+
* Generates comprehensive technical analysis for trend identification and position management.
|
|
4756
|
+
* Includes 30+ indicators optimized for 1-hour timeframe with 48-candle lookback (48 hours).
|
|
4757
|
+
*
|
|
4758
|
+
* Indicators included:
|
|
4759
|
+
* - Momentum: RSI(14), Stochastic RSI(14), MACD(12,26,9), Stochastic(14,3,3), Momentum(10)
|
|
4760
|
+
* - Trend: ADX(14), +DI/-DI(14), SMA(50), EMA(20,34), DEMA(21), WMA(20)
|
|
4761
|
+
* - Volatility: ATR(14,20), Bollinger Bands(20,2), CCI(20)
|
|
4762
|
+
* - Support/Resistance: 4-candle pivot detection
|
|
4763
|
+
* - Fibonacci: Retracement levels (0%, 23.6%, 38.2%, 50%, 61.8%, 78.6%, 100%) with nearest level
|
|
4764
|
+
* - Volume: Trend analysis (increasing/decreasing/stable)
|
|
4765
|
+
*
|
|
4766
|
+
* @param symbol - Trading pair symbol (e.g., 'BTCUSDT')
|
|
4767
|
+
* @param history - History container to append report to
|
|
4768
|
+
* @returns Promise that resolves when report is committed
|
|
4769
|
+
*
|
|
4770
|
+
* @example
|
|
4771
|
+
* ```typescript
|
|
4772
|
+
* import { commitLongTermMath } from '@backtest-kit/signals';
|
|
4773
|
+
*
|
|
4774
|
+
* const messages = [];
|
|
4775
|
+
* await commitLongTermMath('ETHUSDT', messages);
|
|
4776
|
+
* ```
|
|
4777
|
+
*/
|
|
2909
4778
|
const commitLongTermMath = trycatch(async (symbol, history) => {
|
|
2910
4779
|
const longTermMath = await fetchLongTermMath(symbol);
|
|
2911
4780
|
await history.push({
|
|
@@ -2918,6 +4787,32 @@ const commitLongTermMath = trycatch(async (symbol, history) => {
|
|
|
2918
4787
|
}, {
|
|
2919
4788
|
fallback: () => Cache.clear(fetchLongTermMath),
|
|
2920
4789
|
});
|
|
4790
|
+
/**
|
|
4791
|
+
* Commits ShortTerm (15-minute) technical analysis report to history container.
|
|
4792
|
+
*
|
|
4793
|
+
* Generates comprehensive technical analysis for day trading strategies.
|
|
4794
|
+
* Includes 30+ indicators optimized for 15-minute timeframe with 144-candle lookback (36 hours).
|
|
4795
|
+
*
|
|
4796
|
+
* Indicators included:
|
|
4797
|
+
* - Momentum: RSI(9), Stochastic RSI(9), MACD(8,21,5), Stochastic(5,3,3), Momentum(8), ROC(5,10)
|
|
4798
|
+
* - Trend: ADX(14), +DI/-DI(14), SMA(50), EMA(8,21), DEMA(21), WMA(20)
|
|
4799
|
+
* - Volatility: ATR(9), Bollinger Bands(10,2) with width, CCI(14)
|
|
4800
|
+
* - Support/Resistance: 48-candle window with 0.3% threshold
|
|
4801
|
+
* - Fibonacci: Retracement levels over 288-candle lookback (72 hours)
|
|
4802
|
+
* - Volume: Trend analysis over 16-candle window
|
|
4803
|
+
*
|
|
4804
|
+
* @param symbol - Trading pair symbol (e.g., 'BTCUSDT')
|
|
4805
|
+
* @param history - History container to append report to
|
|
4806
|
+
* @returns Promise that resolves when report is committed
|
|
4807
|
+
*
|
|
4808
|
+
* @example
|
|
4809
|
+
* ```typescript
|
|
4810
|
+
* import { commitShortTermMath } from '@backtest-kit/signals';
|
|
4811
|
+
*
|
|
4812
|
+
* const messages = [];
|
|
4813
|
+
* await commitShortTermMath('BTCUSDT', messages);
|
|
4814
|
+
* ```
|
|
4815
|
+
*/
|
|
2921
4816
|
const commitShortTermMath = trycatch(async (symbol, history) => {
|
|
2922
4817
|
const shortTermMath = await fetchShortTermMath(symbol);
|
|
2923
4818
|
await history.push({
|
|
@@ -2930,6 +4825,33 @@ const commitShortTermMath = trycatch(async (symbol, history) => {
|
|
|
2930
4825
|
}, {
|
|
2931
4826
|
fallback: () => Cache.clear(fetchShortTermMath),
|
|
2932
4827
|
});
|
|
4828
|
+
/**
|
|
4829
|
+
* Commits SwingTerm (30-minute) technical analysis report to history container.
|
|
4830
|
+
*
|
|
4831
|
+
* Generates comprehensive technical analysis for swing trading strategies.
|
|
4832
|
+
* Includes 30+ indicators optimized for 30-minute timeframe with 96-candle lookback (48 hours).
|
|
4833
|
+
*
|
|
4834
|
+
* Indicators included:
|
|
4835
|
+
* - Momentum: RSI(14), Stochastic RSI(14), MACD(12,26,9), Stochastic(14,3,3), Momentum(8)
|
|
4836
|
+
* - Trend: ADX(14), +DI/-DI(14), SMA(20), EMA(13,34), DEMA(21), WMA(20)
|
|
4837
|
+
* - Volatility: ATR(14), Bollinger Bands(20,2) with width, CCI(20), Basic volatility
|
|
4838
|
+
* - Support/Resistance: 20-candle window detection
|
|
4839
|
+
* - Fibonacci: Support/resistance levels with current level identification
|
|
4840
|
+
* - Volume: Trading volume analysis
|
|
4841
|
+
* - Price Momentum: 6-period momentum indicator
|
|
4842
|
+
*
|
|
4843
|
+
* @param symbol - Trading pair symbol (e.g., 'BTCUSDT')
|
|
4844
|
+
* @param history - History container to append report to
|
|
4845
|
+
* @returns Promise that resolves when report is committed
|
|
4846
|
+
*
|
|
4847
|
+
* @example
|
|
4848
|
+
* ```typescript
|
|
4849
|
+
* import { commitSwingTermMath } from '@backtest-kit/signals';
|
|
4850
|
+
*
|
|
4851
|
+
* const messages = [];
|
|
4852
|
+
* await commitSwingTermMath('BTCUSDT', messages);
|
|
4853
|
+
* ```
|
|
4854
|
+
*/
|
|
2933
4855
|
const commitSwingTermMath = trycatch(async (symbol, history) => {
|
|
2934
4856
|
const swingTermMath = await fetchSwingTermMath(symbol);
|
|
2935
4857
|
await history.push({
|
|
@@ -2943,9 +4865,59 @@ const commitSwingTermMath = trycatch(async (symbol, history) => {
|
|
|
2943
4865
|
fallback: () => Cache.clear(fetchSwingTermMath),
|
|
2944
4866
|
});
|
|
2945
4867
|
|
|
4868
|
+
/**
|
|
4869
|
+
* Orchestrator functions for complete market analysis setup.
|
|
4870
|
+
*
|
|
4871
|
+
* Provides high-level functions that combine multiple analysis types
|
|
4872
|
+
* (order book, candle history, technical indicators) into comprehensive
|
|
4873
|
+
* market reports for LLM-based trading strategies.
|
|
4874
|
+
*
|
|
4875
|
+
* Key features:
|
|
4876
|
+
* - commitBookDataReport: Order book analysis with top 20 levels by volume
|
|
4877
|
+
* - commitHistorySetup: All-in-one setup with full multi-timeframe analysis
|
|
4878
|
+
* - Automatic mode detection (skips order book in backtest mode)
|
|
4879
|
+
* - System context injection (symbol, price, timestamp)
|
|
4880
|
+
*
|
|
4881
|
+
* @module function/other
|
|
4882
|
+
*/
|
|
4883
|
+
/**
|
|
4884
|
+
* Cached function to fetch order book analysis report.
|
|
4885
|
+
* Cache TTL: 5 minutes
|
|
4886
|
+
*/
|
|
2946
4887
|
const fetchBookData = Cache.fn(signal.bookDataMathService.getReport, {
|
|
2947
4888
|
interval: "5m",
|
|
2948
4889
|
});
|
|
4890
|
+
/**
|
|
4891
|
+
* Commits order book analysis report to history container.
|
|
4892
|
+
*
|
|
4893
|
+
* Fetches and appends real-time order book data including top 20 price levels
|
|
4894
|
+
* by volume percentage, best bid/ask, mid price, spread, and depth imbalance.
|
|
4895
|
+
* Automatically skipped in backtest mode (order book data unavailable).
|
|
4896
|
+
*
|
|
4897
|
+
* Order book metrics:
|
|
4898
|
+
* - Best Bid/Ask: Top buy and sell prices
|
|
4899
|
+
* - Mid Price: (Best Bid + Best Ask) / 2
|
|
4900
|
+
* - Spread: Best Ask - Best Bid
|
|
4901
|
+
* - Depth Imbalance: (Bid Volume - Ask Volume) / (Bid Volume + Ask Volume)
|
|
4902
|
+
* - Positive = buying pressure
|
|
4903
|
+
* - Negative = selling pressure
|
|
4904
|
+
* - Top 20 Levels: Sorted by volume percentage on each side
|
|
4905
|
+
*
|
|
4906
|
+
* @param symbol - Trading pair symbol (e.g., 'BTCUSDT')
|
|
4907
|
+
* @param history - History container to append report to
|
|
4908
|
+
* @returns Promise that resolves when report is committed (or immediately in backtest mode)
|
|
4909
|
+
*
|
|
4910
|
+
* @example
|
|
4911
|
+
* ```typescript
|
|
4912
|
+
* import { commitBookDataReport } from '@backtest-kit/signals';
|
|
4913
|
+
*
|
|
4914
|
+
* const messages = [];
|
|
4915
|
+
* await commitBookDataReport('BTCUSDT', messages);
|
|
4916
|
+
*
|
|
4917
|
+
* // In live mode: messages contains order book analysis
|
|
4918
|
+
* // In backtest mode: messages unchanged (order book skipped)
|
|
4919
|
+
* ```
|
|
4920
|
+
*/
|
|
2949
4921
|
const commitBookDataReport = trycatch(async (symbol, history) => {
|
|
2950
4922
|
const mode = await getMode();
|
|
2951
4923
|
if (mode === "backtest") {
|
|
@@ -2962,15 +4934,56 @@ const commitBookDataReport = trycatch(async (symbol, history) => {
|
|
|
2962
4934
|
}, {
|
|
2963
4935
|
fallback: () => Cache.clear(fetchBookData),
|
|
2964
4936
|
});
|
|
4937
|
+
/**
|
|
4938
|
+
* Commits complete multi-timeframe market analysis setup to history container.
|
|
4939
|
+
*
|
|
4940
|
+
* All-in-one function that orchestrates the full technical analysis pipeline.
|
|
4941
|
+
* Sequentially commits order book data, candle histories, technical indicators,
|
|
4942
|
+
* and system context for comprehensive LLM-based trading analysis.
|
|
4943
|
+
*
|
|
4944
|
+
* Analysis pipeline:
|
|
4945
|
+
* 1. Order Book: Top 20 levels, bid/ask depth, spread, imbalance (live mode only)
|
|
4946
|
+
* 2. Candle Histories: 1m (15 candles), 15m (8 candles), 30m (6 candles), 1h (6 candles)
|
|
4947
|
+
* 3. Technical Indicators:
|
|
4948
|
+
* - MicroTerm (1m): 40+ scalping indicators
|
|
4949
|
+
* - ShortTerm (15m): 30+ day trading indicators
|
|
4950
|
+
* - SwingTerm (30m): 30+ swing trading indicators
|
|
4951
|
+
* - LongTerm (1h): 30+ trend indicators
|
|
4952
|
+
* 4. System Context: Symbol, current price (VWAP), timestamp
|
|
4953
|
+
*
|
|
4954
|
+
* Total output: 150+ indicators across 4 timeframes + order book + candle data
|
|
4955
|
+
*
|
|
4956
|
+
* @param symbol - Trading pair symbol (e.g., 'BTCUSDT')
|
|
4957
|
+
* @param history - History container to append all reports to
|
|
4958
|
+
* @returns Promise that resolves when all reports are committed
|
|
4959
|
+
*
|
|
4960
|
+
* @example
|
|
4961
|
+
* ```typescript
|
|
4962
|
+
* import { commitHistorySetup } from '@backtest-kit/signals';
|
|
4963
|
+
* import { json } from './llm-wrapper';
|
|
4964
|
+
*
|
|
4965
|
+
* // Complete LLM strategy setup
|
|
4966
|
+
* const messages = [
|
|
4967
|
+
* { role: 'system', content: 'You are a trading bot. Analyze and generate signals.' }
|
|
4968
|
+
* ];
|
|
4969
|
+
*
|
|
4970
|
+
* // Inject all technical analysis
|
|
4971
|
+
* await commitHistorySetup('BTCUSDT', messages);
|
|
4972
|
+
*
|
|
4973
|
+
* // Generate trading signal
|
|
4974
|
+
* const signal = await json(messages);
|
|
4975
|
+
* console.log(signal); // { position: 'long', priceTakeProfit: 50500, priceStopLoss: 49500 }
|
|
4976
|
+
* ```
|
|
4977
|
+
*/
|
|
2965
4978
|
const commitHistorySetup = async (symbol, history) => {
|
|
2966
|
-
//
|
|
4979
|
+
// Order book analysis
|
|
2967
4980
|
await commitBookDataReport(symbol, history);
|
|
2968
|
-
//
|
|
4981
|
+
// Candle histories across timeframes
|
|
2969
4982
|
await commitOneMinuteHistory(symbol, history);
|
|
2970
4983
|
await commitFifteenMinuteHistory(symbol, history);
|
|
2971
4984
|
await commitThirtyMinuteHistory(symbol, history);
|
|
2972
4985
|
await commitHourHistory(symbol, history);
|
|
2973
|
-
//
|
|
4986
|
+
// Technical indicators across timeframes
|
|
2974
4987
|
await commitMicroTermMath(symbol, history);
|
|
2975
4988
|
await commitShortTermMath(symbol, history);
|
|
2976
4989
|
await commitSwingTermMath(symbol, history);
|
|
@@ -2984,6 +4997,43 @@ const commitHistorySetup = async (symbol, history) => {
|
|
|
2984
4997
|
});
|
|
2985
4998
|
};
|
|
2986
4999
|
|
|
5000
|
+
/**
|
|
5001
|
+
* Configuration utilities for signals library.
|
|
5002
|
+
*
|
|
5003
|
+
* Provides functions to customize library behavior, primarily logging configuration.
|
|
5004
|
+
*
|
|
5005
|
+
* @module tools/setup
|
|
5006
|
+
*/
|
|
5007
|
+
/**
|
|
5008
|
+
* Sets custom logger implementation for signals library.
|
|
5009
|
+
*
|
|
5010
|
+
* By default, signals uses a no-op logger (no output).
|
|
5011
|
+
* Use this function to enable logging for debugging and monitoring.
|
|
5012
|
+
*
|
|
5013
|
+
* @param logger - Custom logger implementation conforming to ILogger interface
|
|
5014
|
+
*
|
|
5015
|
+
* @example
|
|
5016
|
+
* ```typescript
|
|
5017
|
+
* import { setLogger } from '@backtest-kit/signals';
|
|
5018
|
+
*
|
|
5019
|
+
* // Enable console logging
|
|
5020
|
+
* setLogger({
|
|
5021
|
+
* log: console.log,
|
|
5022
|
+
* debug: console.debug,
|
|
5023
|
+
* info: console.info,
|
|
5024
|
+
* warn: console.warn,
|
|
5025
|
+
* });
|
|
5026
|
+
*
|
|
5027
|
+
* // Or use custom logger
|
|
5028
|
+
* import winston from 'winston';
|
|
5029
|
+
* setLogger({
|
|
5030
|
+
* log: (topic, ...args) => winston.log('info', topic, args),
|
|
5031
|
+
* debug: (topic, ...args) => winston.debug(topic, args),
|
|
5032
|
+
* info: (topic, ...args) => winston.info(topic, args),
|
|
5033
|
+
* warn: (topic, ...args) => winston.warn(topic, args),
|
|
5034
|
+
* });
|
|
5035
|
+
* ```
|
|
5036
|
+
*/
|
|
2987
5037
|
const setLogger = (logger) => {
|
|
2988
5038
|
signal.loggerService.setLogger(logger);
|
|
2989
5039
|
};
|