@imbingox/acex 0.3.0-beta.2 → 0.3.0-beta.4

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.
@@ -0,0 +1,109 @@
1
+ import type {
2
+ MarketAdapter,
3
+ PrivateUserDataAdapter,
4
+ } from "../adapters/types.ts";
5
+ import type {
6
+ VenueAccountCapabilities,
7
+ VenueCapabilities,
8
+ VenueMarketCapabilities,
9
+ VenueOrderCapabilities,
10
+ } from "../types/client.ts";
11
+ import { SUPPORTED_VENUES, type Venue } from "../types/shared.ts";
12
+
13
+ const unsupportedAccount: VenueAccountCapabilities = {
14
+ register: "unsupported",
15
+ snapshot: "unsupported",
16
+ updates: "unsupported",
17
+ balances: "unsupported",
18
+ positions: "unsupported",
19
+ risk: "unsupported",
20
+ lending: "unsupported",
21
+ credentialsRequired: false,
22
+ };
23
+
24
+ const unsupportedOrder: Omit<VenueOrderCapabilities, "reason"> = {
25
+ supported: false,
26
+ openOrders: "unsupported",
27
+ updates: "unsupported",
28
+ create: "unsupported",
29
+ cancel: "unsupported",
30
+ cancelAll: "unsupported",
31
+ orderTypes: [],
32
+ timeInForce: [],
33
+ postOnly: false,
34
+ reduceOnly: false,
35
+ positionSide: "unsupported",
36
+ clientOrderId: false,
37
+ };
38
+
39
+ const typeOnlyNotes = [
40
+ "Venue is declared in public types but has no runtime adapter yet.",
41
+ ];
42
+
43
+ const unsupportedMarket: VenueMarketCapabilities = {
44
+ catalog: "unsupported",
45
+ l1Book: "unsupported",
46
+ fundingRate: "unsupported",
47
+ marketTypes: [],
48
+ };
49
+
50
+ export interface VenueCapabilityAdapterRegistry {
51
+ marketAdapters: ReadonlyMap<Venue, MarketAdapter>;
52
+ privateAdapters: ReadonlyMap<Venue, PrivateUserDataAdapter>;
53
+ }
54
+
55
+ export function getVenueCapabilitiesSnapshot(
56
+ venue: Venue,
57
+ registry: VenueCapabilityAdapterRegistry,
58
+ ): VenueCapabilities {
59
+ const marketAdapter = registry.marketAdapters.get(venue);
60
+ const privateAdapter = registry.privateAdapters.get(venue);
61
+
62
+ return cloneVenueCapabilities({
63
+ venue,
64
+ runtimeStatus: marketAdapter || privateAdapter ? "available" : "type_only",
65
+ readOnly: privateAdapter?.readOnly ?? false,
66
+ notes:
67
+ privateAdapter?.notes ??
68
+ (marketAdapter
69
+ ? [
70
+ "Capabilities describe the current SDK runtime, not the venue's full API surface.",
71
+ ]
72
+ : typeOnlyNotes),
73
+ market: marketAdapter?.marketCapabilities ?? unsupportedMarket,
74
+ account: privateAdapter?.accountCapabilities ?? unsupportedAccount,
75
+ order: privateAdapter?.orderCapabilities ?? {
76
+ ...unsupportedOrder,
77
+ reason: "not_implemented",
78
+ },
79
+ });
80
+ }
81
+
82
+ export function listVenueCapabilitiesSnapshots(
83
+ registry: VenueCapabilityAdapterRegistry,
84
+ ): VenueCapabilities[] {
85
+ return SUPPORTED_VENUES.map((venue) =>
86
+ getVenueCapabilitiesSnapshot(venue, registry),
87
+ );
88
+ }
89
+
90
+ function cloneVenueCapabilities(
91
+ capabilities: VenueCapabilities,
92
+ ): VenueCapabilities {
93
+ return {
94
+ ...capabilities,
95
+ notes: [...capabilities.notes],
96
+ market: {
97
+ ...capabilities.market,
98
+ marketTypes: [...capabilities.market.marketTypes],
99
+ },
100
+ account: {
101
+ ...capabilities.account,
102
+ },
103
+ order: {
104
+ ...capabilities.order,
105
+ orderTypes: [...capabilities.order.orderTypes],
106
+ timeInForce: [...capabilities.order.timeInForce],
107
+ },
108
+ };
109
+ }
@@ -277,6 +277,7 @@ export class AccountManagerImpl
277
277
  accountId: string,
278
278
  venue: Venue,
279
279
  update: RawAccountUpdate,
280
+ options: { preserveStatus?: boolean } = {},
280
281
  ): void {
281
282
  const record = this.getOrCreateRecord(accountId, venue);
282
283
  if (!record.subscribed) {
@@ -358,16 +359,24 @@ export class AccountManagerImpl
358
359
  receivedAt: update.receivedAt,
359
360
  updatedAt: update.receivedAt,
360
361
  };
361
- record.status = {
362
- ...record.status,
363
- activity: "active",
364
- ready: true,
365
- runtimeStatus: "healthy",
366
- reason: undefined,
367
- lastReceivedAt: update.receivedAt,
368
- lastReadyAt: update.receivedAt,
369
- inactiveSince: undefined,
370
- };
362
+ record.status = options.preserveStatus
363
+ ? {
364
+ ...record.status,
365
+ activity: "active",
366
+ lastReceivedAt: update.receivedAt,
367
+ lastReadyAt: record.status.lastReadyAt ?? update.receivedAt,
368
+ inactiveSince: undefined,
369
+ }
370
+ : {
371
+ ...record.status,
372
+ activity: "active",
373
+ ready: true,
374
+ runtimeStatus: "healthy",
375
+ reason: undefined,
376
+ lastReceivedAt: update.receivedAt,
377
+ lastReadyAt: update.receivedAt,
378
+ inactiveSince: undefined,
379
+ };
371
380
  this.publishStatus(record);
372
381
  }
373
382
 
@@ -588,6 +597,10 @@ export class AccountManagerImpl
588
597
  input.riskRatio === undefined
589
598
  ? previous?.riskRatio
590
599
  : new BigNumber(input.riskRatio),
600
+ actualLeverage:
601
+ input.actualLeverage === undefined
602
+ ? previous?.actualLeverage
603
+ : new BigNumber(input.actualLeverage),
591
604
  initialMargin:
592
605
  input.initialMargin === undefined
593
606
  ? previous?.initialMargin
@@ -93,6 +93,7 @@ export interface RiskSnapshot {
93
93
  venue: Venue;
94
94
  equity?: BigNumber;
95
95
  riskRatio?: BigNumber;
96
+ actualLeverage?: BigNumber;
96
97
  initialMargin?: BigNumber;
97
98
  maintenanceMargin?: BigNumber;
98
99
  exchangeTs?: number;
@@ -7,8 +7,10 @@ import type {
7
7
  MarketDataStatus,
8
8
  MarketManager,
9
9
  MarketStatusChangedEvent,
10
+ MarketType,
10
11
  } from "./market.ts";
11
12
  import type {
13
+ CreateOrderType,
12
14
  OrderDataStatus,
13
15
  OrderManager,
14
16
  OrderStatusChangedEvent,
@@ -56,6 +58,73 @@ export interface ClientEventStreams {
56
58
  errors(): AsyncIterable<AcexInternalError>;
57
59
  }
58
60
 
61
+ export type VenueRuntimeStatus = "available" | "type_only" | "reserved";
62
+
63
+ export type VenueCapabilitySupport = "supported" | "unsupported";
64
+
65
+ export type VenueCapabilityReason =
66
+ | "not_implemented"
67
+ | "read_only"
68
+ | "market_type_unsupported"
69
+ | "sdk_reserved";
70
+
71
+ export type FundingRateCapability = VenueCapabilitySupport | "market_dependent";
72
+
73
+ export type PrivateUpdateCapability = "websocket" | "polling" | "unsupported";
74
+
75
+ export type CancelAllOrdersCapability = "symbol" | "account" | "unsupported";
76
+
77
+ export type PositionSideCapability =
78
+ | "optional"
79
+ | "required_for_hedge"
80
+ | "unsupported";
81
+
82
+ export type OrderTimeInForceCapability = "gtc" | "post_only";
83
+
84
+ export interface VenueMarketCapabilities {
85
+ catalog: VenueCapabilitySupport;
86
+ l1Book: VenueCapabilitySupport;
87
+ fundingRate: FundingRateCapability;
88
+ marketTypes: MarketType[];
89
+ }
90
+
91
+ export interface VenueAccountCapabilities {
92
+ register: VenueCapabilitySupport;
93
+ snapshot: VenueCapabilitySupport;
94
+ updates: PrivateUpdateCapability;
95
+ balances: VenueCapabilitySupport;
96
+ positions: VenueCapabilitySupport;
97
+ risk: VenueCapabilitySupport;
98
+ lending: VenueCapabilitySupport;
99
+ credentialsRequired: boolean;
100
+ }
101
+
102
+ export interface VenueOrderCapabilities {
103
+ supported: boolean;
104
+ openOrders: VenueCapabilitySupport;
105
+ updates: PrivateUpdateCapability;
106
+ create: VenueCapabilitySupport;
107
+ cancel: VenueCapabilitySupport;
108
+ cancelAll: CancelAllOrdersCapability;
109
+ orderTypes: CreateOrderType[];
110
+ timeInForce: OrderTimeInForceCapability[];
111
+ postOnly: boolean;
112
+ reduceOnly: boolean;
113
+ positionSide: PositionSideCapability;
114
+ clientOrderId: boolean;
115
+ reason?: VenueCapabilityReason;
116
+ }
117
+
118
+ export interface VenueCapabilities {
119
+ venue: Venue;
120
+ runtimeStatus: VenueRuntimeStatus;
121
+ readOnly: boolean;
122
+ notes: string[];
123
+ market: VenueMarketCapabilities;
124
+ account: VenueAccountCapabilities;
125
+ order: VenueOrderCapabilities;
126
+ }
127
+
59
128
  export interface AcexClient {
60
129
  readonly market: MarketManager;
61
130
  readonly account: AccountManager;
@@ -64,6 +133,8 @@ export interface AcexClient {
64
133
 
65
134
  getStatus(): ClientStatus;
66
135
  getHealth(): ClientHealthSnapshot;
136
+ getVenueCapabilities(venue: Venue): VenueCapabilities;
137
+ listVenueCapabilities(): VenueCapabilities[];
67
138
 
68
139
  registerAccount(input: RegisterAccountInput): Promise<RegisterAccountResult>;
69
140
  updateAccountCredentials(
@@ -36,6 +36,9 @@ export interface AccountRuntimeOptions {
36
36
  streamReconnectDelayMs?: number;
37
37
  streamReconnectMaxDelayMs?: number;
38
38
  listenKeyKeepAliveMs?: number;
39
+ binance?: {
40
+ riskPollIntervalMs?: number;
41
+ };
39
42
  juplend?: {
40
43
  pollIntervalMs?: number;
41
44
  };