@reefclaw/openclaw-plugin 0.1.5 → 0.1.6
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/ccxt/binance-private.d.ts +21 -0
- package/ccxt/binance-private.js +132 -22
- package/config/plugin-config-io.d.ts +6 -0
- package/config/tool-gate.js +3 -0
- package/exchange-adapter.d.ts +16 -0
- package/index.js +551 -54
- package/lifecycle/trading-operation-lock.d.ts +17 -0
- package/lifecycle/trading-operation-lock.js +14 -0
- package/live/bracket-id.d.ts +2 -3
- package/live/bracket-id.js +22 -9
- package/live/live-adapter.d.ts +24 -1
- package/live/live-adapter.js +114 -2
- package/live/local-signal-service.js +11 -6
- package/live/local-strategy-evaluator.js +4 -0
- package/live/proposal-decision-listener.d.ts +6 -0
- package/live/proposal-decision-listener.js +4 -0
- package/live/stop-watcher.d.ts +27 -1
- package/live/stop-watcher.js +59 -2
- package/onboarding/runtime.d.ts +13 -0
- package/onboarding/runtime.js +22 -2
- package/openclaw.plugin.json +1 -0
- package/package.json +1 -1
- package/portfolio/wave9-admission.d.ts +67 -0
- package/portfolio/wave9-admission.js +262 -0
- package/portfolio/wave9-policy.d.ts +36 -0
- package/portfolio/wave9-policy.js +183 -0
- package/signals/conditions/registry.js +50 -0
- package/simulator/exchange-simulator.js +5 -0
- package/simulator/fill-engine.js +5 -1
- package/simulator/types.d.ts +6 -1
- package/strategy/evaluator.d.ts +3 -0
- package/strategy/evaluator.js +5 -0
- package/tools/assessment-validation.d.ts +2 -0
- package/tools/attach-brackets.d.ts +7 -2
- package/tools/attach-brackets.js +36 -0
- package/tools/cancel-all-orders.d.ts +2 -0
- package/tools/cancel-all-orders.js +4 -1
- package/tools/cancel-order.d.ts +4 -0
- package/tools/cancel-order.js +49 -3
- package/tools/close-position.d.ts +23 -0
- package/tools/close-position.js +286 -13
- package/tools/create-order.d.ts +28 -0
- package/tools/create-order.js +1364 -192
- package/tools/get-analytics.js +2 -2
- package/tools/get-basis.js +2 -2
- package/tools/get-cascade-risk.js +2 -2
- package/tools/get-crypto-metrics.js +14 -4
- package/tools/get-cvd.js +2 -2
- package/tools/get-divergences.js +2 -2
- package/tools/get-funding-context.js +2 -2
- package/tools/get-liquidation-levels.js +2 -2
- package/tools/get-liquidation-pulse.js +2 -2
- package/tools/get-pattern-scan.js +2 -2
- package/tools/get-regime.js +2 -2
- package/tools/get-resting-liquidity.js +2 -2
- package/tools/get-risk-scenario.js +2 -2
- package/tools/get-session-review.js +2 -2
- package/tools/get-setup-detail.js +9 -1
- package/tools/get-signals.js +2 -2
- package/tools/get-sizing.js +2 -2
- package/tools/get-trade-feedback.js +2 -2
- package/tools/get-trade-flow.js +2 -2
- package/tools/get-volume-profile.js +2 -2
- package/tools/get-wave9-status.d.ts +127 -0
- package/tools/get-wave9-status.js +796 -0
- package/tools/intel-api.d.ts +20 -0
- package/tools/intel-api.js +67 -0
- package/tools/intel-cache.d.ts +1 -1
- package/tools/intel-cache.js +20 -5
- package/tools/list-strategies.d.ts +11 -1
- package/tools/list-strategies.js +17 -0
- package/tools/modify-stop.d.ts +4 -0
- package/tools/modify-stop.js +63 -24
- package/tools/modify-target.d.ts +4 -0
- package/tools/modify-target.js +62 -23
- package/tools/scan-pairs.js +19 -8
- package/tools/toggle-strategy.js +7 -0
- package/types.d.ts +5 -0
- package/venues/hyperliquid/hl-balance.d.ts +116 -0
- package/venues/hyperliquid/hl-balance.js +145 -0
- package/venues/hyperliquid/hl-brackets.d.ts +102 -0
- package/venues/hyperliquid/hl-brackets.js +172 -0
- package/venues/hyperliquid/hl-cloid.d.ts +22 -0
- package/venues/hyperliquid/hl-cloid.js +82 -0
- package/venues/hyperliquid/hl-info-cache.d.ts +46 -0
- package/venues/hyperliquid/hl-info-cache.js +125 -0
- package/venues/hyperliquid/hl-live-adapter.d.ts +88 -0
- package/venues/hyperliquid/hl-live-adapter.js +353 -0
- package/venues/hyperliquid/hl-precision.d.ts +61 -0
- package/venues/hyperliquid/hl-precision.js +176 -0
- package/venues/hyperliquid/hl-private.d.ts +88 -0
- package/venues/hyperliquid/hl-private.js +357 -0
- package/venues/hyperliquid/hl-public.d.ts +31 -4
- package/venues/hyperliquid/hl-public.js +155 -11
- package/venues/hyperliquid/hl-rate-gate.d.ts +57 -0
- package/venues/hyperliquid/hl-rate-gate.js +220 -0
- package/venues/hyperliquid/hl-user-stream.d.ts +90 -0
- package/venues/hyperliquid/hl-user-stream.js +220 -0
- package/venues/registry.d.ts +23 -9
- package/venues/registry.js +12 -13
- package/venues/symbols.d.ts +43 -0
- package/venues/symbols.js +107 -0
- package/wave9/live-account-capture.d.ts +67 -0
- package/wave9/live-account-capture.js +435 -0
- package/wave9/live-autonomous-protection.d.ts +39 -0
- package/wave9/live-autonomous-protection.js +112 -0
- package/wave9/live-durable-reconciliation-scheduler.d.ts +33 -0
- package/wave9/live-durable-reconciliation-scheduler.js +115 -0
- package/wave9/live-execution-ledger.d.ts +107 -0
- package/wave9/live-execution-ledger.js +498 -0
- package/wave9/live-position-confirmation.d.ts +18 -0
- package/wave9/live-position-confirmation.js +111 -0
- package/wave9/live-residual-protection.d.ts +18 -0
- package/wave9/live-residual-protection.js +250 -0
- package/wave9/live-startup-reconciliation.d.ts +38 -0
- package/wave9/live-startup-reconciliation.js +454 -0
- package/wave9/live-symbol-ownership.d.ts +20 -0
- package/wave9/live-symbol-ownership.js +132 -0
- package/wave9/paper-admission-guard.d.ts +199 -0
- package/wave9/paper-admission-guard.js +650 -0
- package/wave9/usdm-evidence-provider.d.ts +42 -0
- package/wave9/usdm-evidence-provider.js +133 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CcxtOrder, CcxtBalance, CcxtPosition, CcxtTicker, ExchangeConfig } from '../types.js';
|
|
2
|
+
import type { ClientOrderResolution } from '../exchange-adapter.js';
|
|
2
3
|
import type { OrderBookDepth } from '../simulator/types.js';
|
|
3
4
|
/** Result of API permission validation. */
|
|
4
5
|
export interface PermissionCheckResult {
|
|
@@ -7,6 +8,18 @@ export interface PermissionCheckResult {
|
|
|
7
8
|
canTrade: boolean;
|
|
8
9
|
errors: string[];
|
|
9
10
|
}
|
|
11
|
+
/** Exact, weight-1 proof returned by Binance's per-clientAlgoId endpoint. */
|
|
12
|
+
export interface BinanceAlgoOrderProof {
|
|
13
|
+
algoId: string | null;
|
|
14
|
+
clientAlgoId: string;
|
|
15
|
+
algoStatus: string;
|
|
16
|
+
symbol: string | null;
|
|
17
|
+
side: 'buy' | 'sell' | null;
|
|
18
|
+
orderType: string | null;
|
|
19
|
+
triggerPrice: number | null;
|
|
20
|
+
quantity: number | null;
|
|
21
|
+
closePosition: boolean | null;
|
|
22
|
+
}
|
|
10
23
|
export declare class BinancePrivateApi {
|
|
11
24
|
private exchange;
|
|
12
25
|
private testnet;
|
|
@@ -154,6 +167,12 @@ export declare class BinancePrivateApi {
|
|
|
154
167
|
* because "I was rate-limited" is just another flavour of "no answer").
|
|
155
168
|
* Ships dark in Phase 1 — no call sites yet. */
|
|
156
169
|
queryAlgoOrderStatus(clientAlgoId: string): Promise<string | null>;
|
|
170
|
+
/**
|
|
171
|
+
* Fetch the full exchange shape for one exact conditional order. Unlike the
|
|
172
|
+
* broad open-algo snapshot, this endpoint is immediately usable after
|
|
173
|
+
* placement and is keyed by the stop's unique clientAlgoId.
|
|
174
|
+
*/
|
|
175
|
+
queryAlgoOrderProof(clientAlgoId: string): Promise<BinanceAlgoOrderProof | null>;
|
|
157
176
|
/** Fetch historical fills (trades) for a symbol via GET /fapi/v1/userTrades.
|
|
158
177
|
* Used by the REST gap-filler (rest-gap-filler.ts) to backfill any fills
|
|
159
178
|
* that landed during a WS blind window — when the user-data stream was
|
|
@@ -214,6 +233,8 @@ export declare class BinancePrivateApi {
|
|
|
214
233
|
* after network timeouts — check if the order went through before retrying.
|
|
215
234
|
*/
|
|
216
235
|
fetchOrderByClientId(clientOrderId: string, symbol: string): Promise<CcxtOrder | null>;
|
|
236
|
+
/** Resolve a deterministic client id without treating read failures as absence. */
|
|
237
|
+
resolveOrderByClientId(clientOrderId: string, symbol: string): Promise<ClientOrderResolution>;
|
|
217
238
|
/** Cancel a real order on the exchange. Binance Futures splits orders across
|
|
218
239
|
* two endpoints — regular (`/fapi/v1/order`) and algo/conditional
|
|
219
240
|
* (`/fapi/v1/algoOrder`). Bracket SL/TP live in the algo bucket.
|
package/ccxt/binance-private.js
CHANGED
|
@@ -682,6 +682,68 @@ export class BinancePrivateApi {
|
|
|
682
682
|
return null;
|
|
683
683
|
}
|
|
684
684
|
}
|
|
685
|
+
/**
|
|
686
|
+
* Fetch the full exchange shape for one exact conditional order. Unlike the
|
|
687
|
+
* broad open-algo snapshot, this endpoint is immediately usable after
|
|
688
|
+
* placement and is keyed by the stop's unique clientAlgoId.
|
|
689
|
+
*/
|
|
690
|
+
async queryAlgoOrderProof(clientAlgoId) {
|
|
691
|
+
if (!clientAlgoId)
|
|
692
|
+
return null;
|
|
693
|
+
try {
|
|
694
|
+
assertNotBanned('queryAlgoOrder');
|
|
695
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
696
|
+
const ex = this.exchange;
|
|
697
|
+
if (typeof ex.fapiPrivateGetAlgoOrder !== 'function')
|
|
698
|
+
return null;
|
|
699
|
+
const raw = await ex.fapiPrivateGetAlgoOrder({ clientAlgoId });
|
|
700
|
+
noteSuccess();
|
|
701
|
+
let row;
|
|
702
|
+
if (Array.isArray(raw)) {
|
|
703
|
+
row = raw
|
|
704
|
+
.find((item) => String(item.clientAlgoId ?? '') === clientAlgoId);
|
|
705
|
+
}
|
|
706
|
+
else if (raw && typeof raw === 'object') {
|
|
707
|
+
const candidate = raw;
|
|
708
|
+
if (String(candidate.clientAlgoId ?? '') === clientAlgoId)
|
|
709
|
+
row = candidate;
|
|
710
|
+
}
|
|
711
|
+
if (!row)
|
|
712
|
+
return null;
|
|
713
|
+
const algoStatus = String(row.algoStatus ?? '').trim().toUpperCase();
|
|
714
|
+
if (!algoStatus)
|
|
715
|
+
return null;
|
|
716
|
+
const sideValue = String(row.side ?? '').trim().toLowerCase();
|
|
717
|
+
const side = sideValue === 'buy' || sideValue === 'sell' ? sideValue : null;
|
|
718
|
+
const triggerPriceValue = Number(row.triggerPrice);
|
|
719
|
+
const quantityValue = Number(row.quantity);
|
|
720
|
+
const closePositionValue = row.closePosition;
|
|
721
|
+
const closePosition = closePositionValue === true
|
|
722
|
+
|| String(closePositionValue).toLowerCase() === 'true'
|
|
723
|
+
? true
|
|
724
|
+
: closePositionValue === false || String(closePositionValue).toLowerCase() === 'false'
|
|
725
|
+
? false
|
|
726
|
+
: null;
|
|
727
|
+
return {
|
|
728
|
+
algoId: row.algoId == null ? null : String(row.algoId),
|
|
729
|
+
clientAlgoId,
|
|
730
|
+
algoStatus,
|
|
731
|
+
symbol: row.symbol == null ? null : String(row.symbol),
|
|
732
|
+
side,
|
|
733
|
+
orderType: row.orderType == null ? null : String(row.orderType).toUpperCase(),
|
|
734
|
+
triggerPrice: Number.isFinite(triggerPriceValue) && triggerPriceValue > 0
|
|
735
|
+
? triggerPriceValue
|
|
736
|
+
: null,
|
|
737
|
+
quantity: Number.isFinite(quantityValue) && quantityValue >= 0 ? quantityValue : null,
|
|
738
|
+
closePosition,
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
catch (err) {
|
|
742
|
+
noteBinanceError(err);
|
|
743
|
+
logger.warn(TAG, `queryAlgoOrderProof(${clientAlgoId}) → null/unknown (NOT a verdict): ${formatError(err)}`);
|
|
744
|
+
return null;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
685
747
|
/** Fetch historical fills (trades) for a symbol via GET /fapi/v1/userTrades.
|
|
686
748
|
* Used by the REST gap-filler (rest-gap-filler.ts) to backfill any fills
|
|
687
749
|
* that landed during a WS blind window — when the user-data stream was
|
|
@@ -831,6 +893,9 @@ export class BinancePrivateApi {
|
|
|
831
893
|
timestamp: raw.timestamp ?? Date.now(),
|
|
832
894
|
datetime: raw.datetime ?? new Date().toISOString(),
|
|
833
895
|
timeInForce: raw.timeInForce ?? 'GTC',
|
|
896
|
+
...(typeof raw.clientOrderId === 'string' && raw.clientOrderId.length > 0
|
|
897
|
+
? { clientOrderId: raw.clientOrderId }
|
|
898
|
+
: {}),
|
|
834
899
|
};
|
|
835
900
|
}
|
|
836
901
|
/** Fetch a single order by ID. Used for fill polling and idempotency checks. */
|
|
@@ -871,39 +936,84 @@ export class BinancePrivateApi {
|
|
|
871
936
|
* after network timeouts — check if the order went through before retrying.
|
|
872
937
|
*/
|
|
873
938
|
async fetchOrderByClientId(clientOrderId, symbol) {
|
|
939
|
+
const resolution = await this.resolveOrderByClientId(clientOrderId, symbol);
|
|
940
|
+
return resolution.status === 'found' ? resolution.order : null;
|
|
941
|
+
}
|
|
942
|
+
/** Resolve a deterministic client id without treating read failures as absence. */
|
|
943
|
+
async resolveOrderByClientId(clientOrderId, symbol) {
|
|
874
944
|
try {
|
|
875
|
-
//
|
|
876
|
-
//
|
|
877
|
-
// resubmit. Accepted tradeoff — extending the IP ban for everyone is
|
|
878
|
-
// worse, and the resubmit path is itself reduce-only/bounded.
|
|
945
|
+
// Never hammer Binance during a ban. A blocked read is caught below as
|
|
946
|
+
// UNKNOWN, so it can never authorize a resubmission.
|
|
879
947
|
assertNotBanned('fetchOrder');
|
|
880
948
|
const raw = await this.exchange.fetchOrder(undefined, symbol, {
|
|
881
949
|
origClientOrderId: clientOrderId,
|
|
882
950
|
});
|
|
883
951
|
noteSuccess();
|
|
952
|
+
const canonicalSymbol = (value) => value.toUpperCase().replace(/[^A-Z0-9]/g, '').replace(/USDTUSDT$/, 'USDT');
|
|
953
|
+
const rawId = raw?.id === undefined || raw?.id === null ? '' : String(raw.id);
|
|
954
|
+
const amount = raw?.amount;
|
|
955
|
+
const filled = raw?.filled;
|
|
956
|
+
const remaining = raw?.remaining;
|
|
957
|
+
if (!raw
|
|
958
|
+
|| rawId.length === 0
|
|
959
|
+
|| rawId.length > 512
|
|
960
|
+
|| rawId.trim() !== rawId
|
|
961
|
+
|| raw.clientOrderId !== clientOrderId
|
|
962
|
+
|| typeof raw.symbol !== 'string'
|
|
963
|
+
|| raw.symbol.length === 0
|
|
964
|
+
|| canonicalSymbol(raw.symbol) !== canonicalSymbol(symbol)
|
|
965
|
+
|| (raw.side !== 'buy' && raw.side !== 'sell')
|
|
966
|
+
|| (raw.type !== 'market' && raw.type !== 'limit')
|
|
967
|
+
|| (raw.status !== 'open' && raw.status !== 'closed' && raw.status !== 'canceled')
|
|
968
|
+
|| typeof amount !== 'number'
|
|
969
|
+
|| !Number.isFinite(amount)
|
|
970
|
+
|| amount <= 0
|
|
971
|
+
|| typeof filled !== 'number'
|
|
972
|
+
|| !Number.isFinite(filled)
|
|
973
|
+
|| filled < 0
|
|
974
|
+
|| filled > amount + 1e-9 * Math.max(1, amount)
|
|
975
|
+
|| typeof remaining !== 'number'
|
|
976
|
+
|| !Number.isFinite(remaining)
|
|
977
|
+
|| remaining < 0
|
|
978
|
+
|| remaining > amount + 1e-9 * Math.max(1, amount)) {
|
|
979
|
+
return { status: 'unknown', detail: 'exchange returned a malformed client-order lookup response' };
|
|
980
|
+
}
|
|
884
981
|
return {
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
982
|
+
status: 'found',
|
|
983
|
+
order: {
|
|
984
|
+
id: rawId,
|
|
985
|
+
symbol: raw.symbol,
|
|
986
|
+
side: raw.side,
|
|
987
|
+
type: raw.type,
|
|
988
|
+
status: raw.status,
|
|
989
|
+
amount,
|
|
990
|
+
filled,
|
|
991
|
+
remaining,
|
|
992
|
+
average: raw.average ?? null,
|
|
993
|
+
price: raw.price ?? null,
|
|
994
|
+
cost: raw.cost ?? 0,
|
|
995
|
+
fee: raw.fee ?? { cost: 0, currency: 'USDT' },
|
|
996
|
+
timestamp: raw.timestamp ?? Date.now(),
|
|
997
|
+
datetime: raw.datetime ?? new Date().toISOString(),
|
|
998
|
+
timeInForce: raw.timeInForce ?? 'GTC',
|
|
999
|
+
clientOrderId: raw.clientOrderId,
|
|
1000
|
+
...(raw.info && typeof raw.info === 'object' ? { info: raw.info } : {}),
|
|
1001
|
+
},
|
|
900
1002
|
};
|
|
901
1003
|
}
|
|
902
1004
|
catch (err) {
|
|
903
1005
|
noteBinanceError(err);
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
1006
|
+
const candidate = err;
|
|
1007
|
+
const message = formatError(err);
|
|
1008
|
+
const messageCode = message.match(/"code"\s*:\s*(-?\d+)/)?.[1];
|
|
1009
|
+
const directCode = typeof candidate?.code === 'number' ? candidate.code : undefined;
|
|
1010
|
+
const code = directCode ?? (messageCode ? Number(messageCode) : undefined);
|
|
1011
|
+
if (code === -2013) {
|
|
1012
|
+
logger.info(TAG, `resolveOrderByClientId(${clientOrderId}) confirmed absent (-2013)`);
|
|
1013
|
+
return { status: 'confirmed_absent' };
|
|
1014
|
+
}
|
|
1015
|
+
logger.warn(TAG, `resolveOrderByClientId(${clientOrderId}) outcome unknown: ${message}`);
|
|
1016
|
+
return { status: 'unknown', detail: message };
|
|
907
1017
|
}
|
|
908
1018
|
}
|
|
909
1019
|
/** Cancel a real order on the exchange. Binance Futures splits orders across
|
|
@@ -40,6 +40,12 @@ export interface PluginConfigFile {
|
|
|
40
40
|
* carry `venue` through or it resets to the binance default. */
|
|
41
41
|
exchange?: ExchangeConfig;
|
|
42
42
|
tradingMode?: TradingMode;
|
|
43
|
+
/** Hyperliquid-specific knobs (Phase 3). `marketSlippagePct` bounds the IOC
|
|
44
|
+
* "market" order — HL has no native market order, and ccxt's 5% default is far
|
|
45
|
+
* too loose to ever rely on. Clamped to ≤2% adapter-side. */
|
|
46
|
+
hl?: {
|
|
47
|
+
marketSlippagePct?: number;
|
|
48
|
+
};
|
|
43
49
|
microLive?: {
|
|
44
50
|
sizeCapPercent?: number;
|
|
45
51
|
maxPositionUSDT?: number;
|
package/config/tool-gate.js
CHANGED
|
@@ -17,6 +17,9 @@ export const UNGOVERNABLE_TOOLS = new Set([
|
|
|
17
17
|
// Core safety floor — protecting/exiting positions and the review capture.
|
|
18
18
|
'create_order',
|
|
19
19
|
'close_position',
|
|
20
|
+
// Reversal capabilities for existing Wave 9 positions come only from this
|
|
21
|
+
// status path, so central tool preferences must never disable it.
|
|
22
|
+
'get_wave9_status',
|
|
20
23
|
'modify_stop',
|
|
21
24
|
'attach_brackets',
|
|
22
25
|
'audit_bracket_protection',
|
package/exchange-adapter.d.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import type { CcxtOrder, CcxtBalance, CcxtPosition, TradingMode } from './types.js';
|
|
2
2
|
import type { PositionMetadata, CloseReason } from './simulator/types.js';
|
|
3
|
+
/** Deterministic client-order lookup used after an outcome-ambiguous submit. */
|
|
4
|
+
export type ClientOrderResolution = {
|
|
5
|
+
status: 'found';
|
|
6
|
+
order: CcxtOrder;
|
|
7
|
+
} | {
|
|
8
|
+
status: 'confirmed_absent';
|
|
9
|
+
} | {
|
|
10
|
+
status: 'unknown';
|
|
11
|
+
detail: string;
|
|
12
|
+
};
|
|
3
13
|
/** Adapter readiness state machine: INIT_PENDING → READY | DEGRADED | BLOCKED */
|
|
4
14
|
export type AdapterReadiness = 'INIT_PENDING' | 'READY' | 'DEGRADED' | 'BLOCKED';
|
|
5
15
|
/** Options for order submission. */
|
|
@@ -42,6 +52,12 @@ export interface IExchangeAdapter {
|
|
|
42
52
|
getPositionsOrNull(symbol?: string): Promise<CcxtPosition[] | null>;
|
|
43
53
|
getOpenOrders(symbol?: string): Promise<CcxtOrder[]>;
|
|
44
54
|
fetchOrder(orderId: string, symbol?: string): Promise<CcxtOrder | null>;
|
|
55
|
+
/**
|
|
56
|
+
* A null-style fetch is unsafe for entry recovery because network/auth/rate
|
|
57
|
+
* failures are not proof an order was absent. Live adapters expose this
|
|
58
|
+
* tri-state resolver; paper adapters may omit it.
|
|
59
|
+
*/
|
|
60
|
+
resolveOrderByClientId?(clientOrderId: string, symbol: string): Promise<ClientOrderResolution>;
|
|
45
61
|
getLastPrice(symbol: string): Promise<number | null>;
|
|
46
62
|
readonly readiness: AdapterReadiness;
|
|
47
63
|
readonly mode: TradingMode;
|