@metaflux/fluxaction 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/package.json +5 -3
- package/scripts/futures.ts +80 -0
- package/scripts/spot.ts +84 -0
- package/src/FluxAction.ts +150 -0
- package/src/clients/GateClient.ts +52 -0
- package/src/core/exchange.ts +8 -0
- package/src/core/logicalOrders.ts +21 -7
- package/src/core/orders.ts +7 -0
- package/src/exchanges/gate/futures/GateFuturesAdapter.ts +301 -0
- package/src/exchanges/gate/index.ts +2 -0
- package/src/exchanges/gate/spot/GateSpotAdapter.ts +208 -0
- package/src/exchanges/gate/spot/gate.mapOrder.ts +22 -0
- package/src/index.ts +21 -126
- package/src/risk/ExitExecutor.ts +56 -0
- package/src/risk/OrderStore.ts +21 -0
- package/src/risk/RiskEngine.ts +101 -0
- package/src/risk/RiskScheduler.ts +23 -0
- package/src/services/ExchangeRegistry.ts +27 -0
- package/examples/main.ts +0 -77
- package/src/core/RiskManager.ts +0 -205
- package/src/core/results.ts +0 -20
- package/src/exchanges/GateSpotAdapter.ts +0 -193
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
import ccxt, { type gateio as GateCcxt } from 'ccxt'
|
|
2
|
-
import {
|
|
3
|
-
type ExchangeAdapter,
|
|
4
|
-
type ExchangeCapabilities,
|
|
5
|
-
type MarketInfo,
|
|
6
|
-
type OrderInfo,
|
|
7
|
-
type PositionInfo,
|
|
8
|
-
} from '../core/exchange'
|
|
9
|
-
|
|
10
|
-
export interface GateSpotAdapterConfig {
|
|
11
|
-
id: string
|
|
12
|
-
label?: string
|
|
13
|
-
apiKey: string
|
|
14
|
-
secret: string
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class GateSpotAdapter implements ExchangeAdapter {
|
|
18
|
-
readonly id: string
|
|
19
|
-
readonly label: string
|
|
20
|
-
readonly capabilities: ExchangeCapabilities
|
|
21
|
-
private ex: GateCcxt
|
|
22
|
-
|
|
23
|
-
constructor(cfg: GateSpotAdapterConfig) {
|
|
24
|
-
this.id = cfg.id
|
|
25
|
-
this.label = cfg.label ?? 'gate-spot'
|
|
26
|
-
|
|
27
|
-
this.ex = new ccxt.gateio({
|
|
28
|
-
apiKey: cfg.apiKey,
|
|
29
|
-
secret: cfg.secret,
|
|
30
|
-
enableRateLimit: true,
|
|
31
|
-
options: {
|
|
32
|
-
defaultType: 'spot',
|
|
33
|
-
createMarketBuyOrderRequiresPrice: false,
|
|
34
|
-
},
|
|
35
|
-
}) as GateCcxt
|
|
36
|
-
|
|
37
|
-
this.capabilities = {
|
|
38
|
-
spot: {
|
|
39
|
-
nativeTakeProfit: false,
|
|
40
|
-
nativeStopLoss: false,
|
|
41
|
-
nativeTrailingStop: false,
|
|
42
|
-
},
|
|
43
|
-
futures: {
|
|
44
|
-
nativeTakeProfit: false,
|
|
45
|
-
nativeStopLoss: false,
|
|
46
|
-
nativeTrailingStop: false,
|
|
47
|
-
},
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async loadMarkets(): Promise<void> {
|
|
52
|
-
await this.ex.loadMarkets()
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
hasSpotMarket(symbol: string): boolean {
|
|
56
|
-
const m = this.ex.markets?.[symbol]
|
|
57
|
-
return !!m && m.type === 'spot'
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
hasFuturesMarket(): boolean {
|
|
61
|
-
return false
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
getMarket(symbol: string): MarketInfo | undefined {
|
|
65
|
-
const m = this.ex.markets?.[symbol]
|
|
66
|
-
if (!m) return undefined
|
|
67
|
-
return {
|
|
68
|
-
symbol: m.symbol,
|
|
69
|
-
base: m.base,
|
|
70
|
-
quote: m.quote,
|
|
71
|
-
type: m.type as any,
|
|
72
|
-
precisionAmount: m.precision?.amount,
|
|
73
|
-
precisionPrice: m.precision?.price,
|
|
74
|
-
minCost: m.limits?.cost?.min,
|
|
75
|
-
minAmount: m.limits?.amount?.min,
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
private roundAmount(symbol: string, amount: number): number {
|
|
80
|
-
const m = this.ex.markets?.[symbol]
|
|
81
|
-
if (!m) return amount
|
|
82
|
-
return Number(this.ex.amountToPrecision(symbol, amount))
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
private roundPrice(symbol: string, price: number): number {
|
|
86
|
-
const m = this.ex.markets?.[symbol]
|
|
87
|
-
if (!m) return price
|
|
88
|
-
return Number(this.ex.priceToPrecision(symbol, price))
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
private mapOrder(symbol: string, o: any): OrderInfo {
|
|
92
|
-
const price = o.price ?? o.average ?? o.avgPrice
|
|
93
|
-
|
|
94
|
-
let baseAmount: number
|
|
95
|
-
if (price && o.cost) {
|
|
96
|
-
baseAmount = o.cost / price
|
|
97
|
-
} else if (price && o.amount) {
|
|
98
|
-
baseAmount = o.amount / price
|
|
99
|
-
} else if (typeof o.amount === 'number' && o.amount > 0) {
|
|
100
|
-
baseAmount = o.amount
|
|
101
|
-
} else {
|
|
102
|
-
baseAmount = 0
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return {
|
|
106
|
-
id: o.id,
|
|
107
|
-
symbol,
|
|
108
|
-
side: o.side,
|
|
109
|
-
type: o.type,
|
|
110
|
-
price,
|
|
111
|
-
amount: baseAmount,
|
|
112
|
-
status: o.status,
|
|
113
|
-
raw: o,
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
async fetchTicker(symbol: string): Promise<{ last: number }> {
|
|
118
|
-
const t = await this.ex.fetchTicker(symbol)
|
|
119
|
-
return { last: t.last ?? 0 }
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
async fetchBalance() {
|
|
123
|
-
const bal = await this.ex.fetchBalance()
|
|
124
|
-
return bal as any
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async fetchOpenOrders(symbol?: string): Promise<OrderInfo[]> {
|
|
128
|
-
const orders = await this.ex.fetchOpenOrders(symbol)
|
|
129
|
-
return orders.map((o: any) => this.mapOrder(o.symbol, o))
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
async cancelOrder(symbol: string, orderId: string): Promise<void> {
|
|
133
|
-
await this.ex.cancelOrder(orderId, symbol)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
async marketBuySpot(symbol: string, quoteCost: number): Promise<OrderInfo> {
|
|
137
|
-
const ticker = await this.fetchTicker(symbol)
|
|
138
|
-
if (!ticker.last || ticker.last <= 0) {
|
|
139
|
-
throw new Error(`gate-spot invalid price for ${symbol}: ${ticker.last}`)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const m = this.getMarket(symbol)
|
|
143
|
-
if (m?.minCost && quoteCost < m.minCost) {
|
|
144
|
-
throw new Error(
|
|
145
|
-
`gate-spot buy violates minCost: ${quoteCost} < ${m.minCost} ${m.quote}`,
|
|
146
|
-
)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const order = await this.ex.createMarketBuyOrderWithCost(symbol, quoteCost, {
|
|
150
|
-
createMarketBuyOrderRequiresPrice: false,
|
|
151
|
-
})
|
|
152
|
-
return this.mapOrder(symbol, order)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
async marketSellSpot(symbol: string, baseAmount: number): Promise<OrderInfo> {
|
|
156
|
-
const amount = this.roundAmount(symbol, baseAmount)
|
|
157
|
-
if (!amount || amount <= 0) {
|
|
158
|
-
throw new Error(`gate-spot sell amount too small for ${symbol}: ${amount}`)
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const order = await this.ex.createOrder(symbol, 'market', 'sell', amount)
|
|
162
|
-
return this.mapOrder(symbol, order)
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
async limitOrderSpot(
|
|
166
|
-
symbol: string,
|
|
167
|
-
side: 'buy' | 'sell',
|
|
168
|
-
baseAmount: number,
|
|
169
|
-
price: number,
|
|
170
|
-
): Promise<OrderInfo> {
|
|
171
|
-
const amount = this.roundAmount(symbol, baseAmount)
|
|
172
|
-
const p = this.roundPrice(symbol, price)
|
|
173
|
-
|
|
174
|
-
if (!amount || amount <= 0) {
|
|
175
|
-
throw new Error(`gate-spot limit amount too small for ${symbol}: ${amount}`)
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const order = await this.ex.createOrder(symbol, 'limit', side, amount, p)
|
|
179
|
-
return this.mapOrder(symbol, order)
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
async openFutures(): Promise<OrderInfo> {
|
|
183
|
-
throw new Error('gate-spot: futures not supported')
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
async closeFutures(): Promise<OrderInfo> {
|
|
187
|
-
throw new Error('gate-spot: futures not supported')
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
async fetchPositions(): Promise<PositionInfo[]> {
|
|
191
|
-
return []
|
|
192
|
-
}
|
|
193
|
-
}
|