UNPKG

@backtest/command-line

Version:

This project is a CLI build around Backtest, a library for trading developers

187 lines 9.6 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.runStrategyPortal = runStrategyPortal; const portals_1 = require("../../helpers/portals"); const parse_1 = require("../../helpers/parse"); const colors_1 = require("../../infra/colors"); const headers_1 = require("../../infra/headers"); const run_results_1 = require("../results/run-results"); const run_results_multi_1 = require("../results/run-results-multi"); const framework_1 = require("@backtest/framework"); function runStrategyPortal(runFast) { return __awaiter(this, void 0, void 0, function* () { console.clear(); let back = false; let valid = false; let portalReturn = { error: false, data: '' }; let runParams = { strategyName: '', historicalData: [], startingAmount: 0, startTime: 0, endTime: 0, params: {}, percentFee: 0, percentSlippage: 0 }; while (!back) { const strategyNames = yield (0, framework_1.findStrategyNames)(); if (!(strategyNames === null || strategyNames === void 0 ? void 0 : strategyNames.length)) return { error: true, data: 'There are no saved strategies' }; let choicesStrategy = strategyNames; choicesStrategy.push((0, colors_1.colorBack)('👈 Back')); (0, headers_1.headerRunStrategy)(); runParams.strategyName = yield (0, portals_1.interactCLI)({ type: 'autocomplete', message: 'Choose a strategy to run:', choices: choicesStrategy }); if (runParams.strategyName.includes('👈')) return { error: false, data: '' }; const historicalNames = yield (0, framework_1.findHistoricalDataNames)(); if (!(historicalNames === null || historicalNames === void 0 ? void 0 : historicalNames.length)) return { error: true, data: 'There are no saved candles' }; let choiceHistoricalData = []; while (choiceHistoricalData.length === 0) { choiceHistoricalData = yield (0, portals_1.interactCLI)({ type: 'checkbox', message: 'Choose which candle(s) set to run on:', choices: historicalNames }); } for (let i = 0; i < choiceHistoricalData.length; i++) { for (let j = 0; j < historicalNames.length; j++) { if (choiceHistoricalData[i] === historicalNames[j]) { //@ts-ignore runParams.historicalData.push(historicalNames[j]); break; } } } const isMultiSymbol = runParams.historicalData.length > 1; const historicalData = yield (0, framework_1.findHistoricalData)(runParams.historicalData[0]); const metaDataStrategy = yield (0, framework_1.findStrategy)(runParams.strategyName); if (!historicalData) { return { error: true, data: `There are no historical data for ${runParams.historicalData[0]}` }; } let paramsCache = {}; for (let i = 0; i < metaDataStrategy.params.length; i++) { let param = yield (0, portals_1.interactCLI)({ type: 'input', message: metaDataStrategy.params[i] }); if (param === undefined || param === '') param = 0; paramsCache[metaDataStrategy.params[i]] = isNaN(+param) ? param : +param; } if (metaDataStrategy.dynamicParams) { let doneWithParams = false; while (!doneWithParams) { const addParam = yield (0, portals_1.interactCLI)({ type: 'autocomplete', message: 'Add a param:', choices: ['Yes', 'No'] }); if (addParam === 'Yes') { let paramName = yield (0, portals_1.interactCLI)({ type: 'input', message: 'Param name:' }); let param = yield (0, portals_1.interactCLI)({ type: 'input', message: paramName }); if (param === undefined || param === '') param = 0; paramsCache[paramName] = isNaN(+param) ? param : +param; } else doneWithParams = true; } } runParams.params = paramsCache; if (!runFast) { if (!isMultiSymbol) { while (!valid) { const startTimeInput = yield (0, portals_1.interactCLI)({ type: 'date', message: 'Start Date:', dateDefault: historicalData.startTime }); runParams.startTime = new Date(startTimeInput).getTime(); if (runParams.startTime < historicalData.startTime) console.log((0, colors_1.colorError)(`Date must be on or after ${(0, parse_1.dateToString)(historicalData.startTime)}`)); else if (runParams.startTime > historicalData.endTime) console.log((0, colors_1.colorError)(`Date must be on or before ${(0, parse_1.dateToString)(historicalData.endTime)}`)); else valid = true; } valid = false; while (!valid) { const endTimeInput = yield (0, portals_1.interactCLI)({ type: 'date', message: 'End Date:', dateDefault: historicalData.endTime }); runParams.endTime = new Date(endTimeInput).getTime(); if (runParams.endTime > historicalData.endTime) console.log((0, colors_1.colorError)(`Date must be on or before ${(0, parse_1.dateToString)(historicalData.endTime)}`)); else if (runParams.endTime <= runParams.startTime) console.log((0, colors_1.colorError)(`Date must be after your declared start time of ${(0, parse_1.dateToString)(runParams.startTime)}`)); else valid = true; } } else { runParams.startTime = historicalData.startTime; runParams.endTime = historicalData.endTime; } runParams.startingAmount = +(yield (0, portals_1.interactCLI)({ type: 'input', message: `Starting ${isMultiSymbol ? '' : historicalData.quote} amount:` })); const choiceFee = yield (0, portals_1.interactCLI)({ type: 'autocomplete', message: 'Add transaction fee or slippage:', choices: ['Yes', 'No'] }); if (choiceFee === 'Yes') { runParams.percentFee = +(yield (0, portals_1.interactCLI)({ type: 'input', message: 'Transaction Fee Percentage (0 for none):' })); runParams.percentSlippage = +(yield (0, portals_1.interactCLI)({ type: 'input', message: 'Slippage Percentage (0 for none):' })); } } else { runParams.startingAmount = 1000; runParams.startTime = historicalData.startTime; runParams.endTime = historicalData.endTime; } console.clear(); console.log((0, colors_1.colorMessage)(`Running ${runParams.strategyName} Strategy`)); const result = yield (0, framework_1.runStrategy)(runParams); console.log((0, colors_1.colorSuccess)(`Strategy ${runParams.strategyName} completed`)); if ('allOrders' in result && result.allOrders.length > 0) { portalReturn = yield (0, run_results_1.resultsPortal)(result, true); } else { portalReturn = yield (0, run_results_multi_1.resultsPortalMulti)(result, true); } } return portalReturn; }); } //# sourceMappingURL=run-strategy.js.map