From 0def64df077beb77d49be9d45d5540083baf96a5 Mon Sep 17 00:00:00 2001 From: bludnic Date: Fri, 10 May 2024 07:55:35 +0100 Subject: [PATCH] feat(cli): add stop command --- packages/cli/src/api/index.ts | 1 + packages/cli/src/api/stop-command.ts | 70 ++++++++++++++++++++++++++++ packages/cli/src/commands/stop.ts | 16 +++++++ packages/cli/src/index.ts | 2 + 4 files changed, 89 insertions(+) create mode 100644 packages/cli/src/api/stop-command.ts create mode 100644 packages/cli/src/commands/stop.ts diff --git a/packages/cli/src/api/index.ts b/packages/cli/src/api/index.ts index fc4e2a19..096e8166 100644 --- a/packages/cli/src/api/index.ts +++ b/packages/cli/src/api/index.ts @@ -1,3 +1,4 @@ export * from "./grid-lines"; export * from "./run-backtest"; export * from "./run-trading"; +export * from "./stop-command"; diff --git a/packages/cli/src/api/stop-command.ts b/packages/cli/src/api/stop-command.ts new file mode 100644 index 00000000..7693a16f --- /dev/null +++ b/packages/cli/src/api/stop-command.ts @@ -0,0 +1,70 @@ +import { templates } from "@opentrader/bot-templates"; +import { xprisma } from "@opentrader/db/dist"; +import { logger } from "@opentrader/logger"; +import { BotProcessing } from "@opentrader/processing"; +import type { CommandResult, ConfigName } from "../types"; +import { readBotConfig, readExchangesConfig } from "../config"; + +export async function stopCommand( + options: { + config: ConfigName; + }, +): Promise { + const config = readBotConfig(options.config); + logger.debug(config, "Parsed bot config"); + + const exchangesConfig = readExchangesConfig(options.config); + logger.debug(exchangesConfig, "Parsed exchanges config"); + + const bot = await xprisma.bot.custom.findUnique({ + where: { + label: config.label, + } + }); + + if (!bot) { + logger.info(`Bot "${config.label}" does not exists. Nothing to stop`); + + return { + result: undefined, + }; + } + + const strategyExists = bot.template in templates; + if (!strategyExists) { + const availableStrategies = Object.keys(templates).join(", "); + logger.info( + `Strategy "${bot.template}" does not exists. Available strategies: ${availableStrategies}`, + ); + + return { + result: undefined, + }; + } + + logger.info(`Processing stop command for bot "${bot.label}"...`); + await stopBot(bot.id); + logger.info(`Command stop processed successfully for bot "${bot.label}"`); + + return { + result: undefined, + }; +} + +async function stopBot(botId: number) { + const botProcessor = await BotProcessing.fromId(botId); + await botProcessor.processStopCommand(); + + await disableBot(botId); +} + +async function disableBot(botId: number) { + await xprisma.bot.custom.update({ + where: { + id: botId, + }, + data: { + enabled: false, + }, + }); +} diff --git a/packages/cli/src/commands/stop.ts b/packages/cli/src/commands/stop.ts new file mode 100644 index 00000000..a1cf6934 --- /dev/null +++ b/packages/cli/src/commands/stop.ts @@ -0,0 +1,16 @@ +import { Command, Option } from "commander"; +import { DEFAULT_CONFIG_NAME } from "../config"; +import { handle } from "../utils/command"; +import * as api from "../api"; + +export function addStopCommand(program: Command) { + program + .command("stop") + .description("Process stop command") + .addOption( + new Option("-c, --config ", "Config file").default( + DEFAULT_CONFIG_NAME, + ), + ) + .action(handle(api.stopCommand)); +} diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 0277a56d..55754028 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -1,4 +1,5 @@ import { Command } from "commander"; +import { addStopCommand } from "./commands/stop"; import { addBacktestCommand } from "./commands/backtest"; import { addGridLinesCommand } from "./commands/grid-lines"; import { addTradeCommand } from "./commands/trade"; @@ -13,5 +14,6 @@ program addBacktestCommand(program); addGridLinesCommand(program); addTradeCommand(program); +addStopCommand(program); program.parse();