@backtest/command-line
Version:
This project is a CLI build around Backtest, a library for trading developers
187 lines • 9.6 kB
JavaScript
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
;