bfxsentry-agent 0.1.0

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.
Files changed (187) hide show
  1. package/config/default.yaml +137 -0
  2. package/config/phase1-safety.yaml +24 -0
  3. package/dist/bin/sentry.d.ts +3 -0
  4. package/dist/bin/sentry.d.ts.map +1 -0
  5. package/dist/bin/sentry.js +124 -0
  6. package/dist/bin/sentry.js.map +1 -0
  7. package/dist/src/backtest/fill-simulator.d.ts +5 -0
  8. package/dist/src/backtest/fill-simulator.d.ts.map +1 -0
  9. package/dist/src/backtest/fill-simulator.js +43 -0
  10. package/dist/src/backtest/fill-simulator.js.map +1 -0
  11. package/dist/src/backtest/report.d.ts +3 -0
  12. package/dist/src/backtest/report.d.ts.map +1 -0
  13. package/dist/src/backtest/report.js +43 -0
  14. package/dist/src/backtest/report.js.map +1 -0
  15. package/dist/src/backtest/runner.d.ts +34 -0
  16. package/dist/src/backtest/runner.d.ts.map +1 -0
  17. package/dist/src/backtest/runner.js +132 -0
  18. package/dist/src/backtest/runner.js.map +1 -0
  19. package/dist/src/collector/basis-monitor.d.ts +9 -0
  20. package/dist/src/collector/basis-monitor.d.ts.map +1 -0
  21. package/dist/src/collector/basis-monitor.js +52 -0
  22. package/dist/src/collector/basis-monitor.js.map +1 -0
  23. package/dist/src/collector/bitfinex-rest.d.ts +20 -0
  24. package/dist/src/collector/bitfinex-rest.d.ts.map +1 -0
  25. package/dist/src/collector/bitfinex-rest.js +350 -0
  26. package/dist/src/collector/bitfinex-rest.js.map +1 -0
  27. package/dist/src/collector/event-detector.d.ts +3 -0
  28. package/dist/src/collector/event-detector.d.ts.map +1 -0
  29. package/dist/src/collector/event-detector.js +41 -0
  30. package/dist/src/collector/event-detector.js.map +1 -0
  31. package/dist/src/collector/polymarket.d.ts +32 -0
  32. package/dist/src/collector/polymarket.d.ts.map +1 -0
  33. package/dist/src/collector/polymarket.js +89 -0
  34. package/dist/src/collector/polymarket.js.map +1 -0
  35. package/dist/src/collector/types.d.ts +114 -0
  36. package/dist/src/collector/types.d.ts.map +1 -0
  37. package/dist/src/collector/types.js +2 -0
  38. package/dist/src/collector/types.js.map +1 -0
  39. package/dist/src/core/config.d.ts +67 -0
  40. package/dist/src/core/config.d.ts.map +1 -0
  41. package/dist/src/core/config.js +27 -0
  42. package/dist/src/core/config.js.map +1 -0
  43. package/dist/src/core/decision-log.d.ts +7 -0
  44. package/dist/src/core/decision-log.d.ts.map +1 -0
  45. package/dist/src/core/decision-log.js +69 -0
  46. package/dist/src/core/decision-log.js.map +1 -0
  47. package/dist/src/core/engine.d.ts +19 -0
  48. package/dist/src/core/engine.d.ts.map +1 -0
  49. package/dist/src/core/engine.js +148 -0
  50. package/dist/src/core/engine.js.map +1 -0
  51. package/dist/src/core/event-bus.d.ts +12 -0
  52. package/dist/src/core/event-bus.d.ts.map +1 -0
  53. package/dist/src/core/event-bus.js +21 -0
  54. package/dist/src/core/event-bus.js.map +1 -0
  55. package/dist/src/core/logger.d.ts +4 -0
  56. package/dist/src/core/logger.d.ts.map +1 -0
  57. package/dist/src/core/logger.js +22 -0
  58. package/dist/src/core/logger.js.map +1 -0
  59. package/dist/src/core/recorder.d.ts +7 -0
  60. package/dist/src/core/recorder.d.ts.map +1 -0
  61. package/dist/src/core/recorder.js +42 -0
  62. package/dist/src/core/recorder.js.map +1 -0
  63. package/dist/src/executor/bitfinex-trader.d.ts +3 -0
  64. package/dist/src/executor/bitfinex-trader.d.ts.map +1 -0
  65. package/dist/src/executor/bitfinex-trader.js +119 -0
  66. package/dist/src/executor/bitfinex-trader.js.map +1 -0
  67. package/dist/src/executor/dry-run.d.ts +4 -0
  68. package/dist/src/executor/dry-run.d.ts.map +1 -0
  69. package/dist/src/executor/dry-run.js +39 -0
  70. package/dist/src/executor/dry-run.js.map +1 -0
  71. package/dist/src/executor/order-id.d.ts +5 -0
  72. package/dist/src/executor/order-id.d.ts.map +1 -0
  73. package/dist/src/executor/order-id.js +20 -0
  74. package/dist/src/executor/order-id.js.map +1 -0
  75. package/dist/src/executor/reconciler.d.ts +8 -0
  76. package/dist/src/executor/reconciler.d.ts.map +1 -0
  77. package/dist/src/executor/reconciler.js +44 -0
  78. package/dist/src/executor/reconciler.js.map +1 -0
  79. package/dist/src/executor/types.d.ts +19 -0
  80. package/dist/src/executor/types.d.ts.map +1 -0
  81. package/dist/src/executor/types.js +2 -0
  82. package/dist/src/executor/types.js.map +1 -0
  83. package/dist/src/risk/cooldown.d.ts +8 -0
  84. package/dist/src/risk/cooldown.d.ts.map +1 -0
  85. package/dist/src/risk/cooldown.js +30 -0
  86. package/dist/src/risk/cooldown.js.map +1 -0
  87. package/dist/src/risk/portfolio-filter.d.ts +9 -0
  88. package/dist/src/risk/portfolio-filter.d.ts.map +1 -0
  89. package/dist/src/risk/portfolio-filter.js +58 -0
  90. package/dist/src/risk/portfolio-filter.js.map +1 -0
  91. package/dist/src/risk/position-manager.d.ts +19 -0
  92. package/dist/src/risk/position-manager.d.ts.map +1 -0
  93. package/dist/src/risk/position-manager.js +171 -0
  94. package/dist/src/risk/position-manager.js.map +1 -0
  95. package/dist/src/risk/strategy-filter.d.ts +8 -0
  96. package/dist/src/risk/strategy-filter.d.ts.map +1 -0
  97. package/dist/src/risk/strategy-filter.js +40 -0
  98. package/dist/src/risk/strategy-filter.js.map +1 -0
  99. package/dist/src/risk/var-calculator.d.ts +10 -0
  100. package/dist/src/risk/var-calculator.d.ts.map +1 -0
  101. package/dist/src/risk/var-calculator.js +38 -0
  102. package/dist/src/risk/var-calculator.js.map +1 -0
  103. package/dist/src/signal/funding-radar.d.ts +4 -0
  104. package/dist/src/signal/funding-radar.d.ts.map +1 -0
  105. package/dist/src/signal/funding-radar.js +92 -0
  106. package/dist/src/signal/funding-radar.js.map +1 -0
  107. package/dist/src/signal/index.d.ts +12 -0
  108. package/dist/src/signal/index.d.ts.map +1 -0
  109. package/dist/src/signal/index.js +37 -0
  110. package/dist/src/signal/index.js.map +1 -0
  111. package/dist/src/signal/liquidation.d.ts +4 -0
  112. package/dist/src/signal/liquidation.d.ts.map +1 -0
  113. package/dist/src/signal/liquidation.js +83 -0
  114. package/dist/src/signal/liquidation.js.map +1 -0
  115. package/dist/src/signal/orderbook.d.ts +4 -0
  116. package/dist/src/signal/orderbook.d.ts.map +1 -0
  117. package/dist/src/signal/orderbook.js +100 -0
  118. package/dist/src/signal/orderbook.js.map +1 -0
  119. package/dist/src/signal/smart-money.d.ts +4 -0
  120. package/dist/src/signal/smart-money.d.ts.map +1 -0
  121. package/dist/src/signal/smart-money.js +39 -0
  122. package/dist/src/signal/smart-money.js.map +1 -0
  123. package/dist/src/signal/types.d.ts +13 -0
  124. package/dist/src/signal/types.d.ts.map +1 -0
  125. package/dist/src/signal/types.js +2 -0
  126. package/dist/src/signal/types.js.map +1 -0
  127. package/dist/src/skill/backtest.d.ts +5 -0
  128. package/dist/src/skill/backtest.d.ts.map +1 -0
  129. package/dist/src/skill/backtest.js +14 -0
  130. package/dist/src/skill/backtest.js.map +1 -0
  131. package/dist/src/skill/config.d.ts +4 -0
  132. package/dist/src/skill/config.d.ts.map +1 -0
  133. package/dist/src/skill/config.js +35 -0
  134. package/dist/src/skill/config.js.map +1 -0
  135. package/dist/src/skill/logs.d.ts +5 -0
  136. package/dist/src/skill/logs.d.ts.map +1 -0
  137. package/dist/src/skill/logs.js +37 -0
  138. package/dist/src/skill/logs.js.map +1 -0
  139. package/dist/src/skill/scan.d.ts +5 -0
  140. package/dist/src/skill/scan.d.ts.map +1 -0
  141. package/dist/src/skill/scan.js +75 -0
  142. package/dist/src/skill/scan.js.map +1 -0
  143. package/dist/src/skill/signal.d.ts +4 -0
  144. package/dist/src/skill/signal.d.ts.map +1 -0
  145. package/dist/src/skill/signal.js +63 -0
  146. package/dist/src/skill/signal.js.map +1 -0
  147. package/dist/src/skill/status.d.ts +2 -0
  148. package/dist/src/skill/status.d.ts.map +1 -0
  149. package/dist/src/skill/status.js +58 -0
  150. package/dist/src/skill/status.js.map +1 -0
  151. package/dist/src/skill/strategy.d.ts +4 -0
  152. package/dist/src/skill/strategy.d.ts.map +1 -0
  153. package/dist/src/skill/strategy.js +44 -0
  154. package/dist/src/skill/strategy.js.map +1 -0
  155. package/dist/src/skill/trade.d.ts +6 -0
  156. package/dist/src/skill/trade.d.ts.map +1 -0
  157. package/dist/src/skill/trade.js +58 -0
  158. package/dist/src/skill/trade.js.map +1 -0
  159. package/dist/src/strategy/funding-arb.d.ts +6 -0
  160. package/dist/src/strategy/funding-arb.d.ts.map +1 -0
  161. package/dist/src/strategy/funding-arb.js +57 -0
  162. package/dist/src/strategy/funding-arb.js.map +1 -0
  163. package/dist/src/strategy/index.d.ts +7 -0
  164. package/dist/src/strategy/index.d.ts.map +1 -0
  165. package/dist/src/strategy/index.js +27 -0
  166. package/dist/src/strategy/index.js.map +1 -0
  167. package/dist/src/strategy/liq-hunter.d.ts +6 -0
  168. package/dist/src/strategy/liq-hunter.d.ts.map +1 -0
  169. package/dist/src/strategy/liq-hunter.js +61 -0
  170. package/dist/src/strategy/liq-hunter.js.map +1 -0
  171. package/dist/src/strategy/ob-sniper.d.ts +6 -0
  172. package/dist/src/strategy/ob-sniper.d.ts.map +1 -0
  173. package/dist/src/strategy/ob-sniper.js +47 -0
  174. package/dist/src/strategy/ob-sniper.js.map +1 -0
  175. package/dist/src/strategy/pm-hedge.d.ts +6 -0
  176. package/dist/src/strategy/pm-hedge.d.ts.map +1 -0
  177. package/dist/src/strategy/pm-hedge.js +55 -0
  178. package/dist/src/strategy/pm-hedge.js.map +1 -0
  179. package/dist/src/strategy/smart-follow.d.ts +6 -0
  180. package/dist/src/strategy/smart-follow.d.ts.map +1 -0
  181. package/dist/src/strategy/smart-follow.js +44 -0
  182. package/dist/src/strategy/smart-follow.js.map +1 -0
  183. package/dist/src/strategy/types.d.ts +58 -0
  184. package/dist/src/strategy/types.d.ts.map +1 -0
  185. package/dist/src/strategy/types.js +2 -0
  186. package/dist/src/strategy/types.js.map +1 -0
  187. package/package.json +54 -0
@@ -0,0 +1,137 @@
1
+ # BfxSentry Agent 默认配置
2
+
3
+ engine:
4
+ mode: dry-run # dry-run | live
5
+ log_level: info # debug | info | warn | error
6
+
7
+ collector:
8
+ bitfinex:
9
+ base_url: https://api-pub.bitfinex.com
10
+ symbol: tBTCUSD
11
+ deriv_symbol: tBTCF0:USTF0
12
+ funding_symbol: fUSD
13
+ ws_url: wss://api-pub.bitfinex.com/ws/2
14
+ polymarket:
15
+ gamma_url: https://gamma-api.polymarket.com
16
+ clob_url: https://clob.polymarket.com
17
+
18
+ smart_follow:
19
+ enabled: true
20
+ tick_interval: 180
21
+ entry_conditions:
22
+ min_score: 65
23
+ min_whales_aligned: 5
24
+ min_correlation: 0.5
25
+ position_confirm: true
26
+ exit_conditions:
27
+ score_drop_below: 45
28
+ whale_flip_count: 3
29
+ max_hold_hours: 24
30
+ trailing_stop_pct: 1.5
31
+ risk:
32
+ size_pct: 8
33
+ max_leverage: 2
34
+ stop_loss_pct: 2.0
35
+
36
+ funding_arb:
37
+ enabled: true
38
+ tick_interval: 300
39
+ lend:
40
+ min_rate_percentile: 0.75
41
+ min_utilization: 0.80
42
+ min_spare_capacity: 0.15
43
+ lend_amount_pct: 25
44
+ preferred_period_days: 7
45
+ high_rate_period_days: 30
46
+ high_rate_threshold: 0.90
47
+ warning:
48
+ rate_spike_pct: 5
49
+ critical_utilization: 0.90
50
+ exit_conditions:
51
+ rate_drop_percentile: 0.30
52
+ supply_recovery_pct: 2
53
+
54
+ liq_hunter:
55
+ enabled: true
56
+ tick_interval: 5
57
+ trend_follow:
58
+ min_intensity_pct: 0.85
59
+ min_dominance: 0.70
60
+ min_price_move_pct: 0.3
61
+ price_window_sec: 180
62
+ reversal:
63
+ min_intensity_pct: 0.95
64
+ price_stall_pct: 0.1
65
+ require_ob_confirm: true
66
+ ob_imbalance_threshold: 1.2
67
+ risk:
68
+ size_pct: 5
69
+ max_leverage: 3
70
+ trend_stop_pct: 0.5
71
+ reversal_stop_pct: 0.3
72
+ take_profit_pct: 1.0
73
+ cooldown_sec: 300
74
+
75
+ ob_sniper:
76
+ enabled: true
77
+ tick_interval: 5
78
+ entry_conditions:
79
+ imbalance_buy: 1.5
80
+ imbalance_sell: 0.67
81
+ depth_range_pct: 0.5
82
+ require_flow_confirm: true
83
+ flow_buy_ratio: 0.60
84
+ flow_sell_ratio: 0.40
85
+ flow_window_sec: 60
86
+ wall_multiplier: 5
87
+ wall_break_price_pct: 0.1
88
+ risk:
89
+ size_pct: 5
90
+ max_leverage: 3
91
+ stop_loss_pct: 0.3
92
+ take_profit_pct: 0.5
93
+ signal_ttl_sec: 120
94
+ cooldown_sec: 120
95
+
96
+ pm_hedge:
97
+ enabled: true
98
+ tick_interval: 15
99
+ signal_driven:
100
+ min_confidence: 20
101
+ min_edge_pct: 3
102
+ stake_usdc: 100
103
+ market_making:
104
+ min_spread_cents: 2
105
+ max_inventory_imbalance: 0.3
106
+ hedge_when_imbalance: 0.2
107
+ hedge:
108
+ delta: 0.5
109
+ bfx_instrument: tBTCF0:USTF0
110
+ max_bfx_position_btc: 0.1
111
+
112
+ risk:
113
+ max_total_position_usd: 5000
114
+ max_daily_loss_usd: 200
115
+ max_daily_trades: 50
116
+ max_concurrent_positions: 3
117
+ conflict_resolution: conservative
118
+ same_direction_cooldown_sec: 300
119
+ opposite_signal_cooldown_sec: 60
120
+ max_slippage_pct: 0.1
121
+ order_type: limit
122
+ limit_offset_pct: 0.02
123
+ portfolio:
124
+ max_portfolio_var_pct: 3
125
+ var_confidence: 0.95
126
+ max_same_direction_pct: 70
127
+ circuit_breaker:
128
+ consecutive_losses: 5
129
+ loss_streak_usd: 300
130
+ cooldown_minutes: 60
131
+ action: pause_all
132
+ trading_hours:
133
+ enabled: false
134
+
135
+ recorder:
136
+ enabled: true
137
+ retention_days: 30
@@ -0,0 +1,24 @@
1
+ # Phase 1 安全覆盖 (前 2 周实盘)
2
+ # 使用: sentry start --mode live --config config/phase1-safety.yaml
3
+
4
+ risk:
5
+ max_total_position_usd: 2000
6
+ max_daily_trades: 15
7
+ max_concurrent_positions: 1
8
+ portfolio:
9
+ circuit_breaker:
10
+ consecutive_losses: 3
11
+ cooldown_minutes: 120
12
+
13
+ smart_follow:
14
+ entry_conditions:
15
+ min_score: 70
16
+ risk:
17
+ size_pct: 5
18
+
19
+ liq_hunter:
20
+ risk:
21
+ size_pct: 3
22
+
23
+ pm_hedge:
24
+ enabled: false
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=sentry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentry.d.ts","sourceRoot":"","sources":["../../bin/sentry.ts"],"names":[],"mappings":""}
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { initLogger } from '../src/core/logger.js';
4
+ import { loadConfig } from '../src/core/config.js';
5
+ import { startEngine, stopEngine } from '../src/core/engine.js';
6
+ import { scanCommand } from '../src/skill/scan.js';
7
+ import { signalCommand } from '../src/skill/signal.js';
8
+ import { strategyCommand } from '../src/skill/strategy.js';
9
+ import { positionCommand } from '../src/skill/status.js';
10
+ import { tradeCommand } from '../src/skill/trade.js';
11
+ import { backtestCommand } from '../src/skill/backtest.js';
12
+ import { configCommand } from '../src/skill/config.js';
13
+ import { logsCommand } from '../src/skill/logs.js';
14
+ const program = new Command();
15
+ program
16
+ .name('sentry')
17
+ .description('BfxSentry Agent CLI — Bitfinex 信号驱动交易代理')
18
+ .version('0.1.0');
19
+ // ── sentry scan ──
20
+ program
21
+ .command('scan')
22
+ .description('全市场一次性扫描, 不交易')
23
+ .option('--json', 'JSON 输出')
24
+ .option('-c, --config <path>', '自定义配置文件')
25
+ .action(async (options) => {
26
+ initLogger('silent');
27
+ await scanCommand(options);
28
+ });
29
+ // ── sentry signal ──
30
+ program
31
+ .command('signal [module]')
32
+ .description('查看信号详情 (smart-money|funding|liquidation|orderbook|polymarket)')
33
+ .option('-c, --config <path>', '自定义配置文件')
34
+ .action(async (module, options) => {
35
+ initLogger('silent');
36
+ await signalCommand(module, options);
37
+ });
38
+ // ── sentry strategy ──
39
+ program
40
+ .command('strategy [name]')
41
+ .description('查看策略状态 (smart-follow|funding-arb|liq-hunter|ob-sniper|pm-hedge)')
42
+ .option('-c, --config <path>', '自定义配置文件')
43
+ .action(async (name, options) => {
44
+ initLogger('silent');
45
+ await strategyCommand(name, options);
46
+ });
47
+ // ── sentry position ──
48
+ program
49
+ .command('position [action] [id]')
50
+ .description('持仓管理 (close <id> | close-all)')
51
+ .action(async (action, id) => {
52
+ initLogger('silent');
53
+ await positionCommand(action, id);
54
+ });
55
+ // ── sentry trade ──
56
+ program
57
+ .command('trade <direction> <size>')
58
+ .description('手动交易 (long|short <btc_size> [--stop 2%] [--tp 3%])')
59
+ .option('--stop <pct>', '止损百分比', '2%')
60
+ .option('--tp <pct>', '止盈百分比', '3%')
61
+ .option('-c, --config <path>', '自定义配置文件')
62
+ .action(async (direction, size, options) => {
63
+ initLogger('silent');
64
+ await tradeCommand(direction, size, options);
65
+ });
66
+ // ── sentry backtest ──
67
+ program
68
+ .command('backtest [strategy]')
69
+ .description('回测策略 (liq-hunter|smart-follow|ob-sniper|funding-arb|pm-hedge)')
70
+ .option('-d, --days <n>', '回测天数', '7')
71
+ .option('-c, --config <path>', '自定义配置文件')
72
+ .action(async (strategy, options) => {
73
+ initLogger('silent');
74
+ await backtestCommand(strategy, options);
75
+ });
76
+ // ── sentry config ──
77
+ program
78
+ .command('config <action> [args...]')
79
+ .description('配置管理 (show | set <path> <value>)')
80
+ .option('-c, --config <path>', '自定义配置文件')
81
+ .action(async (action, args, options) => {
82
+ initLogger('silent');
83
+ await configCommand(action, args, options);
84
+ });
85
+ // ── sentry logs ──
86
+ program
87
+ .command('logs')
88
+ .description('查看交易日志')
89
+ .option('-l, --level <level>', '日志级别 (all|warn)', 'all')
90
+ .option('-n, --limit <n>', '显示条数', '20')
91
+ .action(async (options) => {
92
+ initLogger('silent');
93
+ await logsCommand(options);
94
+ });
95
+ // ── sentry start ──
96
+ program
97
+ .command('start')
98
+ .description('启动 Agent (持续运行)')
99
+ .option('-m, --mode <mode>', '运行模式 (dry-run|live)', 'dry-run')
100
+ .option('-c, --config <path>', '自定义配置文件')
101
+ .option('-i, --interval <sec>', 'Tick 间隔 (秒)', '10')
102
+ .action(async (options) => {
103
+ const cfg = loadConfig(options.config);
104
+ cfg.engine.mode = options.mode;
105
+ initLogger(cfg.engine.log_level);
106
+ console.log(`\n BfxSentry Agent 启动中... (${cfg.engine.mode} 模式)\n`);
107
+ const shutdown = () => {
108
+ console.log('\n 正在停止...');
109
+ stopEngine();
110
+ setTimeout(() => process.exit(0), 1000);
111
+ };
112
+ process.on('SIGINT', shutdown);
113
+ process.on('SIGTERM', shutdown);
114
+ await startEngine(cfg, parseInt(options.interval));
115
+ });
116
+ // ── sentry stop ──
117
+ program
118
+ .command('stop')
119
+ .description('停止 Agent')
120
+ .action(() => {
121
+ stopEngine();
122
+ });
123
+ program.parse();
124
+ //# sourceMappingURL=sentry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentry.js","sourceRoot":"","sources":["../../bin/sentry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { TradeIntent, ExecutionResult } from '../strategy/types.js';
2
+ import type { MarketSnapshot } from '../collector/types.js';
3
+ export declare function simulateFill(intent: TradeIntent, snapshot: MarketSnapshot): ExecutionResult;
4
+ export declare function wouldFillLimit(price: number, direction: 'long' | 'short', nextSnapshot: MarketSnapshot): boolean;
5
+ //# sourceMappingURL=fill-simulator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fill-simulator.d.ts","sourceRoot":"","sources":["../../../src/backtest/fill-simulator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAG3D,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,GAAG,eAAe,CAgC3F;AAGD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAAG,OAAO,EAC3B,YAAY,EAAE,cAAc,GAC3B,OAAO,CAQT"}
@@ -0,0 +1,43 @@
1
+ // Simulates order fills conservatively using recorded snapshot data
2
+ export function simulateFill(intent, snapshot) {
3
+ const { ticker, orderbook } = snapshot;
4
+ // Market order: fill at best bid/ask with slippage
5
+ const bestBid = orderbook.bids[0]?.price || ticker.lastPrice;
6
+ const bestAsk = orderbook.asks[0]?.price || ticker.lastPrice;
7
+ let fillPrice;
8
+ if (intent.direction === 'long') {
9
+ // Buying: fill at ask + estimated slippage from depth
10
+ const depth = orderbook.askDepth02;
11
+ const slippage = depth > 0 ? Math.min(0.001, 0.01 / depth) : 0.001;
12
+ fillPrice = bestAsk * (1 + slippage);
13
+ }
14
+ else {
15
+ // Selling: fill at bid - estimated slippage
16
+ const depth = orderbook.bidDepth02;
17
+ const slippage = depth > 0 ? Math.min(0.001, 0.01 / depth) : 0.001;
18
+ fillPrice = bestBid * (1 - slippage);
19
+ }
20
+ const capitalUsd = 5000;
21
+ const sizeUsd = capitalUsd * (intent.sizePct / 100);
22
+ const fillSize = sizeUsd / fillPrice;
23
+ return {
24
+ success: true,
25
+ orderId: `bt-${intent.id}`,
26
+ fillPrice,
27
+ fillSize,
28
+ fee: sizeUsd * 0.001,
29
+ timestamp: snapshot.timestamp,
30
+ };
31
+ }
32
+ // Check if a limit order would have been filled
33
+ export function wouldFillLimit(price, direction, nextSnapshot) {
34
+ if (direction === 'long') {
35
+ // Buy limit fills when ask drops to or below price
36
+ return nextSnapshot.ticker.low <= price;
37
+ }
38
+ else {
39
+ // Sell limit fills when bid rises to or above price
40
+ return nextSnapshot.ticker.high >= price;
41
+ }
42
+ }
43
+ //# sourceMappingURL=fill-simulator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fill-simulator.js","sourceRoot":"","sources":["../../../src/backtest/fill-simulator.ts"],"names":[],"mappings":"AAGA,oEAAoE;AACpE,MAAM,UAAU,YAAY,CAAC,MAAmB,EAAE,QAAwB;IACxE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAA;IAEtC,mDAAmD;IACnD,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,MAAM,CAAC,SAAS,CAAA;IAC5D,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,MAAM,CAAC,SAAS,CAAA;IAE5D,IAAI,SAAiB,CAAA;IACrB,IAAI,MAAM,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;QAChC,sDAAsD;QACtD,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAA;QAClC,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;QAClE,SAAS,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAA;IACtC,CAAC;SAAM,CAAC;QACN,4CAA4C;QAC5C,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAA;QAClC,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;QAClE,SAAS,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAA;IACtC,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAA;IACvB,MAAM,OAAO,GAAG,UAAU,GAAG,CAAC,MAAM,CAAC,OAAO,GAAG,GAAG,CAAC,CAAA;IACnD,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAA;IAEpC,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,MAAM,MAAM,CAAC,EAAE,EAAE;QAC1B,SAAS;QACT,QAAQ;QACR,GAAG,EAAE,OAAO,GAAG,KAAK;QACpB,SAAS,EAAE,QAAQ,CAAC,SAAS;KAC9B,CAAA;AACH,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,cAAc,CAC5B,KAAa,EACb,SAA2B,EAC3B,YAA4B;IAE5B,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACzB,mDAAmD;QACnD,OAAO,YAAY,CAAC,MAAM,CAAC,GAAG,IAAI,KAAK,CAAA;IACzC,CAAC;SAAM,CAAC;QACN,oDAAoD;QACpD,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,IAAI,KAAK,CAAA;IAC1C,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { BacktestResult } from './runner.js';
2
+ export declare function printBacktestReport(result: BacktestResult): void;
3
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../src/backtest/report.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,QA+CzD"}
@@ -0,0 +1,43 @@
1
+ import chalk from 'chalk';
2
+ export function printBacktestReport(result) {
3
+ const { summary, period, trades } = result;
4
+ console.log('');
5
+ console.log(chalk.bold.cyan('═══════════════════════════════════════════════════'));
6
+ console.log(chalk.bold.cyan(' BfxSentry · 回测报告'));
7
+ console.log(chalk.bold.cyan('═══════════════════════════════════════════════════'));
8
+ console.log('');
9
+ console.log(` 策略: ${chalk.bold(result.strategy)}`);
10
+ console.log(` 区间: ${new Date(period.start).toLocaleDateString()} — ${new Date(period.end).toLocaleDateString()} (${period.days} 天)`);
11
+ console.log(` 快照数: ${result.snapshotsUsed}`);
12
+ console.log('');
13
+ console.log(chalk.bold(' ── 绩效概览 ──'));
14
+ console.log('');
15
+ const pnlColor = summary.totalPnl >= 0 ? chalk.green : chalk.red;
16
+ console.log(` 总交易: ${summary.totalTrades}`);
17
+ console.log(` 胜/负: ${chalk.green(String(summary.wins))} / ${chalk.red(String(summary.losses))}`);
18
+ console.log(` 胜率: ${(summary.winRate * 100).toFixed(1)}%`);
19
+ console.log(` 总 PnL: ${pnlColor('$' + summary.totalPnl.toFixed(2))}`);
20
+ console.log(` 均 PnL: $${summary.avgPnl.toFixed(2)}`);
21
+ console.log(` 最大回撤: ${(summary.maxDrawdown * 100).toFixed(2)}%`);
22
+ console.log(` Sharpe: ${summary.sharpeRatio.toFixed(2)}`);
23
+ console.log('');
24
+ if (trades.length > 0) {
25
+ console.log(chalk.bold(' ── 最近交易 ──'));
26
+ console.log('');
27
+ console.log(chalk.dim(' 时间 策略 方向 入场 出场 PnL'));
28
+ console.log(chalk.dim(' ─────────────────────────────────────────────────────────────────────'));
29
+ const recent = trades.slice(-15);
30
+ for (const t of recent) {
31
+ const dir = t.direction === 'long' ? chalk.green('多') : chalk.red('空');
32
+ const pnl = t.pnl >= 0 ? chalk.green(`+$${t.pnl.toFixed(2)}`) : chalk.red(`-$${Math.abs(t.pnl).toFixed(2)}`);
33
+ const time = new Date(t.timestamp).toLocaleString().padEnd(20);
34
+ console.log(` ${time} ${t.strategy.padEnd(14)} ${dir} $${t.entryPrice.toFixed(0).padEnd(10)} $${t.exitPrice.toFixed(0).padEnd(10)} ${pnl}`);
35
+ }
36
+ console.log('');
37
+ }
38
+ if (trades.length === 0) {
39
+ console.log(chalk.yellow(' 没有录制数据可供回测。先运行 sentry start 采集数据。'));
40
+ console.log('');
41
+ }
42
+ }
43
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/backtest/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { AgentConfig } from '../core/config.js';
2
+ export interface BacktestResult {
3
+ strategy: string | 'all';
4
+ period: {
5
+ start: number;
6
+ end: number;
7
+ days: number;
8
+ };
9
+ snapshotsUsed: number;
10
+ trades: BacktestTrade[];
11
+ summary: {
12
+ totalTrades: number;
13
+ wins: number;
14
+ losses: number;
15
+ winRate: number;
16
+ totalPnl: number;
17
+ avgPnl: number;
18
+ maxDrawdown: number;
19
+ sharpeRatio: number;
20
+ };
21
+ }
22
+ interface BacktestTrade {
23
+ timestamp: number;
24
+ strategy: string;
25
+ direction: 'long' | 'short';
26
+ entryPrice: number;
27
+ exitPrice: number;
28
+ pnl: number;
29
+ holdingMs: number;
30
+ reason: string;
31
+ }
32
+ export declare function runBacktest(config: AgentConfig, strategyFilter_: string | undefined, days: number): Promise<BacktestResult>;
33
+ export {};
34
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/backtest/runner.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAMpD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAA;IACxB,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACpD,aAAa,EAAE,MAAM,CAAA;IACrB,MAAM,EAAE,aAAa,EAAE,CAAA;IACvB,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAA;QACnB,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,MAAM,CAAA;QACd,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,EAAE,MAAM,CAAA;QACd,WAAW,EAAE,MAAM,CAAA;QACnB,WAAW,EAAE,MAAM,CAAA;KACpB,CAAA;CACF;AAED,UAAU,aAAa;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,WAAW,EACnB,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,cAAc,CAAC,CAwHzB"}
@@ -0,0 +1,132 @@
1
+ import Database from 'better-sqlite3';
2
+ import { resolve } from 'node:path';
3
+ import { generateAllSignals } from '../signal/index.js';
4
+ import { evaluateAllStrategies } from '../strategy/index.js';
5
+ import { strategyFilter } from '../risk/strategy-filter.js';
6
+ import { portfolioFilter } from '../risk/portfolio-filter.js';
7
+ import { simulateFill } from './fill-simulator.js';
8
+ import { openPosition, closePosition, checkStopLossAndTakeProfit, updatePositionPrices, getPositions } from '../risk/position-manager.js';
9
+ const DB_PATH = resolve(import.meta.dirname, '..', '..', 'data', 'sentry.db');
10
+ export async function runBacktest(config, strategyFilter_, days) {
11
+ const db = new Database(DB_PATH, { readonly: true });
12
+ const cutoff = Date.now() - days * 86400_000;
13
+ const rows = db.prepare(`
14
+ SELECT data_json, signals_json, timestamp FROM snapshots
15
+ WHERE timestamp >= ? ORDER BY timestamp ASC
16
+ `).all(cutoff);
17
+ db.close();
18
+ if (rows.length === 0) {
19
+ return emptyResult(strategyFilter_ || 'all', days);
20
+ }
21
+ const trades = [];
22
+ let equity = 5000;
23
+ let peakEquity = equity;
24
+ let maxDrawdown = 0;
25
+ const returns = [];
26
+ for (let i = 0; i < rows.length; i++) {
27
+ const snapshot = JSON.parse(rows[i].data_json);
28
+ const price = snapshot.ticker.lastPrice;
29
+ // Update positions
30
+ updatePositionPrices(price);
31
+ // Check stop loss / take profit
32
+ const closed = checkStopLossAndTakeProfit(price);
33
+ for (const c of closed) {
34
+ const pos = getPositions().find(p => p.id === c.posId);
35
+ trades.push({
36
+ timestamp: snapshot.timestamp,
37
+ strategy: pos?.strategy || 'unknown',
38
+ direction: pos?.direction || 'long',
39
+ entryPrice: pos?.entryPrice || 0,
40
+ exitPrice: price,
41
+ pnl: c.pnl,
42
+ holdingMs: pos ? snapshot.timestamp - pos.openedAt : 0,
43
+ reason: c.reason,
44
+ });
45
+ equity += c.pnl;
46
+ returns.push(c.pnl / equity);
47
+ }
48
+ // Generate signals and evaluate strategies
49
+ const signals = generateAllSignals(snapshot);
50
+ let intents = evaluateAllStrategies(signals, snapshot, config);
51
+ if (strategyFilter_) {
52
+ intents = intents.filter(i => i.strategy === strategyFilter_);
53
+ }
54
+ // Risk filter + execute
55
+ for (const intent of intents) {
56
+ const sf = strategyFilter(intent, config);
57
+ if (!sf.passed)
58
+ continue;
59
+ const pf = portfolioFilter(intent, config);
60
+ if (!pf.passed)
61
+ continue;
62
+ const result = simulateFill(intent, snapshot);
63
+ if (result.success) {
64
+ openPosition(intent, result);
65
+ }
66
+ }
67
+ // Track drawdown
68
+ if (equity > peakEquity)
69
+ peakEquity = equity;
70
+ const dd = (peakEquity - equity) / peakEquity;
71
+ if (dd > maxDrawdown)
72
+ maxDrawdown = dd;
73
+ }
74
+ // Close remaining positions at last price
75
+ const lastSnapshot = JSON.parse(rows[rows.length - 1].data_json);
76
+ const remaining = getPositions();
77
+ for (const pos of remaining) {
78
+ const pnl = closePosition(pos.id, lastSnapshot.ticker.lastPrice, '回测结束');
79
+ trades.push({
80
+ timestamp: lastSnapshot.timestamp,
81
+ strategy: pos.strategy,
82
+ direction: pos.direction,
83
+ entryPrice: pos.entryPrice,
84
+ exitPrice: lastSnapshot.ticker.lastPrice,
85
+ pnl,
86
+ holdingMs: lastSnapshot.timestamp - pos.openedAt,
87
+ reason: '回测结束平仓',
88
+ });
89
+ equity += pnl;
90
+ returns.push(pnl / equity);
91
+ }
92
+ const wins = trades.filter(t => t.pnl > 0).length;
93
+ const totalPnl = trades.reduce((s, t) => s + t.pnl, 0);
94
+ const avgReturn = returns.length > 0 ? returns.reduce((a, b) => a + b, 0) / returns.length : 0;
95
+ const stdReturn = returns.length > 1
96
+ ? Math.sqrt(returns.reduce((s, r) => s + (r - avgReturn) ** 2, 0) / (returns.length - 1))
97
+ : 0;
98
+ const sharpe = stdReturn > 0 ? (avgReturn / stdReturn) * Math.sqrt(252) : 0;
99
+ return {
100
+ strategy: strategyFilter_ || 'all',
101
+ period: {
102
+ start: rows[0].timestamp,
103
+ end: rows[rows.length - 1].timestamp,
104
+ days,
105
+ },
106
+ snapshotsUsed: rows.length,
107
+ trades,
108
+ summary: {
109
+ totalTrades: trades.length,
110
+ wins,
111
+ losses: trades.length - wins,
112
+ winRate: trades.length > 0 ? wins / trades.length : 0,
113
+ totalPnl,
114
+ avgPnl: trades.length > 0 ? totalPnl / trades.length : 0,
115
+ maxDrawdown,
116
+ sharpeRatio: sharpe,
117
+ },
118
+ };
119
+ }
120
+ function emptyResult(strategy, days) {
121
+ return {
122
+ strategy,
123
+ period: { start: 0, end: 0, days },
124
+ snapshotsUsed: 0,
125
+ trades: [],
126
+ summary: {
127
+ totalTrades: 0, wins: 0, losses: 0, winRate: 0,
128
+ totalPnl: 0, avgPnl: 0, maxDrawdown: 0, sharpeRatio: 0,
129
+ },
130
+ };
131
+ }
132
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/backtest/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export interface BasisSnapshot {
2
+ timestamp: number;
3
+ bfxPrice: number;
4
+ binancePrice: number | null;
5
+ bfxVsBinance: number | null;
6
+ }
7
+ export declare function fetchBinancePrice(): Promise<number | null>;
8
+ export declare function calculateBasis(bfxPrice: number): Promise<BasisSnapshot>;
9
+ //# sourceMappingURL=basis-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basis-monitor.d.ts","sourceRoot":"","sources":["../../../src/collector/basis-monitor.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B;AAsBD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOhE;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAiB7E"}