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.
- package/config/default.yaml +137 -0
- package/config/phase1-safety.yaml +24 -0
- package/dist/bin/sentry.d.ts +3 -0
- package/dist/bin/sentry.d.ts.map +1 -0
- package/dist/bin/sentry.js +124 -0
- package/dist/bin/sentry.js.map +1 -0
- package/dist/src/backtest/fill-simulator.d.ts +5 -0
- package/dist/src/backtest/fill-simulator.d.ts.map +1 -0
- package/dist/src/backtest/fill-simulator.js +43 -0
- package/dist/src/backtest/fill-simulator.js.map +1 -0
- package/dist/src/backtest/report.d.ts +3 -0
- package/dist/src/backtest/report.d.ts.map +1 -0
- package/dist/src/backtest/report.js +43 -0
- package/dist/src/backtest/report.js.map +1 -0
- package/dist/src/backtest/runner.d.ts +34 -0
- package/dist/src/backtest/runner.d.ts.map +1 -0
- package/dist/src/backtest/runner.js +132 -0
- package/dist/src/backtest/runner.js.map +1 -0
- package/dist/src/collector/basis-monitor.d.ts +9 -0
- package/dist/src/collector/basis-monitor.d.ts.map +1 -0
- package/dist/src/collector/basis-monitor.js +52 -0
- package/dist/src/collector/basis-monitor.js.map +1 -0
- package/dist/src/collector/bitfinex-rest.d.ts +20 -0
- package/dist/src/collector/bitfinex-rest.d.ts.map +1 -0
- package/dist/src/collector/bitfinex-rest.js +350 -0
- package/dist/src/collector/bitfinex-rest.js.map +1 -0
- package/dist/src/collector/event-detector.d.ts +3 -0
- package/dist/src/collector/event-detector.d.ts.map +1 -0
- package/dist/src/collector/event-detector.js +41 -0
- package/dist/src/collector/event-detector.js.map +1 -0
- package/dist/src/collector/polymarket.d.ts +32 -0
- package/dist/src/collector/polymarket.d.ts.map +1 -0
- package/dist/src/collector/polymarket.js +89 -0
- package/dist/src/collector/polymarket.js.map +1 -0
- package/dist/src/collector/types.d.ts +114 -0
- package/dist/src/collector/types.d.ts.map +1 -0
- package/dist/src/collector/types.js +2 -0
- package/dist/src/collector/types.js.map +1 -0
- package/dist/src/core/config.d.ts +67 -0
- package/dist/src/core/config.d.ts.map +1 -0
- package/dist/src/core/config.js +27 -0
- package/dist/src/core/config.js.map +1 -0
- package/dist/src/core/decision-log.d.ts +7 -0
- package/dist/src/core/decision-log.d.ts.map +1 -0
- package/dist/src/core/decision-log.js +69 -0
- package/dist/src/core/decision-log.js.map +1 -0
- package/dist/src/core/engine.d.ts +19 -0
- package/dist/src/core/engine.d.ts.map +1 -0
- package/dist/src/core/engine.js +148 -0
- package/dist/src/core/engine.js.map +1 -0
- package/dist/src/core/event-bus.d.ts +12 -0
- package/dist/src/core/event-bus.d.ts.map +1 -0
- package/dist/src/core/event-bus.js +21 -0
- package/dist/src/core/event-bus.js.map +1 -0
- package/dist/src/core/logger.d.ts +4 -0
- package/dist/src/core/logger.d.ts.map +1 -0
- package/dist/src/core/logger.js +22 -0
- package/dist/src/core/logger.js.map +1 -0
- package/dist/src/core/recorder.d.ts +7 -0
- package/dist/src/core/recorder.d.ts.map +1 -0
- package/dist/src/core/recorder.js +42 -0
- package/dist/src/core/recorder.js.map +1 -0
- package/dist/src/executor/bitfinex-trader.d.ts +3 -0
- package/dist/src/executor/bitfinex-trader.d.ts.map +1 -0
- package/dist/src/executor/bitfinex-trader.js +119 -0
- package/dist/src/executor/bitfinex-trader.js.map +1 -0
- package/dist/src/executor/dry-run.d.ts +4 -0
- package/dist/src/executor/dry-run.d.ts.map +1 -0
- package/dist/src/executor/dry-run.js +39 -0
- package/dist/src/executor/dry-run.js.map +1 -0
- package/dist/src/executor/order-id.d.ts +5 -0
- package/dist/src/executor/order-id.d.ts.map +1 -0
- package/dist/src/executor/order-id.js +20 -0
- package/dist/src/executor/order-id.js.map +1 -0
- package/dist/src/executor/reconciler.d.ts +8 -0
- package/dist/src/executor/reconciler.d.ts.map +1 -0
- package/dist/src/executor/reconciler.js +44 -0
- package/dist/src/executor/reconciler.js.map +1 -0
- package/dist/src/executor/types.d.ts +19 -0
- package/dist/src/executor/types.d.ts.map +1 -0
- package/dist/src/executor/types.js +2 -0
- package/dist/src/executor/types.js.map +1 -0
- package/dist/src/risk/cooldown.d.ts +8 -0
- package/dist/src/risk/cooldown.d.ts.map +1 -0
- package/dist/src/risk/cooldown.js +30 -0
- package/dist/src/risk/cooldown.js.map +1 -0
- package/dist/src/risk/portfolio-filter.d.ts +9 -0
- package/dist/src/risk/portfolio-filter.d.ts.map +1 -0
- package/dist/src/risk/portfolio-filter.js +58 -0
- package/dist/src/risk/portfolio-filter.js.map +1 -0
- package/dist/src/risk/position-manager.d.ts +19 -0
- package/dist/src/risk/position-manager.d.ts.map +1 -0
- package/dist/src/risk/position-manager.js +171 -0
- package/dist/src/risk/position-manager.js.map +1 -0
- package/dist/src/risk/strategy-filter.d.ts +8 -0
- package/dist/src/risk/strategy-filter.d.ts.map +1 -0
- package/dist/src/risk/strategy-filter.js +40 -0
- package/dist/src/risk/strategy-filter.js.map +1 -0
- package/dist/src/risk/var-calculator.d.ts +10 -0
- package/dist/src/risk/var-calculator.d.ts.map +1 -0
- package/dist/src/risk/var-calculator.js +38 -0
- package/dist/src/risk/var-calculator.js.map +1 -0
- package/dist/src/signal/funding-radar.d.ts +4 -0
- package/dist/src/signal/funding-radar.d.ts.map +1 -0
- package/dist/src/signal/funding-radar.js +92 -0
- package/dist/src/signal/funding-radar.js.map +1 -0
- package/dist/src/signal/index.d.ts +12 -0
- package/dist/src/signal/index.d.ts.map +1 -0
- package/dist/src/signal/index.js +37 -0
- package/dist/src/signal/index.js.map +1 -0
- package/dist/src/signal/liquidation.d.ts +4 -0
- package/dist/src/signal/liquidation.d.ts.map +1 -0
- package/dist/src/signal/liquidation.js +83 -0
- package/dist/src/signal/liquidation.js.map +1 -0
- package/dist/src/signal/orderbook.d.ts +4 -0
- package/dist/src/signal/orderbook.d.ts.map +1 -0
- package/dist/src/signal/orderbook.js +100 -0
- package/dist/src/signal/orderbook.js.map +1 -0
- package/dist/src/signal/smart-money.d.ts +4 -0
- package/dist/src/signal/smart-money.d.ts.map +1 -0
- package/dist/src/signal/smart-money.js +39 -0
- package/dist/src/signal/smart-money.js.map +1 -0
- package/dist/src/signal/types.d.ts +13 -0
- package/dist/src/signal/types.d.ts.map +1 -0
- package/dist/src/signal/types.js +2 -0
- package/dist/src/signal/types.js.map +1 -0
- package/dist/src/skill/backtest.d.ts +5 -0
- package/dist/src/skill/backtest.d.ts.map +1 -0
- package/dist/src/skill/backtest.js +14 -0
- package/dist/src/skill/backtest.js.map +1 -0
- package/dist/src/skill/config.d.ts +4 -0
- package/dist/src/skill/config.d.ts.map +1 -0
- package/dist/src/skill/config.js +35 -0
- package/dist/src/skill/config.js.map +1 -0
- package/dist/src/skill/logs.d.ts +5 -0
- package/dist/src/skill/logs.d.ts.map +1 -0
- package/dist/src/skill/logs.js +37 -0
- package/dist/src/skill/logs.js.map +1 -0
- package/dist/src/skill/scan.d.ts +5 -0
- package/dist/src/skill/scan.d.ts.map +1 -0
- package/dist/src/skill/scan.js +75 -0
- package/dist/src/skill/scan.js.map +1 -0
- package/dist/src/skill/signal.d.ts +4 -0
- package/dist/src/skill/signal.d.ts.map +1 -0
- package/dist/src/skill/signal.js +63 -0
- package/dist/src/skill/signal.js.map +1 -0
- package/dist/src/skill/status.d.ts +2 -0
- package/dist/src/skill/status.d.ts.map +1 -0
- package/dist/src/skill/status.js +58 -0
- package/dist/src/skill/status.js.map +1 -0
- package/dist/src/skill/strategy.d.ts +4 -0
- package/dist/src/skill/strategy.d.ts.map +1 -0
- package/dist/src/skill/strategy.js +44 -0
- package/dist/src/skill/strategy.js.map +1 -0
- package/dist/src/skill/trade.d.ts +6 -0
- package/dist/src/skill/trade.d.ts.map +1 -0
- package/dist/src/skill/trade.js +58 -0
- package/dist/src/skill/trade.js.map +1 -0
- package/dist/src/strategy/funding-arb.d.ts +6 -0
- package/dist/src/strategy/funding-arb.d.ts.map +1 -0
- package/dist/src/strategy/funding-arb.js +57 -0
- package/dist/src/strategy/funding-arb.js.map +1 -0
- package/dist/src/strategy/index.d.ts +7 -0
- package/dist/src/strategy/index.d.ts.map +1 -0
- package/dist/src/strategy/index.js +27 -0
- package/dist/src/strategy/index.js.map +1 -0
- package/dist/src/strategy/liq-hunter.d.ts +6 -0
- package/dist/src/strategy/liq-hunter.d.ts.map +1 -0
- package/dist/src/strategy/liq-hunter.js +61 -0
- package/dist/src/strategy/liq-hunter.js.map +1 -0
- package/dist/src/strategy/ob-sniper.d.ts +6 -0
- package/dist/src/strategy/ob-sniper.d.ts.map +1 -0
- package/dist/src/strategy/ob-sniper.js +47 -0
- package/dist/src/strategy/ob-sniper.js.map +1 -0
- package/dist/src/strategy/pm-hedge.d.ts +6 -0
- package/dist/src/strategy/pm-hedge.d.ts.map +1 -0
- package/dist/src/strategy/pm-hedge.js +55 -0
- package/dist/src/strategy/pm-hedge.js.map +1 -0
- package/dist/src/strategy/smart-follow.d.ts +6 -0
- package/dist/src/strategy/smart-follow.d.ts.map +1 -0
- package/dist/src/strategy/smart-follow.js +44 -0
- package/dist/src/strategy/smart-follow.js.map +1 -0
- package/dist/src/strategy/types.d.ts +58 -0
- package/dist/src/strategy/types.d.ts.map +1 -0
- package/dist/src/strategy/types.js +2 -0
- package/dist/src/strategy/types.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { loadConfig } from '../core/config.js';
|
|
3
|
+
import { getRecentDecisions } from '../core/decision-log.js';
|
|
4
|
+
const STRATEGY_NAMES = {
|
|
5
|
+
'smart-follow': '聪明钱跟单',
|
|
6
|
+
'funding-arb': '融资套利',
|
|
7
|
+
'liq-hunter': '爆仓猎人',
|
|
8
|
+
'ob-sniper': '盘口狙击',
|
|
9
|
+
'pm-hedge': 'PM 对冲',
|
|
10
|
+
};
|
|
11
|
+
export async function strategyCommand(name, options) {
|
|
12
|
+
const cfg = loadConfig(options?.config);
|
|
13
|
+
console.log('');
|
|
14
|
+
console.log(chalk.bold.cyan(' BfxSentry · 策略状态'));
|
|
15
|
+
console.log('');
|
|
16
|
+
const strategies = [
|
|
17
|
+
{ key: 'smart_follow', id: 'smart-follow' },
|
|
18
|
+
{ key: 'funding_arb', id: 'funding-arb' },
|
|
19
|
+
{ key: 'liq_hunter', id: 'liq-hunter' },
|
|
20
|
+
{ key: 'ob_sniper', id: 'ob-sniper' },
|
|
21
|
+
{ key: 'pm_hedge', id: 'pm-hedge' },
|
|
22
|
+
];
|
|
23
|
+
for (const s of strategies) {
|
|
24
|
+
if (name && s.id !== name)
|
|
25
|
+
continue;
|
|
26
|
+
const sCfg = cfg[s.key];
|
|
27
|
+
const enabled = sCfg?.enabled;
|
|
28
|
+
const interval = sCfg?.tick_interval;
|
|
29
|
+
const icon = enabled ? chalk.green('ON') : chalk.red('OFF');
|
|
30
|
+
console.log(` ${icon} ${chalk.bold((STRATEGY_NAMES[s.id] || s.id).padEnd(12))} 间隔 ${interval}s`);
|
|
31
|
+
// Show recent decisions for this strategy
|
|
32
|
+
const decisions = getRecentDecisions(5).filter(d => d.strategy === s.id);
|
|
33
|
+
if (decisions.length > 0) {
|
|
34
|
+
for (const d of decisions.slice(0, 3)) {
|
|
35
|
+
const time = new Date(d.timestamp).toLocaleTimeString();
|
|
36
|
+
const action = d.intent ? `${d.intent.direction} ${d.intent.confidence.toFixed(0)}%` : '无操作';
|
|
37
|
+
const risk = d.riskFilterResult.passed ? chalk.green('通过') : chalk.red(d.riskFilterResult.reason || '拒绝');
|
|
38
|
+
console.log(chalk.dim(` ${time} ${action} 风控: ${risk}`));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
console.log('');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy.js","sourceRoot":"","sources":["../../../src/skill/strategy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trade.d.ts","sourceRoot":"","sources":["../../../src/skill/trade.ts"],"names":[],"mappings":"AAQA,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,iBAuDzD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { loadConfig } from '../core/config.js';
|
|
3
|
+
import { runOnce } from '../core/engine.js';
|
|
4
|
+
import { dryRunExecute } from '../executor/dry-run.js';
|
|
5
|
+
import { liveExecute } from '../executor/bitfinex-trader.js';
|
|
6
|
+
import { openPosition } from '../risk/position-manager.js';
|
|
7
|
+
export async function tradeCommand(direction, sizeStr, options) {
|
|
8
|
+
if (direction !== 'long' && direction !== 'short') {
|
|
9
|
+
console.log(chalk.red('\n 用法: sentry trade <long|short> <size_btc> [--stop 2%] [--tp 3%]\n'));
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const size = parseFloat(sizeStr);
|
|
13
|
+
if (isNaN(size) || size <= 0) {
|
|
14
|
+
console.log(chalk.red('\n 无效的仓位大小\n'));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const cfg = loadConfig(options.config);
|
|
18
|
+
const { snapshot } = await runOnce(cfg);
|
|
19
|
+
const price = snapshot.ticker.lastPrice;
|
|
20
|
+
const stopPct = parseFloat(options.stop?.replace('%', '') || '2');
|
|
21
|
+
const tpPct = parseFloat(options.tp?.replace('%', '') || '3');
|
|
22
|
+
const intent = {
|
|
23
|
+
id: `manual-${Date.now()}`,
|
|
24
|
+
strategy: 'manual',
|
|
25
|
+
direction: direction,
|
|
26
|
+
instrument: cfg.collector.bitfinex.symbol,
|
|
27
|
+
sizePct: (size * price / cfg.risk.max_total_position_usd) * 100,
|
|
28
|
+
leverage: 1,
|
|
29
|
+
entryPrice: price,
|
|
30
|
+
stopLossPct: stopPct,
|
|
31
|
+
takeProfitPct: tpPct,
|
|
32
|
+
confidence: 100,
|
|
33
|
+
reason: `手动 ${direction} ${size} BTC`,
|
|
34
|
+
signalIds: [],
|
|
35
|
+
timestamp: Date.now(),
|
|
36
|
+
};
|
|
37
|
+
console.log('');
|
|
38
|
+
console.log(chalk.bold(` 手动交易: ${direction.toUpperCase()} ${size} BTC @ $${price.toLocaleString()}`));
|
|
39
|
+
console.log(chalk.dim(` 止损: ${stopPct}% | 止盈: ${tpPct}%`));
|
|
40
|
+
let result;
|
|
41
|
+
if (cfg.engine.mode === 'live') {
|
|
42
|
+
result = await liveExecute(intent);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
result = dryRunExecute(intent, snapshot);
|
|
46
|
+
}
|
|
47
|
+
if (result.success) {
|
|
48
|
+
const pos = openPosition(intent, result);
|
|
49
|
+
console.log(chalk.green(` 成交: $${result.fillPrice?.toFixed(2)} x ${result.fillSize?.toFixed(6)} BTC [${cfg.engine.mode}]`));
|
|
50
|
+
if (pos)
|
|
51
|
+
console.log(chalk.dim(` 持仓 ID: ${pos.id}`));
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
console.log(chalk.red(` 失败: ${result.error}`));
|
|
55
|
+
}
|
|
56
|
+
console.log('');
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=trade.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trade.js","sourceRoot":"","sources":["../../../src/skill/trade.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Signal } from '../signal/types.js';
|
|
2
|
+
import type { TradeIntent } from './types.js';
|
|
3
|
+
import type { AgentConfig } from '../core/config.js';
|
|
4
|
+
import type { MarketSnapshot } from '../collector/types.js';
|
|
5
|
+
export declare function evaluateFundingArb(signals: Signal[], snapshot: MarketSnapshot, config: AgentConfig): TradeIntent | null;
|
|
6
|
+
//# sourceMappingURL=funding-arb.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"funding-arb.d.ts","sourceRoot":"","sources":["../../../src/strategy/funding-arb.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE3D,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,WAAW,GAClB,WAAW,GAAG,IAAI,CA0DpB"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export function evaluateFundingArb(signals, snapshot, config) {
|
|
2
|
+
const cfg = config.funding_arb;
|
|
3
|
+
if (!cfg.enabled)
|
|
4
|
+
return null;
|
|
5
|
+
const fundSignals = signals.filter(s => s.module === 'funding');
|
|
6
|
+
if (fundSignals.length === 0)
|
|
7
|
+
return null;
|
|
8
|
+
// S1: Lending opportunity
|
|
9
|
+
const lendSignal = fundSignals.find(s => s.id === 'FR-S1');
|
|
10
|
+
if (lendSignal) {
|
|
11
|
+
const lendCfg = cfg.lend;
|
|
12
|
+
const details = lendSignal.details;
|
|
13
|
+
const period = details.frrPct >= lendCfg.high_rate_threshold
|
|
14
|
+
? lendCfg.high_rate_period_days
|
|
15
|
+
: lendCfg.preferred_period_days;
|
|
16
|
+
return {
|
|
17
|
+
id: `fa-lend-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
18
|
+
strategy: 'funding-arb',
|
|
19
|
+
direction: 'long', // lending = providing capital
|
|
20
|
+
instrument: 'fUSD',
|
|
21
|
+
sizePct: lendCfg.lend_amount_pct,
|
|
22
|
+
leverage: 1,
|
|
23
|
+
entryPrice: details.frr,
|
|
24
|
+
stopLossPct: 0, // no stop loss on lending
|
|
25
|
+
takeProfitPct: 0,
|
|
26
|
+
confidence: lendSignal.confidence,
|
|
27
|
+
reason: `适合放贷: FRR P${(details.frrPct * 100).toFixed(0)}, 年化 ${details.annualizedRate.toFixed(1)}%, 建议 ${period} 天`,
|
|
28
|
+
signalIds: [lendSignal.id],
|
|
29
|
+
timestamp: Date.now(),
|
|
30
|
+
meta: { type: 'lend', period, frr: details.frr, utilization: details.utilization },
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// S2: Warning - don't borrow
|
|
34
|
+
const warnSignal = fundSignals.find(s => s.id === 'FR-S2');
|
|
35
|
+
if (warnSignal) {
|
|
36
|
+
// This is an advisory signal, not a trade intent
|
|
37
|
+
// But we can emit a "reduce leverage" intent
|
|
38
|
+
return {
|
|
39
|
+
id: `fa-warn-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
40
|
+
strategy: 'funding-arb',
|
|
41
|
+
direction: 'short', // reduce exposure
|
|
42
|
+
instrument: config.collector.bitfinex.symbol,
|
|
43
|
+
sizePct: 0,
|
|
44
|
+
leverage: 1,
|
|
45
|
+
entryPrice: snapshot.ticker.lastPrice,
|
|
46
|
+
stopLossPct: 0,
|
|
47
|
+
takeProfitPct: 0,
|
|
48
|
+
confidence: warnSignal.confidence,
|
|
49
|
+
reason: `高费率警告: 不适合借杠杆, 建议减仓`,
|
|
50
|
+
signalIds: [warnSignal.id],
|
|
51
|
+
timestamp: Date.now(),
|
|
52
|
+
meta: { type: 'warning', action: 'reduce_leverage' },
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=funding-arb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"funding-arb.js","sourceRoot":"","sources":["../../../src/strategy/funding-arb.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Signal } from '../signal/types.js';
|
|
2
|
+
import type { TradeIntent } from './types.js';
|
|
3
|
+
import type { AgentConfig } from '../core/config.js';
|
|
4
|
+
import type { MarketSnapshot } from '../collector/types.js';
|
|
5
|
+
export type { TradeIntent, Position, ExecutionResult, DecisionRecord } from './types.js';
|
|
6
|
+
export declare function evaluateAllStrategies(signals: Signal[], snapshot: MarketSnapshot, config: AgentConfig): TradeIntent[];
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/strategy/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAO3D,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAExF,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,WAAW,GAClB,WAAW,EAAE,CAqBf"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { evaluateSmartFollow } from './smart-follow.js';
|
|
2
|
+
import { evaluateFundingArb } from './funding-arb.js';
|
|
3
|
+
import { evaluateLiqHunter } from './liq-hunter.js';
|
|
4
|
+
import { evaluateObSniper } from './ob-sniper.js';
|
|
5
|
+
import { evaluatePmHedge } from './pm-hedge.js';
|
|
6
|
+
export function evaluateAllStrategies(signals, snapshot, config) {
|
|
7
|
+
const intents = [];
|
|
8
|
+
const evaluators = [
|
|
9
|
+
evaluateSmartFollow,
|
|
10
|
+
evaluateFundingArb,
|
|
11
|
+
evaluateLiqHunter,
|
|
12
|
+
evaluateObSniper,
|
|
13
|
+
evaluatePmHedge,
|
|
14
|
+
];
|
|
15
|
+
for (const evaluate of evaluators) {
|
|
16
|
+
try {
|
|
17
|
+
const intent = evaluate(signals, snapshot, config);
|
|
18
|
+
if (intent)
|
|
19
|
+
intents.push(intent);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// Strategy evaluation failure should not crash the engine
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return intents;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/strategy/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAI/C,MAAM,UAAU,qBAAqB,CACnC,OAAiB,EACjB,QAAwB,EACxB,MAAmB;IAEnB,MAAM,OAAO,GAAkB,EAAE,CAAA;IAEjC,MAAM,UAAU,GAAG;QACjB,mBAAmB;QACnB,kBAAkB;QAClB,iBAAiB;QACjB,gBAAgB;QAChB,eAAe;KAChB,CAAA;IAED,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;YAClD,IAAI,MAAM;gBAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,0DAA0D;QAC5D,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Signal } from '../signal/types.js';
|
|
2
|
+
import type { TradeIntent } from './types.js';
|
|
3
|
+
import type { AgentConfig } from '../core/config.js';
|
|
4
|
+
import type { MarketSnapshot } from '../collector/types.js';
|
|
5
|
+
export declare function evaluateLiqHunter(signals: Signal[], snapshot: MarketSnapshot, config: AgentConfig): TradeIntent | null;
|
|
6
|
+
//# sourceMappingURL=liq-hunter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"liq-hunter.d.ts","sourceRoot":"","sources":["../../../src/strategy/liq-hunter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE3D,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,WAAW,GAClB,WAAW,GAAG,IAAI,CA6DpB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export function evaluateLiqHunter(signals, snapshot, config) {
|
|
2
|
+
const cfg = config.liq_hunter;
|
|
3
|
+
if (!cfg.enabled)
|
|
4
|
+
return null;
|
|
5
|
+
const risk = cfg.risk;
|
|
6
|
+
const liqSignals = signals.filter(s => s.module === 'liquidation');
|
|
7
|
+
if (liqSignals.length === 0)
|
|
8
|
+
return null;
|
|
9
|
+
// LQ1/LQ2: Trend follow
|
|
10
|
+
const trendSignal = liqSignals.find(s => s.id === 'LQ-1' || s.id === 'LQ-2');
|
|
11
|
+
if (trendSignal) {
|
|
12
|
+
return {
|
|
13
|
+
id: `lh-trend-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
14
|
+
strategy: 'liq-hunter',
|
|
15
|
+
direction: trendSignal.direction,
|
|
16
|
+
instrument: config.collector.bitfinex.symbol,
|
|
17
|
+
sizePct: risk.size_pct,
|
|
18
|
+
leverage: risk.max_leverage,
|
|
19
|
+
entryPrice: snapshot.ticker.lastPrice,
|
|
20
|
+
stopLossPct: risk.trend_stop_pct,
|
|
21
|
+
takeProfitPct: risk.take_profit_pct,
|
|
22
|
+
confidence: trendSignal.confidence,
|
|
23
|
+
reason: trendSignal.summary,
|
|
24
|
+
signalIds: [trendSignal.id],
|
|
25
|
+
timestamp: Date.now(),
|
|
26
|
+
meta: {
|
|
27
|
+
type: 'trend_follow',
|
|
28
|
+
intensity: trendSignal.details.intensity,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// LQ3: Reversal (requires orderbook confirmation)
|
|
33
|
+
const reversalCfg = cfg.reversal;
|
|
34
|
+
const reversalSignal = liqSignals.find(s => s.id === 'LQ-3');
|
|
35
|
+
if (reversalSignal && reversalCfg) {
|
|
36
|
+
if (reversalCfg.require_ob_confirm) {
|
|
37
|
+
const obSignals = signals.filter(s => s.module === 'orderbook' && s.direction !== 'neutral');
|
|
38
|
+
const confirmed = obSignals.some(s => s.direction === reversalSignal.direction);
|
|
39
|
+
if (!confirmed)
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
id: `lh-rev-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
44
|
+
strategy: 'liq-hunter',
|
|
45
|
+
direction: reversalSignal.direction,
|
|
46
|
+
instrument: config.collector.bitfinex.symbol,
|
|
47
|
+
sizePct: risk.size_pct * 0.5, // half size for reversal
|
|
48
|
+
leverage: risk.max_leverage,
|
|
49
|
+
entryPrice: snapshot.ticker.lastPrice,
|
|
50
|
+
stopLossPct: risk.reversal_stop_pct,
|
|
51
|
+
takeProfitPct: risk.take_profit_pct,
|
|
52
|
+
confidence: reversalSignal.confidence,
|
|
53
|
+
reason: reversalSignal.summary,
|
|
54
|
+
signalIds: [reversalSignal.id],
|
|
55
|
+
timestamp: Date.now(),
|
|
56
|
+
meta: { type: 'reversal' },
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=liq-hunter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"liq-hunter.js","sourceRoot":"","sources":["../../../src/strategy/liq-hunter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Signal } from '../signal/types.js';
|
|
2
|
+
import type { TradeIntent } from './types.js';
|
|
3
|
+
import type { AgentConfig } from '../core/config.js';
|
|
4
|
+
import type { MarketSnapshot } from '../collector/types.js';
|
|
5
|
+
export declare function evaluateObSniper(signals: Signal[], snapshot: MarketSnapshot, config: AgentConfig): TradeIntent | null;
|
|
6
|
+
//# sourceMappingURL=ob-sniper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ob-sniper.d.ts","sourceRoot":"","sources":["../../../src/strategy/ob-sniper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE3D,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,WAAW,GAClB,WAAW,GAAG,IAAI,CA6CpB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export function evaluateObSniper(signals, snapshot, config) {
|
|
2
|
+
const cfg = config.ob_sniper;
|
|
3
|
+
if (!cfg.enabled)
|
|
4
|
+
return null;
|
|
5
|
+
const entry = cfg.entry_conditions;
|
|
6
|
+
const risk = cfg.risk;
|
|
7
|
+
const obSignals = signals.filter(s => s.module === 'orderbook' && s.direction !== 'neutral');
|
|
8
|
+
if (obSignals.length === 0)
|
|
9
|
+
return null;
|
|
10
|
+
// Pick strongest signal
|
|
11
|
+
const best = obSignals.sort((a, b) => b.confidence - a.confidence)[0];
|
|
12
|
+
// Flow confirmation
|
|
13
|
+
if (entry.require_flow_confirm) {
|
|
14
|
+
const flow = snapshot.tradeFlow;
|
|
15
|
+
if (best.direction === 'long' && flow.buyRatio60s < entry.flow_buy_ratio)
|
|
16
|
+
return null;
|
|
17
|
+
if (best.direction === 'short' && flow.buyRatio60s > entry.flow_sell_ratio)
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
// Check signal TTL
|
|
21
|
+
if (best.ttlSec) {
|
|
22
|
+
const age = (Date.now() - best.timestamp) / 1000;
|
|
23
|
+
if (age > best.ttlSec)
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
id: `ob-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
28
|
+
strategy: 'ob-sniper',
|
|
29
|
+
direction: best.direction,
|
|
30
|
+
instrument: config.collector.bitfinex.symbol,
|
|
31
|
+
sizePct: risk.size_pct,
|
|
32
|
+
leverage: risk.max_leverage,
|
|
33
|
+
entryPrice: snapshot.ticker.lastPrice,
|
|
34
|
+
stopLossPct: risk.stop_loss_pct,
|
|
35
|
+
takeProfitPct: risk.take_profit_pct,
|
|
36
|
+
confidence: best.confidence,
|
|
37
|
+
reason: best.summary,
|
|
38
|
+
signalIds: [best.id],
|
|
39
|
+
timestamp: Date.now(),
|
|
40
|
+
ttlSec: risk.signal_ttl_sec,
|
|
41
|
+
meta: {
|
|
42
|
+
signalType: best.id.startsWith('OB-3') ? 'wall_break' : 'imbalance',
|
|
43
|
+
imbalance: best.details.imbalance,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=ob-sniper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ob-sniper.js","sourceRoot":"","sources":["../../../src/strategy/ob-sniper.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,gBAAgB,CAC9B,OAAiB,EACjB,QAAwB,EACxB,MAAmB;IAEnB,MAAM,GAAG,GAAG,MAAM,CAAC,SAAoC,CAAA;IACvD,IAAI,CAAC,GAAG,CAAC,OAAO;QAAE,OAAO,IAAI,CAAA;IAE7B,MAAM,KAAK,GAAG,GAAG,CAAC,gBAA2C,CAAA;IAC7D,MAAM,IAAI,GAAG,GAAG,CAAC,IAA8B,CAAA;IAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAA;IAC5F,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAEvC,wBAAwB;IACxB,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;IAErE,oBAAoB;IACpB,IAAI,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAA;QAC/B,IAAI,IAAI,CAAC,SAAS,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,GAAI,KAAK,CAAC,cAAyB;YAAE,OAAO,IAAI,CAAA;QACjG,IAAI,IAAI,CAAC,SAAS,KAAK,OAAO,IAAI,IAAI,CAAC,WAAW,GAAI,KAAK,CAAC,eAA0B;YAAE,OAAO,IAAI,CAAA;IACrG,CAAC;IAED,mBAAmB;IACnB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAA;QAChD,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAA;IACpC,CAAC;IAED,OAAO;QACL,EAAE,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;QAChE,QAAQ,EAAE,WAAW;QACrB,SAAS,EAAE,IAAI,CAAC,SAA6B;QAC7C,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM;QAC5C,OAAO,EAAE,IAAI,CAAC,QAAQ;QACtB,QAAQ,EAAE,IAAI,CAAC,YAAY;QAC3B,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS;QACrC,WAAW,EAAE,IAAI,CAAC,aAAa;QAC/B,aAAa,EAAE,IAAI,CAAC,eAAe;QACnC,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,MAAM,EAAE,IAAI,CAAC,OAAO;QACpB,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,MAAM,EAAE,IAAI,CAAC,cAAc;QAC3B,IAAI,EAAE;YACJ,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW;YACnE,SAAS,EAAG,IAAI,CAAC,OAAkC,CAAC,SAAS;SAC9D;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Signal } from '../signal/types.js';
|
|
2
|
+
import type { TradeIntent } from './types.js';
|
|
3
|
+
import type { AgentConfig } from '../core/config.js';
|
|
4
|
+
import type { MarketSnapshot } from '../collector/types.js';
|
|
5
|
+
export declare function evaluatePmHedge(signals: Signal[], snapshot: MarketSnapshot, config: AgentConfig): TradeIntent | null;
|
|
6
|
+
//# sourceMappingURL=pm-hedge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pm-hedge.d.ts","sourceRoot":"","sources":["../../../src/strategy/pm-hedge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE3D,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,WAAW,GAClB,WAAW,GAAG,IAAI,CAuDpB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export function evaluatePmHedge(signals, snapshot, config) {
|
|
2
|
+
const cfg = config.pm_hedge;
|
|
3
|
+
if (!cfg.enabled)
|
|
4
|
+
return null;
|
|
5
|
+
const signalDriven = cfg.signal_driven;
|
|
6
|
+
const hedge = cfg.hedge;
|
|
7
|
+
// Aggregate all directional signals
|
|
8
|
+
let bullWeight = 0;
|
|
9
|
+
let bearWeight = 0;
|
|
10
|
+
for (const s of signals) {
|
|
11
|
+
if (s.direction === 'long')
|
|
12
|
+
bullWeight += s.confidence;
|
|
13
|
+
else if (s.direction === 'short')
|
|
14
|
+
bearWeight += s.confidence;
|
|
15
|
+
}
|
|
16
|
+
const total = bullWeight + bearWeight;
|
|
17
|
+
if (total === 0)
|
|
18
|
+
return null;
|
|
19
|
+
const rawProb = bullWeight / total;
|
|
20
|
+
// Compress towards 50%
|
|
21
|
+
const upProb = 0.5 + (rawProb - 0.5) * 0.6;
|
|
22
|
+
const confidence = Math.abs(upProb - 0.5) * 200;
|
|
23
|
+
if (confidence < signalDriven.min_confidence)
|
|
24
|
+
return null;
|
|
25
|
+
const direction = upProb > 0.55 ? 'long' : upProb < 0.45 ? 'short' : null;
|
|
26
|
+
if (!direction)
|
|
27
|
+
return null;
|
|
28
|
+
// Calculate hedge position
|
|
29
|
+
const btcPrice = snapshot.ticker.lastPrice;
|
|
30
|
+
const hedgeBtc = (signalDriven.stake_usdc * hedge.delta) / btcPrice;
|
|
31
|
+
const maxBtc = hedge.max_bfx_position_btc;
|
|
32
|
+
return {
|
|
33
|
+
id: `pm-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
34
|
+
strategy: 'pm-hedge',
|
|
35
|
+
direction,
|
|
36
|
+
instrument: hedge.bfx_instrument,
|
|
37
|
+
sizePct: 0, // PM hedge uses fixed USDC stake
|
|
38
|
+
leverage: 1,
|
|
39
|
+
entryPrice: btcPrice,
|
|
40
|
+
stopLossPct: 5, // wider stop for hedge
|
|
41
|
+
takeProfitPct: 10,
|
|
42
|
+
confidence,
|
|
43
|
+
reason: `PM 信号聚合 ${direction === 'long' ? '偏多' : '偏空'} ${(upProb * 100).toFixed(0)}%, 对冲 ${Math.min(hedgeBtc, maxBtc).toFixed(5)} BTC`,
|
|
44
|
+
signalIds: signals.filter(s => s.direction !== 'neutral').map(s => s.id),
|
|
45
|
+
timestamp: Date.now(),
|
|
46
|
+
meta: {
|
|
47
|
+
upProb,
|
|
48
|
+
confidence,
|
|
49
|
+
stakeUsdc: signalDriven.stake_usdc,
|
|
50
|
+
hedgeBtc: Math.min(hedgeBtc, maxBtc),
|
|
51
|
+
delta: hedge.delta,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=pm-hedge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pm-hedge.js","sourceRoot":"","sources":["../../../src/strategy/pm-hedge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Signal } from '../signal/types.js';
|
|
2
|
+
import type { TradeIntent } from './types.js';
|
|
3
|
+
import type { AgentConfig } from '../core/config.js';
|
|
4
|
+
import type { MarketSnapshot } from '../collector/types.js';
|
|
5
|
+
export declare function evaluateSmartFollow(signals: Signal[], snapshot: MarketSnapshot, config: AgentConfig): TradeIntent | null;
|
|
6
|
+
//# sourceMappingURL=smart-follow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-follow.d.ts","sourceRoot":"","sources":["../../../src/strategy/smart-follow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE3D,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,WAAW,GAClB,WAAW,GAAG,IAAI,CA6CpB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export function evaluateSmartFollow(signals, snapshot, config) {
|
|
2
|
+
const cfg = config.smart_follow;
|
|
3
|
+
if (!cfg.enabled)
|
|
4
|
+
return null;
|
|
5
|
+
const entry = cfg.entry_conditions;
|
|
6
|
+
const risk = cfg.risk;
|
|
7
|
+
const smSignals = signals.filter(s => s.module === 'smart-money');
|
|
8
|
+
if (smSignals.length === 0)
|
|
9
|
+
return null;
|
|
10
|
+
const main = smSignals[0];
|
|
11
|
+
if (main.direction === 'neutral')
|
|
12
|
+
return null;
|
|
13
|
+
// Check entry conditions
|
|
14
|
+
const score = snapshot.whaleScore;
|
|
15
|
+
if (score < entry.min_score)
|
|
16
|
+
return null;
|
|
17
|
+
const whales = snapshot.whales;
|
|
18
|
+
const aligned = whales.filter(w => w.direction === main.direction).length;
|
|
19
|
+
if (aligned < entry.min_whales_aligned)
|
|
20
|
+
return null;
|
|
21
|
+
// Position confirmation
|
|
22
|
+
if (entry.position_confirm) {
|
|
23
|
+
const posSignals = signals.filter(s => s.module === 'smart-money' && s.direction === main.direction);
|
|
24
|
+
if (posSignals.length === 0)
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
id: `sf-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
29
|
+
strategy: 'smart-follow',
|
|
30
|
+
direction: main.direction,
|
|
31
|
+
instrument: config.collector.bitfinex.symbol,
|
|
32
|
+
sizePct: risk.size_pct,
|
|
33
|
+
leverage: risk.max_leverage,
|
|
34
|
+
entryPrice: snapshot.ticker.lastPrice,
|
|
35
|
+
stopLossPct: risk.stop_loss_pct,
|
|
36
|
+
takeProfitPct: cfg.exit_conditions.trailing_stop_pct || 1.5,
|
|
37
|
+
confidence: main.confidence,
|
|
38
|
+
reason: `聪明钱 ${main.direction === 'long' ? '看多' : '看空'}, 评分 ${score.toFixed(0)}, ${aligned} 鲸鱼同向`,
|
|
39
|
+
signalIds: smSignals.map(s => s.id),
|
|
40
|
+
timestamp: Date.now(),
|
|
41
|
+
meta: { score, aligned, whaleDirection: snapshot.whaleDirection },
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=smart-follow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-follow.js","sourceRoot":"","sources":["../../../src/strategy/smart-follow.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,mBAAmB,CACjC,OAAiB,EACjB,QAAwB,EACxB,MAAmB;IAEnB,MAAM,GAAG,GAAG,MAAM,CAAC,YAAuC,CAAA;IAC1D,IAAI,CAAC,GAAG,CAAC,OAAO;QAAE,OAAO,IAAI,CAAA;IAE7B,MAAM,KAAK,GAAG,GAAG,CAAC,gBAAoD,CAAA;IACtE,MAAM,IAAI,GAAG,GAAG,CAAC,IAA8B,CAAA;IAE/C,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAA;IACjE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAEvC,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;IACzB,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IAE7C,yBAAyB;IACzB,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAA;IACjC,IAAI,KAAK,GAAI,KAAK,CAAC,SAAoB;QAAE,OAAO,IAAI,CAAA;IAEpD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAA;IAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAA;IACzE,IAAI,OAAO,GAAI,KAAK,CAAC,kBAA6B;QAAE,OAAO,IAAI,CAAA;IAE/D,wBAAwB;IACxB,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACpC,CAAC,CAAC,MAAM,KAAK,aAAa,IAAI,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,CAC7D,CAAA;QACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;IAC1C,CAAC;IAED,OAAO;QACL,EAAE,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;QAChE,QAAQ,EAAE,cAAc;QACxB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM;QAC5C,OAAO,EAAE,IAAI,CAAC,QAAQ;QACtB,QAAQ,EAAE,IAAI,CAAC,YAAY;QAC3B,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS;QACrC,WAAW,EAAE,IAAI,CAAC,aAAa;QAC/B,aAAa,EAAG,GAAG,CAAC,eAA0C,CAAC,iBAAiB,IAAI,GAAG;QACvF,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,MAAM,EAAE,OAAO,IAAI,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,OAAO;QACjG,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,CAAC,cAAc,EAAE;KAClE,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export interface TradeIntent {
|
|
2
|
+
id: string;
|
|
3
|
+
strategy: string;
|
|
4
|
+
direction: 'long' | 'short';
|
|
5
|
+
instrument: string;
|
|
6
|
+
sizePct: number;
|
|
7
|
+
leverage: number;
|
|
8
|
+
entryPrice: number;
|
|
9
|
+
stopLossPct: number;
|
|
10
|
+
takeProfitPct: number;
|
|
11
|
+
confidence: number;
|
|
12
|
+
reason: string;
|
|
13
|
+
signalIds: string[];
|
|
14
|
+
timestamp: number;
|
|
15
|
+
ttlSec?: number;
|
|
16
|
+
meta?: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
export interface Position {
|
|
19
|
+
id: string;
|
|
20
|
+
strategy: string;
|
|
21
|
+
direction: 'long' | 'short';
|
|
22
|
+
instrument: string;
|
|
23
|
+
entryPrice: number;
|
|
24
|
+
currentPrice: number;
|
|
25
|
+
size: number;
|
|
26
|
+
sizeUsd: number;
|
|
27
|
+
leverage: number;
|
|
28
|
+
unrealizedPnl: number;
|
|
29
|
+
unrealizedPnlPct: number;
|
|
30
|
+
stopLoss: number;
|
|
31
|
+
takeProfit: number;
|
|
32
|
+
openedAt: number;
|
|
33
|
+
highWatermark: number;
|
|
34
|
+
trailingStopPct?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface ExecutionResult {
|
|
37
|
+
success: boolean;
|
|
38
|
+
orderId?: string;
|
|
39
|
+
fillPrice?: number;
|
|
40
|
+
fillSize?: number;
|
|
41
|
+
fee?: number;
|
|
42
|
+
error?: string;
|
|
43
|
+
timestamp: number;
|
|
44
|
+
}
|
|
45
|
+
export interface DecisionRecord {
|
|
46
|
+
timestamp: number;
|
|
47
|
+
strategy: string;
|
|
48
|
+
signalsSnapshot: Record<string, unknown>[];
|
|
49
|
+
configSnapshot: Record<string, unknown>;
|
|
50
|
+
intent: TradeIntent | null;
|
|
51
|
+
riskFilterResult: {
|
|
52
|
+
passed: boolean;
|
|
53
|
+
reason?: string;
|
|
54
|
+
};
|
|
55
|
+
executionResult: ExecutionResult | null;
|
|
56
|
+
pnlAtExit?: number;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/strategy/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,MAAM,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IAC1C,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACvC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;IAC1B,gBAAgB,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACtD,eAAe,EAAE,eAAe,GAAG,IAAI,CAAA;IACvC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/strategy/types.ts"],"names":[],"mappings":""}
|