perp-cli 0.12.17 → 0.14.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/README.md +247 -27
- package/dist/_stderr-filter.js +0 -1
- package/dist/agent-wallet/lighter-keystore.d.ts +11 -0
- package/dist/agent-wallet/lighter-keystore.js +92 -10
- package/dist/agent-wallet/passphrase.d.ts +1 -1
- package/dist/agent-wallet/passphrase.js +16 -3
- package/dist/agent-wallet/store.d.ts +37 -4
- package/dist/agent-wallet/store.js +132 -0
- package/dist/agent-wallet/venue-keystore.d.ts +14 -0
- package/dist/agent-wallet/venue-keystore.js +121 -0
- package/dist/api/public/hyperliquid.js +4 -4
- package/dist/api/public/lighter.js +5 -5
- package/dist/api/public/pacifica.d.ts +0 -1
- package/dist/api/public/pacifica.js +4 -13
- package/dist/api/public/urls.d.ts +9 -1
- package/dist/api/public/urls.js +35 -13
- package/dist/arb/file-lock.d.ts +11 -0
- package/dist/arb/file-lock.js +74 -0
- package/dist/arb/index.d.ts +2 -2
- package/dist/arb/index.js +2 -2
- package/dist/arb/pending-entry.d.ts +32 -0
- package/dist/arb/pending-entry.js +77 -0
- package/dist/arb/sizing.d.ts +6 -13
- package/dist/arb/sizing.js +12 -51
- package/dist/arb/state.d.ts +45 -12
- package/dist/arb/state.js +214 -42
- package/dist/arb/utils.d.ts +20 -6
- package/dist/arb/utils.js +43 -39
- package/dist/bot/conditions.d.ts +4 -4
- package/dist/bot/conditions.js +11 -6
- package/dist/bot/config.d.ts +17 -1
- package/dist/bot/config.js +48 -12
- package/dist/bot/engine.d.ts +61 -2
- package/dist/bot/engine.js +610 -144
- package/dist/bot/fill-size.d.ts +7 -0
- package/dist/bot/fill-size.js +18 -0
- package/dist/bot/index.d.ts +1 -1
- package/dist/bot/index.js +1 -1
- package/dist/bot/perp-order.d.ts +99 -0
- package/dist/bot/perp-order.js +299 -0
- package/dist/bot/presets.d.ts +7 -0
- package/dist/bot/presets.js +17 -0
- package/dist/bot/quarantine.d.ts +75 -0
- package/dist/bot/quarantine.js +190 -0
- package/dist/bot/quote-rules.d.ts +23 -0
- package/dist/bot/quote-rules.js +69 -0
- package/dist/bot/strategies/avellaneda-mm.d.ts +32 -2
- package/dist/bot/strategies/avellaneda-mm.js +72 -70
- package/dist/bot/strategies/basis-arb.js +2 -0
- package/dist/bot/strategies/dca-strategy.d.ts +2 -0
- package/dist/bot/strategies/dca-strategy.js +5 -0
- package/dist/bot/strategies/funding-arb-strategy.d.ts +43 -3
- package/dist/bot/strategies/funding-arb-strategy.js +571 -380
- package/dist/bot/strategies/funding-arb-utils.d.ts +48 -23
- package/dist/bot/strategies/funding-arb-utils.js +159 -195
- package/dist/bot/strategies/funding-arb-v2.d.ts +32 -0
- package/dist/bot/strategies/funding-arb-v2.js +258 -47
- package/dist/bot/strategies/funding-auto.js +215 -194
- package/dist/bot/strategies/spot-perp-arb-strategy.d.ts +14 -0
- package/dist/bot/strategies/spot-perp-arb-strategy.js +217 -50
- package/dist/bot/strategies/spot-perp-executor.d.ts +73 -19
- package/dist/bot/strategies/spot-perp-executor.js +319 -120
- package/dist/bot/strategies/spot-perp-state.d.ts +43 -0
- package/dist/bot/strategies/spot-perp-state.js +70 -0
- package/dist/bot/strategy-types.d.ts +6 -0
- package/dist/bot/tui/BotDashboard.d.ts +7 -2
- package/dist/bot/tui/BotDashboard.js +6 -3
- package/dist/bridge-engine.d.ts +120 -19
- package/dist/bridge-engine.js +710 -422
- package/dist/bridge-signers.d.ts +54 -0
- package/dist/bridge-signers.js +161 -0
- package/dist/cache.d.ts +4 -1
- package/dist/cache.js +11 -0
- package/dist/cli-flags.d.ts +50 -0
- package/dist/cli-flags.js +104 -0
- package/dist/cli-program.d.ts +35 -0
- package/dist/cli-program.js +286 -0
- package/dist/cli-spec.js +1 -1
- package/dist/client-id-tracker.js +11 -2
- package/dist/commands/account.d.ts +7 -1
- package/dist/commands/account.js +70 -92
- package/dist/commands/agent-import.d.ts +114 -0
- package/dist/commands/agent-import.js +794 -0
- package/dist/commands/agent.d.ts +232 -2
- package/dist/commands/agent.js +1858 -955
- package/dist/commands/alerts.d.ts +1 -0
- package/dist/commands/alerts.js +31 -28
- package/dist/commands/arb/index.d.ts +60 -1
- package/dist/commands/arb/index.js +381 -384
- package/dist/commands/arb-auto.d.ts +132 -4
- package/dist/commands/arb-auto.js +1474 -967
- package/dist/commands/arb.d.ts +3 -1
- package/dist/commands/arb.js +62 -30
- package/dist/commands/bot.js +127 -47
- package/dist/commands/bridge.d.ts +2 -1
- package/dist/commands/bridge.js +339 -192
- package/dist/commands/builder.d.ts +55 -0
- package/dist/commands/builder.js +387 -0
- package/dist/commands/funds-onchain.d.ts +32 -0
- package/dist/commands/funds-onchain.js +286 -0
- package/dist/commands/funds.d.ts +25 -0
- package/dist/commands/funds.js +939 -245
- package/dist/commands/history.js +72 -45
- package/dist/commands/init.d.ts +107 -15
- package/dist/commands/init.js +1116 -249
- package/dist/commands/jobs.d.ts +2 -1
- package/dist/commands/jobs.js +77 -15
- package/dist/commands/manage.js +136 -91
- package/dist/commands/market.d.ts +4 -1
- package/dist/commands/market.js +35 -32
- package/dist/commands/outcome.d.ts +10 -0
- package/dist/commands/outcome.js +396 -0
- package/dist/commands/plan.js +52 -12
- package/dist/commands/portfolio.d.ts +1 -0
- package/dist/commands/portfolio.js +60 -72
- package/dist/commands/rebalance.d.ts +2 -1
- package/dist/commands/rebalance.js +33 -43
- package/dist/commands/risk.js +46 -19
- package/dist/commands/settings.d.ts +1 -0
- package/dist/commands/settings.js +246 -51
- package/dist/commands/trade.d.ts +50 -0
- package/dist/commands/trade.js +1943 -695
- package/dist/commands/wallet.d.ts +30 -1
- package/dist/commands/wallet.js +316 -337
- package/dist/config.d.ts +60 -9
- package/dist/config.js +252 -82
- package/dist/constants.d.ts +29 -4
- package/dist/constants.js +62 -20
- package/dist/dashboard/server.d.ts +2 -0
- package/dist/dashboard/server.js +9 -6
- package/dist/dashboard/ui.js +6 -4
- package/dist/dashboard/ws-feeds.js +20 -8
- package/dist/dex-asset-map.js +5 -3
- package/dist/errors.d.ts +122 -0
- package/dist/errors.js +194 -0
- package/dist/event-stream.js +75 -19
- package/dist/evm-master-tx.d.ts +59 -0
- package/dist/evm-master-tx.js +154 -0
- package/dist/exchanges/adapter-network.d.ts +10 -0
- package/dist/exchanges/adapter-network.js +10 -0
- package/dist/exchanges/arcus/adapter.d.ts +196 -0
- package/dist/exchanges/arcus/adapter.js +1092 -0
- package/dist/exchanges/arcus/agent.d.ts +55 -0
- package/dist/exchanges/arcus/agent.js +188 -0
- package/dist/exchanges/arcus/client.d.ts +63 -0
- package/dist/exchanges/arcus/client.js +285 -0
- package/dist/exchanges/arcus/public.d.ts +65 -0
- package/dist/exchanges/arcus/public.js +138 -0
- package/dist/exchanges/arcus/signing.d.ts +176 -0
- package/dist/exchanges/arcus/signing.js +288 -0
- package/dist/exchanges/arcus/spot-chain.d.ts +60 -0
- package/dist/exchanges/arcus/spot-chain.js +241 -0
- package/dist/exchanges/arcus/spot-router.d.ts +177 -0
- package/dist/exchanges/arcus/spot-router.js +183 -0
- package/dist/exchanges/arcus/spot.d.ts +109 -0
- package/dist/exchanges/arcus/spot.js +645 -0
- package/dist/exchanges/aster-funds.d.ts +127 -0
- package/dist/exchanges/aster-funds.js +252 -0
- package/dist/exchanges/aster-nonce.d.ts +2 -0
- package/dist/exchanges/aster-nonce.js +107 -0
- package/dist/exchanges/aster-spot.d.ts +117 -0
- package/dist/exchanges/aster-spot.js +686 -0
- package/dist/exchanges/aster-typed-data.d.ts +133 -7
- package/dist/exchanges/aster-typed-data.js +121 -7
- package/dist/exchanges/aster.d.ts +219 -6
- package/dist/exchanges/aster.js +1023 -153
- package/dist/exchanges/builder-fee.d.ts +254 -0
- package/dist/exchanges/builder-fee.js +421 -0
- package/dist/exchanges/canonical-symbols.d.ts +32 -0
- package/dist/exchanges/canonical-symbols.js +96 -0
- package/dist/exchanges/capabilities.d.ts +7 -1
- package/dist/exchanges/capabilities.js +7 -0
- package/dist/exchanges/hl-signing.d.ts +165 -0
- package/dist/exchanges/hl-signing.js +158 -0
- package/dist/exchanges/hyperliquid-outcome.d.ts +211 -0
- package/dist/exchanges/hyperliquid-outcome.js +646 -0
- package/dist/exchanges/hyperliquid-spot.d.ts +44 -5
- package/dist/exchanges/hyperliquid-spot.js +308 -117
- package/dist/exchanges/hyperliquid.d.ts +462 -57
- package/dist/exchanges/hyperliquid.js +1575 -449
- package/dist/exchanges/index.d.ts +6 -0
- package/dist/exchanges/index.js +4 -0
- package/dist/exchanges/interface.d.ts +63 -10
- package/dist/exchanges/interface.js +18 -3
- package/dist/exchanges/ioc-outcome.d.ts +44 -0
- package/dist/exchanges/ioc-outcome.js +57 -0
- package/dist/exchanges/legacy-trading-v2.d.ts +39 -0
- package/dist/exchanges/legacy-trading-v2.js +940 -0
- package/dist/exchanges/lighter-public.d.ts +43 -0
- package/dist/exchanges/lighter-public.js +276 -0
- package/dist/exchanges/lighter-rh-deposit.d.ts +62 -0
- package/dist/exchanges/lighter-rh-deposit.js +185 -0
- package/dist/exchanges/lighter-signer.d.ts +123 -0
- package/dist/exchanges/lighter-signer.js +215 -0
- package/dist/exchanges/lighter-spot.d.ts +91 -13
- package/dist/exchanges/lighter-spot.js +595 -233
- package/dist/exchanges/lighter.d.ts +611 -39
- package/dist/exchanges/lighter.js +1890 -649
- package/dist/exchanges/ondo/adapter.d.ts +166 -0
- package/dist/exchanges/ondo/adapter.js +835 -0
- package/dist/exchanges/ondo/agent.d.ts +31 -0
- package/dist/exchanges/ondo/agent.js +101 -0
- package/dist/exchanges/ondo/client.d.ts +60 -0
- package/dist/exchanges/ondo/client.js +297 -0
- package/dist/exchanges/ondo/funds.d.ts +122 -0
- package/dist/exchanges/ondo/funds.js +290 -0
- package/dist/exchanges/ondo/public.d.ts +95 -0
- package/dist/exchanges/ondo/public.js +214 -0
- package/dist/exchanges/ondo/spot.d.ts +127 -0
- package/dist/exchanges/ondo/spot.js +392 -0
- package/dist/exchanges/outcome-interface.d.ts +140 -0
- package/dist/exchanges/outcome-interface.js +16 -0
- package/dist/exchanges/pacifica-spot.d.ts +83 -0
- package/dist/exchanges/pacifica-spot.js +324 -0
- package/dist/exchanges/pacifica-typed-data.d.ts +30 -13
- package/dist/exchanges/pacifica-typed-data.js +57 -9
- package/dist/exchanges/pacifica.d.ts +288 -4
- package/dist/exchanges/pacifica.js +1013 -76
- package/dist/exchanges/precision.d.ts +47 -0
- package/dist/exchanges/precision.js +209 -0
- package/dist/exchanges/qfex/adapter.d.ts +341 -0
- package/dist/exchanges/qfex/adapter.js +1383 -0
- package/dist/exchanges/qfex/agent.d.ts +58 -0
- package/dist/exchanges/qfex/agent.js +188 -0
- package/dist/exchanges/qfex/client.d.ts +54 -0
- package/dist/exchanges/qfex/client.js +138 -0
- package/dist/exchanges/qfex/errors.d.ts +70 -0
- package/dist/exchanges/qfex/errors.js +236 -0
- package/dist/exchanges/qfex/public.d.ts +122 -0
- package/dist/exchanges/qfex/public.js +268 -0
- package/dist/exchanges/qfex/signing.d.ts +160 -0
- package/dist/exchanges/qfex/signing.js +283 -0
- package/dist/exchanges/qfex/ws-transport.d.ts +294 -0
- package/dist/exchanges/qfex/ws-transport.js +798 -0
- package/dist/exchanges/rate-limiter.d.ts +12 -0
- package/dist/exchanges/rate-limiter.js +64 -0
- package/dist/exchanges/registry.d.ts +14 -2
- package/dist/exchanges/registry.js +20 -32
- package/dist/exchanges/slippage.d.ts +37 -0
- package/dist/exchanges/slippage.js +70 -0
- package/dist/exchanges/spot-factory.d.ts +166 -0
- package/dist/exchanges/spot-factory.js +431 -0
- package/dist/exchanges/spot-interface.d.ts +98 -4
- package/dist/exchanges/spot-interface.js +27 -1
- package/dist/exchanges/spot-result.d.ts +79 -0
- package/dist/exchanges/spot-result.js +273 -0
- package/dist/exchanges/trading-v2.d.ts +117 -0
- package/dist/exchanges/trading-v2.js +301 -0
- package/dist/exchanges/venue-types.d.ts +231 -0
- package/dist/exchanges/venue-types.js +87 -0
- package/dist/exchanges/venue.d.ts +211 -0
- package/dist/exchanges/venue.js +132 -0
- package/dist/exchanges/venues/arcus.d.ts +8 -0
- package/dist/exchanges/venues/arcus.js +109 -0
- package/dist/exchanges/venues/aster.d.ts +49 -0
- package/dist/exchanges/venues/aster.js +176 -0
- package/dist/exchanges/venues/create-helpers.d.ts +18 -0
- package/dist/exchanges/venues/create-helpers.js +199 -0
- package/dist/exchanges/venues/hyperliquid.d.ts +23 -0
- package/dist/exchanges/venues/hyperliquid.js +126 -0
- package/dist/exchanges/venues/index.d.ts +16 -0
- package/dist/exchanges/venues/index.js +26 -0
- package/dist/exchanges/venues/lighter-family.d.ts +92 -0
- package/dist/exchanges/venues/lighter-family.js +166 -0
- package/dist/exchanges/venues/lighter-rh.d.ts +7 -0
- package/dist/exchanges/venues/lighter-rh.js +58 -0
- package/dist/exchanges/venues/lighter.d.ts +6 -0
- package/dist/exchanges/venues/lighter.js +55 -0
- package/dist/exchanges/venues/ondo.d.ts +34 -0
- package/dist/exchanges/venues/ondo.js +140 -0
- package/dist/exchanges/venues/pacifica.d.ts +8 -0
- package/dist/exchanges/venues/pacifica.js +95 -0
- package/dist/exchanges/venues/qfex.d.ts +28 -0
- package/dist/exchanges/venues/qfex.js +132 -0
- package/dist/execution-log.js +10 -2
- package/dist/funding/legacy-public.d.ts +31 -0
- package/dist/funding/legacy-public.js +369 -0
- package/dist/funding/normalize.d.ts +28 -16
- package/dist/funding/normalize.js +61 -29
- package/dist/funding/rates.d.ts +46 -11
- package/dist/funding/rates.js +228 -277
- package/dist/guardrail/perp-guardrail.js +0 -0
- package/dist/index.js +156 -684
- package/dist/jobs.d.ts +84 -6
- package/dist/jobs.js +239 -41
- package/dist/landing.d.ts +7 -2
- package/dist/landing.js +19 -3
- package/dist/mcp-server.d.ts +14 -4
- package/dist/mcp-server.js +820 -402
- package/dist/mcp-trade-guard.d.ts +16 -0
- package/dist/mcp-trade-guard.js +59 -0
- package/dist/pacifica/client.d.ts +41 -10
- package/dist/pacifica/client.js +167 -63
- package/dist/pacifica/constants.d.ts +0 -1
- package/dist/pacifica/constants.js +0 -5
- package/dist/pacifica/deposit.d.ts +30 -3
- package/dist/pacifica/deposit.js +119 -2
- package/dist/pacifica/faucet.d.ts +29 -0
- package/dist/pacifica/faucet.js +100 -0
- package/dist/pacifica/sign-tx.d.ts +15 -0
- package/dist/pacifica/sign-tx.js +41 -0
- package/dist/pacifica/types/account.d.ts +28 -4
- package/dist/pacifica/types/lake.d.ts +20 -5
- package/dist/pacifica/types/lake.js +4 -0
- package/dist/pacifica/types/market.d.ts +5 -0
- package/dist/pacifica/types/order.d.ts +4 -1
- package/dist/pacifica/types/position.d.ts +9 -1
- package/dist/plan-executor.d.ts +10 -5
- package/dist/plan-executor.js +165 -54
- package/dist/position-history.js +13 -0
- package/dist/rebalance.d.ts +26 -2
- package/dist/rebalance.js +86 -7
- package/dist/relay-swap.d.ts +232 -0
- package/dist/relay-swap.js +630 -0
- package/dist/risk.js +5 -1
- package/dist/secret-env.d.ts +15 -0
- package/dist/secret-env.js +36 -0
- package/dist/settings.d.ts +169 -6
- package/dist/settings.js +219 -38
- package/dist/signer/ows-evm.d.ts +13 -0
- package/dist/signer/ows-evm.js +22 -0
- package/dist/smart-order.d.ts +9 -0
- package/dist/smart-order.js +53 -8
- package/dist/strategies/dca.d.ts +6 -2
- package/dist/strategies/dca.js +66 -26
- package/dist/strategies/funding-arb.d.ts +11 -1
- package/dist/strategies/funding-arb.js +202 -89
- package/dist/strategies/grid.d.ts +31 -0
- package/dist/strategies/grid.js +89 -11
- package/dist/strategies/pending-stop.d.ts +8 -0
- package/dist/strategies/pending-stop.js +12 -0
- package/dist/strategies/split-order.d.ts +45 -17
- package/dist/strategies/split-order.js +157 -91
- package/dist/strategies/trailing-stop.d.ts +2 -1
- package/dist/strategies/trailing-stop.js +52 -6
- package/dist/strategies/twap.d.ts +6 -1
- package/dist/strategies/twap.js +39 -11
- package/dist/trade-validator.d.ts +22 -0
- package/dist/trade-validator.js +119 -15
- package/dist/utils/numeric.d.ts +46 -0
- package/dist/utils/numeric.js +79 -0
- package/dist/utils.d.ts +19 -0
- package/dist/utils.js +96 -19
- package/dist/withdraw-gate.d.ts +49 -0
- package/dist/withdraw-gate.js +131 -0
- package/package.json +15 -6
- package/skills/perp-cli/SKILL.md +142 -55
- package/skills/perp-cli/references/agent-operations.md +110 -56
- package/skills/perp-cli/references/commands.md +266 -71
- package/skills/perp-cli/references/strategies.md +34 -31
- package/skills/perp-cli/scripts/arb-monitor.sh +10 -5
- package/skills/perp-cli/scripts/funding-analysis.sh +14 -9
- package/skills/perp-cli/scripts/preflight.sh +21 -14
- package/skills/perp-cli/scripts/spot-perp-scan.sh +12 -7
- package/skills/perp-cli/scripts/validate-arb.sh +31 -15
- package/vendor/lighter-signer/SHA256SUMS +2 -0
- package/vendor/lighter-signer/VERSION +8 -0
- package/vendor/lighter-signer/lighter-signer.wasm +0 -0
- package/vendor/lighter-signer/wasm_exec.js +575 -0
- package/dist/bot/strategies/funding-arb-v2-strategy.d.ts +0 -42
- package/dist/bot/strategies/funding-arb-v2-strategy.js +0 -864
package/dist/arb/utils.d.ts
CHANGED
|
@@ -1,24 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Arb utilities: settlement timing strategy, basis risk monitoring, and webhook notifications.
|
|
3
3
|
*/
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Settlement schedules per venue (UTC hours when settlement occurs), generated
|
|
6
|
+
* from `VenueDefinition.settlementIntervalHours`, anchored at 00:00 UTC
|
|
7
|
+
* (design §10.1, §10.13 #1). Venues whose interval is per-market (Aster)
|
|
8
|
+
* have no entry — pass the market's interval to getLastSettlement().
|
|
9
|
+
*/
|
|
5
10
|
export declare const SETTLEMENT_SCHEDULES: Record<string, number[]>;
|
|
6
11
|
export type SettleStrategy = "block" | "aggressive" | "off";
|
|
7
12
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
13
|
+
* Settlement interval in hours for a venue ref. `marketIntervalHours` (the
|
|
14
|
+
* market's `settlementIntervalHours`) takes precedence; it is required for
|
|
15
|
+
* per-market venues. Unknown venues throw UNKNOWN_VENUE.
|
|
16
|
+
*/
|
|
17
|
+
export declare function settlementIntervalHours(exchange: string, marketIntervalHours?: number | null): number;
|
|
18
|
+
/**
|
|
19
|
+
* Get the most recent settlement time for an exchange (anchored at 00:00 UTC).
|
|
20
|
+
* @param marketIntervalHours market settlement interval; required for per-market venues
|
|
21
|
+
* @returns Date of the most recent past settlement (== now when exactly on a settlement)
|
|
10
22
|
*/
|
|
11
|
-
export declare function getLastSettlement(exchange: string, now?: Date): Date;
|
|
23
|
+
export declare function getLastSettlement(exchange: string, now?: Date, marketIntervalHours?: number | null): Date;
|
|
12
24
|
/**
|
|
13
25
|
* Get minutes since the most recent settlement for an exchange.
|
|
14
26
|
*/
|
|
15
|
-
export declare function getMinutesSinceSettlement(exchange: string, now?: Date): number;
|
|
27
|
+
export declare function getMinutesSinceSettlement(exchange: string, now?: Date, marketIntervalHours?: number | null): number;
|
|
16
28
|
/**
|
|
17
29
|
* Compute a score boost for aggressive settlement mode.
|
|
18
30
|
* Returns a multiplier > 1.0 if within the post-settlement window, else 1.0.
|
|
19
31
|
* The boost decays linearly from 1.5x (right after settlement) to 1.0x (at windowMinutes).
|
|
32
|
+
* `marketIntervalFor` returns the market's settlement interval per exchange;
|
|
33
|
+
* it must return a number for per-market venues (Aster).
|
|
20
34
|
*/
|
|
21
|
-
export declare function aggressiveSettleBoost(longExchange: string, shortExchange: string, windowMinutes?: number, now?: Date): number;
|
|
35
|
+
export declare function aggressiveSettleBoost(longExchange: string, shortExchange: string, windowMinutes?: number, now?: Date, marketIntervalFor?: (exchange: string) => number | null): number;
|
|
22
36
|
/**
|
|
23
37
|
* Estimate cumulative funding between now and the next settlement.
|
|
24
38
|
*
|
package/dist/arb/utils.js
CHANGED
|
@@ -1,62 +1,66 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Arb utilities: settlement timing strategy, basis risk monitoring, and webhook notifications.
|
|
3
3
|
*/
|
|
4
|
+
import { PerpError } from "../errors.js";
|
|
5
|
+
import { listVenues, settlementIntervalOf } from "../exchanges/venue.js";
|
|
6
|
+
import { ensureVenuesRegistered } from "../exchanges/venues/index.js";
|
|
4
7
|
// ── Settlement Timing Strategy ──
|
|
5
|
-
|
|
6
|
-
export const SETTLEMENT_SCHEDULES = {
|
|
7
|
-
hyperliquid: Array.from({ length: 24 }, (_, i) => i), // every hour
|
|
8
|
-
pacifica: Array.from({ length: 24 }, (_, i) => i), // every hour
|
|
9
|
-
lighter: Array.from({ length: 24 }, (_, i) => i), // every hour
|
|
10
|
-
aster: [0, 8, 16], // every 8 hours (Binance convention)
|
|
11
|
-
};
|
|
8
|
+
ensureVenuesRegistered();
|
|
12
9
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* Settlement schedules per venue (UTC hours when settlement occurs), generated
|
|
11
|
+
* from `VenueDefinition.settlementIntervalHours`, anchored at 00:00 UTC
|
|
12
|
+
* (design §10.1, §10.13 #1). Venues whose interval is per-market (Aster)
|
|
13
|
+
* have no entry — pass the market's interval to getLastSettlement().
|
|
15
14
|
*/
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
export const SETTLEMENT_SCHEDULES = Object.fromEntries(listVenues()
|
|
16
|
+
.filter(v => v.settlementIntervalHours !== "perMarket")
|
|
17
|
+
.map(v => [v.id, scheduleFor(v.settlementIntervalHours)]));
|
|
18
|
+
function scheduleFor(intervalHours) {
|
|
19
|
+
if (!(intervalHours > 0) || 24 % intervalHours !== 0) {
|
|
20
|
+
throw new PerpError("INVALID_PARAMS", `Settlement interval ${intervalHours}h does not divide a UTC day`);
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// Exactly at settlement time
|
|
33
|
-
if (hour === currentHour && currentMinutes === 0 && currentSeconds === 0) {
|
|
34
|
-
const last = new Date(now);
|
|
35
|
-
last.setUTCHours(hour, 0, 0, 0);
|
|
36
|
-
return last;
|
|
22
|
+
return Array.from({ length: 24 / intervalHours }, (_, i) => i * intervalHours);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Settlement interval in hours for a venue ref. `marketIntervalHours` (the
|
|
26
|
+
* market's `settlementIntervalHours`) takes precedence; it is required for
|
|
27
|
+
* per-market venues. Unknown venues throw UNKNOWN_VENUE.
|
|
28
|
+
*/
|
|
29
|
+
export function settlementIntervalHours(exchange, marketIntervalHours = null) {
|
|
30
|
+
if (marketIntervalHours !== null) {
|
|
31
|
+
if (!(marketIntervalHours > 0)) {
|
|
32
|
+
throw new PerpError("INVALID_PARAMS", `Invalid settlement interval ${marketIntervalHours}h for ${exchange}`);
|
|
37
33
|
}
|
|
34
|
+
return marketIntervalHours;
|
|
38
35
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
return settlementIntervalOf(exchange);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get the most recent settlement time for an exchange (anchored at 00:00 UTC).
|
|
40
|
+
* @param marketIntervalHours market settlement interval; required for per-market venues
|
|
41
|
+
* @returns Date of the most recent past settlement (== now when exactly on a settlement)
|
|
42
|
+
*/
|
|
43
|
+
export function getLastSettlement(exchange, now = new Date(), marketIntervalHours = null) {
|
|
44
|
+
const intervalMs = settlementIntervalHours(exchange, marketIntervalHours) * 3_600_000;
|
|
45
|
+
return new Date(Math.floor(now.getTime() / intervalMs) * intervalMs);
|
|
44
46
|
}
|
|
45
47
|
/**
|
|
46
48
|
* Get minutes since the most recent settlement for an exchange.
|
|
47
49
|
*/
|
|
48
|
-
export function getMinutesSinceSettlement(exchange, now = new Date()) {
|
|
49
|
-
const lastSettle = getLastSettlement(exchange, now);
|
|
50
|
+
export function getMinutesSinceSettlement(exchange, now = new Date(), marketIntervalHours = null) {
|
|
51
|
+
const lastSettle = getLastSettlement(exchange, now, marketIntervalHours);
|
|
50
52
|
return (now.getTime() - lastSettle.getTime()) / (1000 * 60);
|
|
51
53
|
}
|
|
52
54
|
/**
|
|
53
55
|
* Compute a score boost for aggressive settlement mode.
|
|
54
56
|
* Returns a multiplier > 1.0 if within the post-settlement window, else 1.0.
|
|
55
57
|
* The boost decays linearly from 1.5x (right after settlement) to 1.0x (at windowMinutes).
|
|
58
|
+
* `marketIntervalFor` returns the market's settlement interval per exchange;
|
|
59
|
+
* it must return a number for per-market venues (Aster).
|
|
56
60
|
*/
|
|
57
|
-
export function aggressiveSettleBoost(longExchange, shortExchange, windowMinutes = 10, now = new Date()) {
|
|
58
|
-
const longMinutes = getMinutesSinceSettlement(longExchange, now);
|
|
59
|
-
const shortMinutes = getMinutesSinceSettlement(shortExchange, now);
|
|
61
|
+
export function aggressiveSettleBoost(longExchange, shortExchange, windowMinutes = 10, now = new Date(), marketIntervalFor = () => null) {
|
|
62
|
+
const longMinutes = getMinutesSinceSettlement(longExchange, now, marketIntervalFor(longExchange));
|
|
63
|
+
const shortMinutes = getMinutesSinceSettlement(shortExchange, now, marketIntervalFor(shortExchange));
|
|
60
64
|
// Use the minimum of the two — we want BOTH exchanges to have recently settled
|
|
61
65
|
const minMinutes = Math.min(longMinutes, shortMinutes);
|
|
62
66
|
if (minMinutes <= windowMinutes) {
|
package/dist/bot/conditions.d.ts
CHANGED
|
@@ -19,14 +19,14 @@ export interface MarketSnapshot {
|
|
|
19
19
|
export declare function calculateRSI(closes: number[], period?: number): number;
|
|
20
20
|
export declare function getMarketSnapshot(adapter: ExchangeAdapter, symbol: string): Promise<MarketSnapshot>;
|
|
21
21
|
export declare function evaluateCondition(condition: Condition, snapshot: MarketSnapshot, context: {
|
|
22
|
-
equity: number;
|
|
22
|
+
equity: number | null;
|
|
23
23
|
startTime: number;
|
|
24
|
-
peakEquity: number;
|
|
24
|
+
peakEquity: number | null;
|
|
25
25
|
dailyPnl: number;
|
|
26
26
|
}): boolean;
|
|
27
27
|
export declare function evaluateAllConditions(conditions: Condition[], snapshot: MarketSnapshot, context: {
|
|
28
|
-
equity: number;
|
|
28
|
+
equity: number | null;
|
|
29
29
|
startTime: number;
|
|
30
|
-
peakEquity: number;
|
|
30
|
+
peakEquity: number | null;
|
|
31
31
|
dailyPnl: number;
|
|
32
32
|
}, mode?: "all" | "any"): boolean;
|
package/dist/bot/conditions.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { symbolMatch } from "../utils.js";
|
|
1
2
|
// ── RSI Calculation (Wilder smoothing) ──
|
|
2
3
|
/**
|
|
3
4
|
* Calculate RSI from an array of closing prices using Wilder's smoothing method.
|
|
@@ -39,13 +40,16 @@ export function calculateRSI(closes, period = 14) {
|
|
|
39
40
|
}
|
|
40
41
|
export async function getMarketSnapshot(adapter, symbol) {
|
|
41
42
|
const markets = await adapter.getMarkets();
|
|
42
|
-
const m = markets.find(mk => mk.symbol
|
|
43
|
+
const m = markets.find(mk => symbolMatch(mk.symbol, symbol));
|
|
43
44
|
if (!m) {
|
|
44
45
|
throw new Error(`Market "${symbol}" not found on ${adapter.name}`);
|
|
45
46
|
}
|
|
46
47
|
const price = parseFloat(m.markPrice);
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
// Unknown funding (venue publishes none, e.g. QFEX) → NaN, never 0: a 0 would satisfy
|
|
49
|
+
// "funding below X" conditions on a rate nobody reported. NaN makes every comparison false.
|
|
50
|
+
const fundingRate = m.fundingRate === null ? NaN : parseFloat(m.fundingRate);
|
|
51
|
+
// Unknown volume → NaN, never 0: a 0 would read as "no liquidity" to volume conditions.
|
|
52
|
+
const volume24h = m.volume24h === null ? NaN : parseFloat(m.volume24h);
|
|
49
53
|
// Try to get kline data for 24h high/low + RSI
|
|
50
54
|
let high24h = price;
|
|
51
55
|
let low24h = price;
|
|
@@ -113,10 +117,11 @@ export function evaluateCondition(condition, snapshot, context) {
|
|
|
113
117
|
return !isNaN(snapshot.rsi) && snapshot.rsi > val;
|
|
114
118
|
case "rsi_below":
|
|
115
119
|
return !isNaN(snapshot.rsi) && snapshot.rsi < val;
|
|
120
|
+
// Unknown equity (null) never meets an equity condition — neither a fake stop nor a fake entry.
|
|
116
121
|
case "balance_above":
|
|
117
|
-
return context.equity > val;
|
|
122
|
+
return context.equity !== null && context.equity > val;
|
|
118
123
|
case "balance_below":
|
|
119
|
-
return context.equity < val;
|
|
124
|
+
return context.equity !== null && context.equity < val;
|
|
120
125
|
case "spread_above":
|
|
121
126
|
// Bid-ask spread percentage, pre-computed from orderbook in snapshot.
|
|
122
127
|
return snapshot.spreadPct > val;
|
|
@@ -125,7 +130,7 @@ export function evaluateCondition(condition, snapshot, context) {
|
|
|
125
130
|
return elapsed > val;
|
|
126
131
|
}
|
|
127
132
|
case "max_drawdown":
|
|
128
|
-
return (context.peakEquity - context.equity) > val;
|
|
133
|
+
return context.equity !== null && context.peakEquity !== null && (context.peakEquity - context.equity) > val;
|
|
129
134
|
default:
|
|
130
135
|
return false;
|
|
131
136
|
}
|
package/dist/bot/config.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type VenueId } from "../exchanges/venue.js";
|
|
1
2
|
export type ConditionType = "price_above" | "price_below" | "volatility_above" | "volatility_below" | "funding_rate_above" | "funding_rate_below" | "spread_above" | "rsi_above" | "rsi_below" | "balance_above" | "balance_below" | "time_after" | "max_drawdown" | "always";
|
|
2
3
|
export interface Condition {
|
|
3
4
|
type: ConditionType;
|
|
@@ -59,7 +60,22 @@ export interface BotConfig {
|
|
|
59
60
|
risk: RiskConfig;
|
|
60
61
|
monitor_interval_sec: number;
|
|
61
62
|
}
|
|
62
|
-
|
|
63
|
+
/**
|
|
64
|
+
* The venue selected on the command line: the root `-e` value (resolved id) and whether it was
|
|
65
|
+
* given explicitly (commander option source "cli") or is the CLI default.
|
|
66
|
+
*/
|
|
67
|
+
export interface CliVenueSelection {
|
|
68
|
+
id: VenueId;
|
|
69
|
+
explicit: boolean;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The venue a config runs on. `config.exchange` (alias resolved; unknown → UNKNOWN_VENUE) wins
|
|
73
|
+
* over the CLI default; an explicit root `-e` naming a different venue is a contradiction →
|
|
74
|
+
* INVALID_PARAMS (never one of them silently). No `exchange` in the config → the CLI selection.
|
|
75
|
+
*/
|
|
76
|
+
export declare function resolveConfigVenue(configExchange: string | null, cli: CliVenueSelection): VenueId;
|
|
77
|
+
/** Load a bot config; its venue is resolved against the CLI selection (resolveConfigVenue). */
|
|
78
|
+
export declare function loadBotConfig(pathOrInline: string, cli: CliVenueSelection): BotConfig;
|
|
63
79
|
export declare function parseStrategy(type: string, raw: Record<string, unknown>): StrategyParams;
|
|
64
80
|
export declare function quickGridConfig(opts: {
|
|
65
81
|
exchange: string;
|
package/dist/bot/config.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { readFileSync, existsSync } from "node:fs";
|
|
2
2
|
import { parse as parseYaml } from "yaml";
|
|
3
|
+
import { PerpError, extractErrorMessage } from "../errors.js";
|
|
4
|
+
import { resolveVenueId } from "../exchanges/venue.js";
|
|
3
5
|
// ── Defaults ──
|
|
4
6
|
const DEFAULT_RISK = {
|
|
5
7
|
max_position_usd: 1000,
|
|
@@ -8,27 +10,61 @@ const DEFAULT_RISK = {
|
|
|
8
10
|
pause_after_loss_sec: 300,
|
|
9
11
|
max_open_bots: 5,
|
|
10
12
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
/**
|
|
14
|
+
* The venue a config runs on. `config.exchange` (alias resolved; unknown → UNKNOWN_VENUE) wins
|
|
15
|
+
* over the CLI default; an explicit root `-e` naming a different venue is a contradiction →
|
|
16
|
+
* INVALID_PARAMS (never one of them silently). No `exchange` in the config → the CLI selection.
|
|
17
|
+
*/
|
|
18
|
+
export function resolveConfigVenue(configExchange, cli) {
|
|
19
|
+
if (configExchange === null)
|
|
20
|
+
return cli.id;
|
|
21
|
+
const id = resolveVenueId(configExchange);
|
|
22
|
+
if (cli.explicit && cli.id !== id) {
|
|
23
|
+
throw new PerpError("INVALID_PARAMS", `The config runs on "${configExchange}" (${id}) but -e selects ${cli.id}`, {
|
|
24
|
+
remediation: `Drop -e, or pass -e ${id}, or change "exchange" in the config`,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return id;
|
|
28
|
+
}
|
|
29
|
+
/** Load a bot config; its venue is resolved against the CLI selection (resolveConfigVenue). */
|
|
30
|
+
export function loadBotConfig(pathOrInline, cli) {
|
|
13
31
|
let raw;
|
|
32
|
+
const remediation = "Pass a readable YAML/JSON config file path (or inline JSON). See examples with: perp strategy example";
|
|
14
33
|
if (existsSync(pathOrInline)) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
34
|
+
let content;
|
|
35
|
+
try {
|
|
36
|
+
content = readFileSync(pathOrInline, "utf-8");
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
throw new PerpError("INVALID_PARAMS", `Cannot read bot config file '${pathOrInline}': ${extractErrorMessage(err)}`, { remediation });
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
raw = pathOrInline.endsWith(".json") ? JSON.parse(content) : parseYaml(content);
|
|
18
43
|
}
|
|
19
|
-
|
|
20
|
-
|
|
44
|
+
catch (err) {
|
|
45
|
+
throw new PerpError("INVALID_PARAMS", `Bot config file '${pathOrInline}' is not valid ${pathOrInline.endsWith(".json") ? "JSON" : "YAML"}: ${extractErrorMessage(err)}`, { remediation });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (pathOrInline.trimStart().startsWith("{")) {
|
|
49
|
+
// Inline JSON config
|
|
50
|
+
try {
|
|
51
|
+
raw = JSON.parse(pathOrInline);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
throw new PerpError("INVALID_PARAMS", `Inline bot config is not valid JSON: ${extractErrorMessage(err)}`, { remediation });
|
|
21
55
|
}
|
|
22
56
|
}
|
|
23
57
|
else {
|
|
24
|
-
|
|
25
|
-
raw = JSON.parse(pathOrInline);
|
|
58
|
+
throw new PerpError("INVALID_PARAMS", `Bot config file not found: '${pathOrInline}'`, { remediation });
|
|
26
59
|
}
|
|
27
|
-
return parseBotConfig(raw);
|
|
60
|
+
return parseBotConfig(raw, cli);
|
|
28
61
|
}
|
|
29
|
-
function parseBotConfig(raw) {
|
|
62
|
+
function parseBotConfig(raw, cli) {
|
|
30
63
|
const name = String(raw.name ?? `bot-${Date.now()}`);
|
|
31
|
-
|
|
64
|
+
if (raw.exchange !== undefined && (typeof raw.exchange !== "string" || raw.exchange.trim() === "")) {
|
|
65
|
+
throw new PerpError("INVALID_PARAMS", `Bot config "exchange" must be a venue name (got ${JSON.stringify(raw.exchange)})`);
|
|
66
|
+
}
|
|
67
|
+
const exchange = resolveConfigVenue(typeof raw.exchange === "string" ? raw.exchange : null, cli);
|
|
32
68
|
const symbol = String(raw.symbol ?? "ETH");
|
|
33
69
|
const monitorInterval = Number(raw.monitor_interval_sec ?? raw.interval ?? 30);
|
|
34
70
|
// Strategy
|
package/dist/bot/engine.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { ExchangeAdapter } from "../exchanges/index.js";
|
|
2
|
+
import { filledOf } from "./fill-size.js";
|
|
2
3
|
import type { BotConfig } from "./config.js";
|
|
4
|
+
import type { StrategyAction } from "./strategy-types.js";
|
|
5
|
+
import { type QuoteRules } from "./quote-rules.js";
|
|
3
6
|
import "./strategies/grid-strategy.js";
|
|
4
7
|
import "./strategies/dca-strategy.js";
|
|
5
8
|
import "./strategies/funding-arb-strategy.js";
|
|
@@ -22,9 +25,65 @@ import "./strategies/funding-auto.js";
|
|
|
22
25
|
import "./strategies/spot-perp-arb-strategy.js";
|
|
23
26
|
export type BotLog = (msg: string) => void;
|
|
24
27
|
export type BotOutputMode = "tui" | "json" | "headless";
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Strategies that place/close orders themselves (multi-leg executors, spot legs) instead of
|
|
30
|
+
* returning StrategyActions — the engine cannot simulate them, so --dry-run is refused.
|
|
31
|
+
*/
|
|
32
|
+
export declare const NON_SIMULATABLE_STRATEGIES: ReadonlySet<string>;
|
|
33
|
+
/**
|
|
34
|
+
* ExchangeAdapter methods a --dry-run bot may call: pure reads (plus resolveSymbol, a local
|
|
35
|
+
* lookup). Allowlist, not blocklist (review L4): any other method — every venue write, and any
|
|
36
|
+
* write added to an adapter later — throws, so a dry-run can never reach the venue's write path.
|
|
37
|
+
*/
|
|
38
|
+
export declare const ADAPTER_READ_METHODS: ReadonlySet<string>;
|
|
39
|
+
/** Throw INVALID_PARAMS if `strategyType` cannot run under --dry-run (checked before any adapter call). */
|
|
40
|
+
export declare function assertStrategySimulatable(strategyType: string): void;
|
|
41
|
+
/** Wrap an adapter so only allowlisted reads run; every other method throws (defense in depth for --dry-run bots). */
|
|
42
|
+
export declare function dryRunAdapter(adapter: ExchangeAdapter): ExchangeAdapter;
|
|
43
|
+
export declare function runBot(adapter: ExchangeAdapter, config: BotConfig, jobId: string | undefined, log: BotLog, extraAdapters: Map<string, ExchangeAdapter> | undefined, // for funding-arb (multi-exchange)
|
|
44
|
+
mode: BotOutputMode,
|
|
45
|
+
/** Global --dry-run: strategy actions are logged, never sent; non-simulatable strategies are refused. */
|
|
46
|
+
isDryRun: boolean): Promise<{
|
|
27
47
|
fills: number;
|
|
48
|
+
ordersPlaced: number;
|
|
28
49
|
totalPnl: number;
|
|
29
50
|
runtime: number;
|
|
30
51
|
}>;
|
|
52
|
+
/** Consecutive ticks with unknown equity after which the bot stops (an error, never a silent run). */
|
|
53
|
+
export declare const UNKNOWN_EQUITY_STOP_TICKS = 10;
|
|
54
|
+
/** Strategies that read the snapshot's orderbook / klines: a tick whose read failed is skipped. */
|
|
55
|
+
export declare const MARKET_DATA_STRATEGIES: ReadonlySet<string>;
|
|
56
|
+
/** Strategies that hold spot legs (spot-perp): their stop summary lists the spot holdings too. */
|
|
57
|
+
export declare const SPOT_LEG_STRATEGIES: ReadonlySet<string>;
|
|
58
|
+
/** A position left open at stop, with the command that closes it (a pair's legs share one command). */
|
|
59
|
+
export interface OpenPositionAtStop {
|
|
60
|
+
exchange: string;
|
|
61
|
+
symbol: string;
|
|
62
|
+
side: string;
|
|
63
|
+
size: string;
|
|
64
|
+
close: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Open positions at stop (logged with the close command); a failed read is logged, never "none".
|
|
68
|
+
* `spotLegs` (a multi-venue spot-perp bot): the bot spot venues' holdings of the traded symbol(s)
|
|
69
|
+
* are listed too — a spot holding + a perp short of one symbol is closed as a pair
|
|
70
|
+
* (`arb close --spot-exch --perp-exch`), never the short alone (that leaves the spot unhedged).
|
|
71
|
+
*/
|
|
72
|
+
export declare function openPositionsAtStop(primary: ExchangeAdapter, symbol: string, extra: Map<string, ExchangeAdapter> | undefined, log: BotLog, spotLegs: boolean): Promise<OpenPositionAtStop[]>;
|
|
73
|
+
/**
|
|
74
|
+
* Send strategy actions. Orders go out on the venue grid (quote-rules.ts): limit prices aligned
|
|
75
|
+
* passively to the tick (bid ↓, ask ↑), sizes floored to the lot, venue minimums refused before
|
|
76
|
+
* sending. `refPrice` = the tick's snapshot price (minimum order value of market orders).
|
|
77
|
+
* One order under the venue minimum (e.g. the inventory-skewed side of a market maker) is
|
|
78
|
+
* skipped for this tick with a log line — the other orders still go out; when EVERY order of
|
|
79
|
+
* the batch is under the minimum the last SIZE_TOO_SMALL is thrown (the tick fails: the
|
|
80
|
+
* strategy's base size itself is too small).
|
|
81
|
+
* Returns the orders sent (`placed`) and those the venue reported as (partly) filled (`filled`,
|
|
82
|
+
* filledOf) — an accepted resting limit order is a placement, not a fill. Under --dry-run every
|
|
83
|
+
* place_order is a simulated placement and nothing fills.
|
|
84
|
+
*/
|
|
85
|
+
export declare function executeActions(adapter: ExchangeAdapter, symbol: string, actions: StrategyAction[], log: BotLog, dryRun: boolean, rulesOf: () => Promise<QuoteRules>, refPrice: number): Promise<{
|
|
86
|
+
placed: number;
|
|
87
|
+
filled: number;
|
|
88
|
+
}>;
|
|
89
|
+
export { filledOf };
|