-
Notifications
You must be signed in to change notification settings - Fork 50
/
Copy pathgrid-bot.ts
77 lines (67 loc) · 2.2 KB
/
grid-bot.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { z } from "zod";
import type { IExchange } from "@opentrader/exchanges";
import type { IBotConfiguration, SmartTradeService, TBotContext } from "@opentrader/bot-processor";
import { cancelSmartTrade, useExchange, useSmartTrade } from "@opentrader/bot-processor";
import { computeGridLevelsFromCurrentAssetPrice, decomposeSymbol } from "@opentrader/tools";
import type { IGetMarketPriceResponse } from "@opentrader/types";
import { logger } from "@opentrader/logger";
/**
* Advanced grid bot template.
* The template allows specifying grid lines with custom prices and quantities.
*/
export function* gridBot(ctx: TBotContext<GridBotConfig>) {
const { config: bot, onStart, onStop } = ctx;
const symbol = bot.symbol;
const { quoteCurrency } = decomposeSymbol(symbol);
const exchange: IExchange = yield useExchange();
let price = 0;
if (onStart) {
const { price: markPrice }: IGetMarketPriceResponse = yield exchange.getMarketPrice({
symbol,
});
price = markPrice;
logger.info(`[Grid] Bot strategy started on ${symbol} pair. Current price is ${price} ${quoteCurrency}`);
}
const gridLevels = computeGridLevelsFromCurrentAssetPrice(bot.settings.gridLines, price);
if (onStop) {
for (const [index, _grid] of gridLevels.entries()) {
yield cancelSmartTrade(`${index}`);
}
return;
}
for (const [index, grid] of gridLevels.entries()) {
const smartTrade: SmartTradeService = yield useSmartTrade(
{
buy: {
type: "Limit",
price: grid.buy.price,
status: grid.buy.status,
},
sell: {
type: "Limit",
price: grid.sell.price,
status: grid.sell.status,
},
quantity: grid.buy.quantity, // or grid.sell.quantity
},
`${index}`,
);
if (smartTrade.isCompleted()) {
yield smartTrade.replace();
}
}
}
gridBot.displayName = "Grid Bot Advanced";
gridBot.hidden = true;
gridBot.schema = z.object({
gridLines: z.array(
z.object({
price: z.number().positive(),
quantity: z.number().positive(),
}),
),
});
gridBot.runPolicy = {
onOrderFilled: true,
};
export type GridBotConfig = IBotConfiguration<z.infer<typeof gridBot.schema>>;