
Security News
pnpm 11.5 Adds Support for Recognizing npm Staged Publishes
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.
@backtest/command-line
Advanced tools
This project is a CLI build around Backtest, a library for trading developers
Enhance your trading strategies with Backtest, the leading CLI tool crafted for trading developers. Leverage the power of TypeScript (or JavaScript) to backtest your strategies with unmatched precision, efficiency, and flexibility.
TL;DR If you are unaware of the original project, you probably don’t need to read further unless you’re curious.
If you’re wondering why there are two similar repositories (this one and the one you can find here), the answer is simple: Andrew’s is the original platform, and it’s well-made, but it hasn’t been updated for a while. While waiting for the author to resume work on it, I decided to create an updated and maintained version. The original license allows this (at least it seems clear to me), and we don’t intend to change the license in the future. The basic idea is to keep this product updated and add some features over time. So far, we’ve added what we needed, which includes:
🌀 Scan Trading Strategies);.ts file. Then, by restarting the strategy from the CLI, even from an already running process, the new version is used;properties inside strategy file .ts. This greatly helps in adding or proliferating strategies; just rescan and you’re done;Node v18 or higher (for this, we removed tulind and added technicalindicators, although both are old and tulind is undoubtedly a great choice. If you need it, you can still add it back in the fork).What might come or be requested (f.e.):
Assumptions for the future:
Intuitive CLI Interface: User-friendly command-line interface for smooth operation.
Comprehensive Candle Data: Access historical candle data from Binance or effortlessly import your own CSV files.
Integrated Storage: Efficiently store your candle data, strategies, and results in the internal SQLite storage.
Documentation: Maximize Backtest’s capabilities with thorough guides and resources.
Follow these instructions to setup the environment:
git clone git@github.com:backtestjs/command-line.git backtest-cli
cd backtest-cli
npm install
When you run the project for the first time, you need to set up the database. Follow these steps:
npx prisma validatenpx prisma generatenpx prisma db pushThese commands ensure that your project is properly configured and ready to use.
Note: If you are not familiar with Prisma and the commands above, you can use npm run align-db to align the schema with the database.
npm run align-db
Start strategic backtesting with a single command:
npm run dev # main.ts
npm run start # dist/main.js
Explore the Backtest universe with our Full Documentation. Discover tutorials, video guides, and extensive examples.
Easily download candle data from Binance or import it from a CSV file for strategy execution. Additionally, you can export your data to a CSV file via the CLI with just a few clicks. No coding or API key is required (thanks Binance!).
In addition to the demonstration strategies already present, you can create your own by adding a file under src/strategies.
Use one of the existing files or the examples in this guide as a reference. Each file should contain a runStrategy method, and if it uses external or dynamic parameters, it should also include a properly filled-out properties structure.
Whenever you create a new strategy, modify the properties structure of an existing one, or delete an existing strategy, you need to run the 🌀 Scan Trading Strategies CLI command.
There’s no need to stop or restart the backtest process if it’s running, or to exit the program. The program will reload the contents of your file with each launch, as long as it’s synchronized.
Using well-defined or dynamic parameters (instead of constants within your strategy) will allow you to run multiple tests simultaneously.
Each candle have the following information available:
export interface Candle {
openTime: number
open: number
high: number
low: number
close: number
volume: number
closeTime: number
assetVolume: number
numberOfTrades: number
}
It is possible to execute a buy or sell by following this:
export interface BuySell {
price?: number // Price of which you will trade the asset
position?: string // Can be "short" or "long" (long is the default)
amount?: number | string // Amount of asset to buy can be number or string (string must include a %), f.e. 300 or "10%"
baseAmount?: number // Trade the base amount to use for percentage calculations (total worth for baseAmount equals to amount)
stopLoss?: number // Price of which a stop loss will trigger (all will be sold on the stop loss)
takeProfit?: number // Price of which a take profit will trigger (all will be sold on the take profit price)
percentFee?: number
percentSlippage?: number //
note?: string // Add a simple note to identify this trade
}
Pay attention: follow these rules:
In particular, the buy signal:
bth.buy()
/* or */
await bth.buy({
position: 'short',
amount: '10%', // or baseAmount
note: 'a simple note here',
stopLoss: stopLoss,
percentSlippage: percentSlippage,
percentFee: percentFee
})
while the sell signal:
bth.sell()
/* or */
await bth.sell({
amount: 250, // or baseAmount
note: 'a simple note here'
})
// Lets say you have $1000 and want to trade bitcoin
// Put in a long order and buy all which is $1000 worth of bitcoin
await buy()
// Lets say you bought bitcoin and are now worth $1000
// Put in a sell order and sell all which is $1000 worth of bitcoin
await sell()
// Lets say you have $1000 and want to trade bitcoin
// Put in a long order of $400 worth of bitcoin
await buy({ amount: 400 })
// Same thing can be achieved here
await buy({ amount: '40%' })
// Lets say you bought bitcoin and are now worth $1000 in bitcoin and put in a sell order of $400 worth of bitcoin
await sell({ amount: 400 })
// Same thing can be achieved here
await sell({ amount: '40%' })
// Lets say you have $1000 and want to trade bitcoin
// Put a short order in with all which is $1000 and a stop loss at $24,000
await buy({ position: "short", stopLoss: 24000 })
// The application is smart enough to know that its a short and only sell if a candles high goes above $24,000
// Lets say you bought bitcoin in a long and a short but only want to sell some of the shorted amount
// Put in a sell order to sell 50% of the shorted amount
await sell({ position: "short", amount "50%"})
// Lets say you have $1000 and bitcoin is currently worth $2000
// Put a long order in of .25 bitcoin which is $500 worth
await buy({ baseAmount: 0.25 })
// This can also be achieved by doing
await buy({ amount: 500 })
// You cannot use amount with baseAmount in the same buy / sell call
// Lets say you bought bitcoin and are worth $1000 and bitcoin is worth $2000
// Put a short order in of .25 bitcoin which is $500 worth
await sell({ baseAmount: 0.25 })
// This can also be achieved by doing
await sell({ amount: 500 })
// Lets say you have $1000 and bitcoins close was $2100 but you had a trigger to buy at $2000
// Put a long order in of $1000 worth but bitcoin at a price of $2000
await buy({ price: 2000 })
// Lets say you bought and bitcoin is worth $2200 but you had a trigger to sell at $2100
// Put a sell order in where bitcoin is worth $2100
await sell({ price: 2100 })
Below is an example of a simple 3 over 45 SMA strategy. You buy once the 3 crosses the 45 and sell otherwise. In this example, we don’t use the power of params.
import { BTH } from '@backtest/framework'
import { indicatorSMA } from '../indicators/moving-averages'
export async function runStrategy(bth: BTH) {
const lowSMACandles = await bth.getCandles('close', 0, 3)
const highSMACandles = await bth.getCandles('close', 0, 45)
// Calculate low and high SMA
const lowSMA = await indicatorSMA(lowSMACandles, 3)
const highSMA = await indicatorSMA(highSMACandles, 45)
// Buy if lowSMA crosses over the highSMA
if (lowSMA > highSMA) {
await bth.buy()
}
// Sell if lowSMA crosses under the highSMA
else {
await bth.sell()
}
}
Pay attention: hard-coded parameters will prevent you from running multiple tests simultaneously!
Below is an example of a simple SMA strategy like above but it’s not hard-coded to the 3 over 45. When you run the strategy through the CLI, you will be asked to provide a low and high SMA. You can even provide multiple lows and multiple highs, and all the variations will be tested in one run.
import { BTH } from '@backtest/framework'
import { indicatorSMA } from '../indicators/moving-averages'
export const properties = {
params: ['lowSMA', 'highSMA'],
dynamicParams: false
}
export async function runStrategy(bth: BTH) {
const lowSMAInput = bth.params.lowSMA
const highSMAInput = bth.params.highSMA
// Get last candles
const lowSMACandles = await bth.getCandles('close', 0, lowSMAInput)
const highSMACandles = await bth.getCandles('close', 0, highSMAInput)
// Calculate low and high SMA
const lowSMA = await indicatorSMA(lowSMACandles, lowSMAInput)
const highSMA = await indicatorSMA(highSMACandles, highSMAInput)
// Buy if lowSMA crosses over the highSMA
if (lowSMA > highSMA) {
await bth.buy()
}
// Sell if lowSMA crosses under the highSMA
else {
await bth.sell()
}
}
BacktestJS not only delivers performance insights but also visualizes your strategy’s effectiveness through comprehensive charts and statistics.
Explore the visual representation of your trading outcomes, from income results to buy/sell locations, offering you a clear view of your strategy’s performance.








Examine permutation results and heatmap visualizations to refine your strategies across different values all in one run.





See if that killer strategy works across the board on many symbols and timeframes with ease. Get all your results in one shot with blazing fast results.



Although there is an option to download data from binance for crypto assets there is no automatic download available for traditional symbols such as apple or tesla stock as well as forex symbols such as usdyen.
This candle data can be downloaded from third party sites such as yahoo finance and can then be easily imported to the Backtest database to use with any strategy.
The CSV file must have the following fields:
The CSV file can have the following optional fields:
Pay attention: follow these rules:
The original project is currently on hold. However, thanks to the permissive license, we aim to continue the author’s work. We express our gratitude and recognition for creating a usable product under a license that allows for external adoption and support.
FAQs
This project is a CLI build around Backtest, a library for trading developers
The npm package @backtest/command-line receives a total of 29 weekly downloads. As such, @backtest/command-line popularity was classified as not popular.
We found that @backtest/command-line demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.

Security News
Federal audit finds NIST lacked a plan to clear the NVD backlog, wasted funds on duplicate work, and delayed use of CISA data.

Research
/Security News
A mini Shai-Hulud campaign compromised Red Hat Cloud Services npm packages to steal developer and CI/CD secrets during installation.