### Install @backtest/framework using npm Source: https://github.com/backtestjs/framework/blob/main/docs/QUICK_START.md Install the @backtest/framework package into your project using npm. This is the first step to using the backtesting framework. ```bash npm i @backtest/framework ``` -------------------------------- ### Basic Trading Strategy Example in TypeScript Source: https://github.com/backtestjs/framework/blob/main/docs/QUICK_START.md A simple trading strategy using the @backtest/framework. It defines start and finish callbacks, and a runStrategy function that uses moving averages to decide on buy or sell actions. ```typescript // ./strategies/demo.ts import { BTH } from '@backtest/framework' export async function startCallback(historicalName: string) { console.log('called before runStrategy', historicalName) } export async function finishCallback(historicalName: string) { console.log('called after runStrategy', historicalName) } export async function runStrategy(bth: BTH) { const sma10 = await bth.getCandles('close', 10) const sma20 = await bth.getCandles('close', 20) if (sma10 > sma20) { await bth.buy() } else { await bth.sell() } } ``` -------------------------------- ### Configure Environment Variables Source: https://github.com/backtestjs/framework/blob/main/docs/CONTRIBUTING.md Copies the example environment file to a new file named '.env'. This setup step is crucial for configuring project-specific settings before running or building the application. ```bash cp .env.example .env ``` -------------------------------- ### Install Backtest.js Framework with npm Source: https://github.com/backtestjs/framework/blob/main/docs/BASIC_USAGE.md Installs the Backtest.js framework using npm. This is the first step to using the framework in your project. ```bash npm install @backtest/framework ``` -------------------------------- ### Install Project Dependencies with npm Source: https://github.com/backtestjs/framework/blob/main/docs/CONTRIBUTING.md Installs all necessary dependencies for the backtestjs/framework project using npm. This is a prerequisite for local development and building the project. ```bash npm install ``` -------------------------------- ### Run the backtestjs/framework Project Source: https://github.com/backtestjs/framework/blob/main/docs/CONTRIBUTING.md Starts the backtestjs/framework application. The 'npm run start' command runs the production build, while 'npm run dev' is suitable for development with features like hot-reloading. ```bash npm run start # or "npm run dev" if you prefer ``` -------------------------------- ### Implement Start and Finish Callbacks for Strategy Initialization and Finalization Source: https://github.com/backtestjs/framework/blob/main/README.md This snippet shows how to implement `start` and `finish` callbacks for a strategy. The `start` callback executes before the strategy runs, useful for initialization, and the `finish` callback runs after, suitable for finalization tasks. Both callbacks receive the historical data name as an argument. ```typescript export async function startCallback(historicalName: string) { console.log('called before runStrategy', historicalName) } export async function finishCallback(historicalName: string) { console.log('called after runStrategy', historicalName) } ``` -------------------------------- ### How to Use @backtest/framework in TypeScript Source: https://github.com/backtestjs/framework/blob/main/docs/QUICK_START.md Demonstrates the usage of various functions from the @backtest/framework package, including data management, strategy scanning, and running backtests. It shows how to download historical data, check for its existence, scan available strategies, and execute a strategy with specified parameters. ```typescript import { parseRunResultsStats, findHistoricalData, findHistoricalDataNames, downloadHistoricalData, runStrategy, scanStrategies } from '@backtest/framework' async function main() { // historical data const startDate = new Date('2024-01-01').getTime() const endDate = new Date('2024-10-15').getTime() // analyzed period const startTime = new Date('2024-03-01').getTime() const endTime = new Date('2024-10-14').getTime() // check if already downloaded const found = await findHistoricalData('BTCEUR-8h') console.log('found:', found) if (!found) { // download data from public API binance const downloaded = await downloadHistoricalData('BTCEUR', { interval: '8h', startDate: startDate, endDate: endDate }) console.log('downloaded:', downloaded) } // check if now is present const allNames = await findHistoricalDataNames() console.log('allNames:', allNames) // scan strategies const scan = await scanStrategies() console.log('scan:', scan) // run strategy const runStrategyResult = await runStrategy({ strategyName: 'demo', historicalData: ['BTCEUR-8h'], params: {}, startingAmount: 1000, startTime: startTime, endTime: endTime }) console.log('runStrategyResult:', runStrategyResult.name) const parsed = await parseRunResultsStats(runStrategyResult) console.log('parsed:', parsed?.totals[0], parsed?.totals[1]) // just to show somethings (probably, you need to look parsed or strategyResult) } main() ``` -------------------------------- ### Utilize Strategy Parameters Source: https://github.com/backtestjs/framework/blob/main/docs/STRATEGY.md Strategies can be made configurable by defining parameters accessible via `bth.params`. These parameters, such as `shortPeriod` and `longPeriod`, can be set externally and used within the strategy logic, for example, to calculate moving averages. ```typescript export async function runStrategy(bth: BTH) { const { shortPeriod, longPeriod } = bth.params const shortMA = await bth.getCandles('close', shortPeriod) const longMA = await bth.getCandles('close', longPeriod) } ``` -------------------------------- ### Basic Trading Strategy Example in TypeScript Source: https://github.com/backtestjs/framework/blob/main/README.md Demonstrates a basic trading strategy using the Backtest JS framework. It fetches 10-period and 20-period Simple Moving Averages (SMA) of closing prices and executes a buy or sell order based on their comparison. Requires the BTH object from the framework. ```typescript import { BTH } from '@backtest/framework' export async function runStrategy(bth: BTH) { const sma10 = await bth.getCandles('close', 10) const sma20 = await bth.getCandles('close', 20) if (sma10 > sma20) { await bth.buy() } else { await bth.sell() } } ``` -------------------------------- ### Execute Trading Orders Source: https://github.com/backtestjs/framework/blob/main/docs/STRATEGY.md The framework provides methods for executing basic and advanced trading orders. `bth.buy()` and `bth.sell()` can be called without arguments for market orders. Advanced orders allow specifying `amount`, `stopLoss`, and `takeProfit` levels for more controlled execution. ```typescript // Basic orders await bth.buy() await bth.sell() // Advanced orders await bth.buy({ amount: 100, stopLoss: 9500, takeProfit: 11000 }) ``` -------------------------------- ### Multi-Timeframe Strategy in TypeScript Source: https://github.com/backtestjs/framework/blob/main/docs/EXAMPLES.md Demonstrates a multi-timeframe analysis strategy. It checks if a trading candle is available. If so, it analyzes the trend based on the previous candle's closing price to decide on a buy order. Otherwise, it logs the volume for the current timeframe. ```typescript export async function runStrategy(bth: BTH) { if (bth.tradingCandle) { const trend = await bth.getCandles('close', 1, 0) if (trend > 0) await bth.buy() } else { // Support timeframe analysis const volume = await bth.getCandles('volume', 1) console.log('Volume:', volume) } } ``` -------------------------------- ### Get Candle Start Date for Symbol (TypeScript) Source: https://context7.com/backtestjs/framework/llms.txt Retrieves the earliest available candle date for a given trading symbol from an exchange (e.g., Binance). Handles potential errors if the symbol is not found. Uses 'getCandleStartDate' from '@backtest/framework'. ```typescript import { getCandleStartDate } from '@backtest/framework' // Get earliest date for Bitcoin const btcStart = await getCandleStartDate('BTCUSDT') if (!btcStart.error) { console.log('BTC trading started on Binance:', new Date(btcStart.data)) // Use this to determine valid startDate for downloads await downloadHistoricalData('BTCUSDT', { interval: '1d', startDate: btcStart.data, endDate: new Date() }) } else { console.log('Symbol not found:', btcStart.error) } // Check if symbol exists const symbolCheck = await getCandleStartDate('INVALIDCOIN') if (symbolCheck.error) { console.log('Symbol does not exist on Binance') ``` -------------------------------- ### Candle Start Date API Source: https://context7.com/backtestjs/framework/llms.txt API to retrieve the earliest available candle start date for a given trading symbol from a data source like Binance. ```APIDOC ## Get Candle Start Date ### Description Retrieves the earliest available candle date for a symbol from a data source (e.g., Binance). This is useful for determining the valid start time for historical data downloads. ### Method - `getCandleStartDate(symbol: string): Promise<{ error?: string, data?: number }>` - Fetches the earliest candle start date for the given symbol. ### Parameters #### Query Parameters - **symbol** (string) - Required - The trading symbol (e.g., 'BTCUSDT'). ### Request Example ```typescript import { getCandleStartDate } from '@backtest/framework'; const btcStart = await getCandleStartDate('BTCUSDT'); if (!btcStart.error) { console.log('BTC trading started on Binance:', new Date(btcStart.data)); } else { console.log('Symbol not found:', btcStart.error); } ``` ### Response Example (Success) ```json { "data": 1483228800000 } ``` ### Response Example (Symbol Not Found) ```json { "error": "Symbol not found" } ``` ``` -------------------------------- ### Moving Average Crossover Strategy in TypeScript Source: https://github.com/backtestjs/framework/blob/main/docs/EXAMPLES.md Implements a simple moving average crossover strategy. It fetches 10-period and 20-period simple moving averages of closing prices and executes a buy order if the 10-period SMA is greater than the 20-period SMA, otherwise a sell order. ```typescript export async function runStrategy(bth: BTH) { const sma10 = await bth.getCandles('close', 10) const sma20 = await bth.getCandles('close', 20) if (sma10 > sma20) { await bth.buy() } else { await bth.sell() } } ``` -------------------------------- ### Define Strategy Entry Point Source: https://github.com/backtestjs/framework/blob/main/docs/STRATEGY.md Every Backtest.js strategy must export an asynchronous `runStrategy` function. This function accepts a `BTH` object as its sole argument, which provides access to all framework functionalities. The strategy logic is implemented within this function. ```typescript import { BTH } from '@backtest/framework' export async function runStrategy(bth: BTH) { // Strategy logic here } ``` -------------------------------- ### Use Multiple Historical Data Intervals in Strategy Source: https://github.com/backtestjs/framework/blob/main/README.md This example demonstrates how to utilize multiple historical data intervals within a trading strategy. It shows conditional execution based on the presence of a 'tradingCandle', allowing for statistical analysis or signal validation using support intervals while executing trades on the primary trading interval. ```typescript export async function runStrategy(bth: BTH) { if (bth.tradingCandle) { // For example, use BTCEUR-1d data to execute your trading strategy (buy, sell, etc.) } else { // do something else when BTCEUR-8h candle is closed } } ``` -------------------------------- ### Implement Custom Technical Indicators in Strategies (TypeScript) Source: https://github.com/backtestjs/framework/blob/main/docs/ADVANCED_USAGE.md This example shows how to integrate custom technical indicators into trading strategies. It includes a sample 'calculateRSI' function and its usage within 'runStrategy', demonstrating how to fetch candle data and apply the custom indicator for trading decisions. Dependencies include the 'BTH' object. ```typescript function calculateRSI(values: number[], period: number): number { // RSI implementation return rsiValue } export async function runStrategy(bth: BTH) { const closes = await bth.getCandles('close', 14) const rsi = calculateRSI(closes, 14) if (rsi < 30) await bth.buy() if (rsi > 70) await bth.sell() } ``` -------------------------------- ### RSI Strategy in TypeScript Source: https://github.com/backtestjs/framework/blob/main/docs/EXAMPLES.md Implements a Relative Strength Index (RSI) based trading strategy. It calculates the RSI over 14 periods using closing prices. A buy order is executed if RSI is below 30, and a sell order if RSI is above 70. ```typescript export async function runStrategy(bth: BTH) { const closes = await bth.getCandles('close', 14) const rsi = calculateRSI(closes) if (rsi < 30) { await bth.buy() } else if (rsi > 70) { await bth.sell() } } ``` -------------------------------- ### Handle Multiple Timeframes Source: https://github.com/backtestjs/framework/blob/main/docs/STRATEGY.md The `bth.tradingCandle` boolean indicates whether the current execution is for the main trading timeframe or a secondary analysis timeframe. This allows conditional logic for different intervals, enabling strategies to perform main trading actions or supplementary analysis. ```typescript export async function runStrategy(bth: BTH) { if (bth.tradingCandle) { // Main trading logic const price = await bth.getCandles('close', 1) } else { // Support timeframe analysis const volume = await bth.getCandles('volume', 1) } } ``` -------------------------------- ### Execute Trading Strategy with Parameters Source: https://context7.com/backtestjs/framework/llms.txt Runs a specified trading strategy with given historical data, parameters, and execution settings like starting amount, time range, fees, and slippage. Supports single parameter values, parameter permutations for testing, multi-symbol data, and auxiliary support intervals for analysis. ```typescript import { runStrategy, scanStrategies } from '@backtest/framework' // Ensure strategies are scanned first await scanStrategies() // Run simple strategy with single parameter values const result = await runStrategy({ strategyName: 'demo', historicalData: ['BTCEUR-1d'], params: { lowSMA: 10, highSMA: 50 }, startingAmount: 1000, startTime: new Date('2024-03-01').getTime(), endTime: new Date('2024-10-14').getTime(), percentFee: 0.1, // 0.1% trading fee percentSlippage: 0.05 // 0.05% slippage }) console.log('Strategy name:', result.name) console.log('Total orders:', result.allOrders.length) console.log('Final worth:', result.allOrders[result.allOrders.length - 1].worth) // Run with parameter permutations (tests all combinations) const multiResult = await runStrategy({ strategyName: 'demo', historicalData: ['BTCEUR-1d'], params: { lowSMA: [10, 20, 30], // Tests 3 values highSMA: [40, 50, 60] // Tests 3 values }, startingAmount: 1000, startTime: new Date('2024-03-01').getTime(), endTime: new Date('2024-10-14').getTime() }) // Tests 9 permutations (3 x 3) and returns StrategyResultMulti // Run multi-symbol strategy const multiSymbol = await runStrategy({ strategyName: 'demo', historicalData: ['BTCEUR-8h', 'BTCEUR-1h'], startingAmount: 1000, startTime: new Date('2024-03-01').getTime(), endTime: new Date('2024-10-14').getTime(), params: {} }) // Run with support intervals for additional analysis const withSupport = await runStrategy({ strategyName: 'demo', historicalData: ['BTCEUR-1d'], supportHistoricalData: ['BTCEUR-8h', 'BTCEUR-1h'], params: { lowSMA: 10, highSMA: 50 }, startingAmount: 1000, startTime: new Date('2024-03-01').getTime(), endTime: new Date('2024-10-14').getTime() }) ``` -------------------------------- ### Buy/Sell Order Interface Definition (TypeScript) Source: https://github.com/backtestjs/framework/blob/main/README.md Defines the structure for buy and sell orders, specifying optional parameters such as price, position (long/short), amount, base amount, stop loss, take profit, fees, slippage, and notes. This interface guides the configuration of trade executions. ```typescript 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 } ``` -------------------------------- ### Run a Trading Strategy with Backtest.js Framework Source: https://github.com/backtestjs/framework/blob/main/README.md Executes a specified trading strategy using the `runStrategy` function. It requires scanning strategies first if changes have been made. The function accepts parameters such as strategy name, historical data symbols, trading parameters, starting amount, and time range. It returns an object with the strategy's name upon successful execution. ```typescript import { scanStrategies, runStrategy } from '@backtest/framework' const scan = await scanStrategies() console.log('Scan strategies:', scan) const runStrategyResult = await runStrategy({ strategyName: 'demo', // ./strategies/demo.ts historicalData: ['BTCEUR-1d'], params: { lowSMA: [10, 20], // or a single value eg. 20 highSMA: [30, 40, 50] // or a single value eg. 50 }, startingAmount: 1000, startTime: startTime, endTime: endTime }) console.log('runStrategyResult:', runStrategyResult.name) ``` -------------------------------- ### Build the backtestjs/framework Project Source: https://github.com/backtestjs/framework/blob/main/docs/CONTRIBUTING.md Compiles and bundles the backtestjs/framework project. This command is typically used to prepare the project for deployment or for running in a production-like environment. ```bash npm run build ``` -------------------------------- ### Configure Backtest.js Framework Environment Source: https://github.com/backtestjs/framework/blob/main/docs/BASIC_USAGE.md Sets up essential environment variables for the Backtest.js framework. DATABASE_URL specifies the database connection, and FRAMEWORK_LOG_LEVEL controls the verbosity of logs. ```env DATABASE_URL=file:./db/backtest.db FRAMEWORK_LOG_LEVEL=ERROR ``` -------------------------------- ### Get and Validate Trading Intervals (TypeScript) Source: https://context7.com/backtestjs/framework/llms.txt Retrieves a list of all valid trading intervals supported by the framework and checks if a given interval string is valid. Uses functions from '@backtest/framework'. ```typescript import { getIntervals, isValidInterval } from '@backtest/framework' // Get all supported intervals const intervals = getIntervals() console.log('Supported intervals:', intervals) // Returns: ['1m', '3m', '5m', '15m', '30m', '1h', '2h', '4h', '6h', '8h', '12h', '1d', '3d', '1w', '1M'] // Validate user input const userInterval = '4h' if (isValidInterval(userInterval)) { console.log(`${userInterval} is valid`) await downloadHistoricalData('BTCEUR', { interval: userInterval, startDate: new Date('2024-01-01'), endDate: new Date('2024-10-15') }) } else { console.log(`Invalid interval: ${userInterval}`) } // Check before import const csvInterval = '15m' if (!isValidInterval(csvInterval)) { throw new Error(`Interval ${csvInterval} is not supported. Use: ${getIntervals().join(', ')}`) } ``` -------------------------------- ### Basic Buy and Sell Execution (TypeScript) Source: https://github.com/backtestjs/framework/blob/main/README.md Demonstrates the simplest way to execute a buy or sell order. The `buy()` function, when called without arguments, defaults to buying the maximum available base currency. Similarly, `sell()` without arguments sells all currently held assets. ```typescript // 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() ``` -------------------------------- ### Prisma CLI Commands for Database Management Source: https://github.com/backtestjs/framework/blob/main/README.md This section provides essential commands for managing the database using Prisma, a modern database toolkit. These commands are used for generating artifacts, validating the schema, and pushing schema changes to the database, specifically when using SQLite. ```bash npx prisma npx prisma validate npx prisma generate npx prisma db push ``` -------------------------------- ### Run a Simple Moving Average Strategy (TypeScript) Source: https://github.com/backtestjs/framework/blob/main/docs/BASIC_USAGE.md Implements a basic trading strategy that compares the current close price to a 20-period Simple Moving Average (SMA). It buys if the close price is above the SMA and sells otherwise. Requires the '@backtest/framework' library. ```typescript import { BTH } from '@backtest/framework' export async function runStrategy(bth: BTH) { const closePrice = await bth.getCandles('close', 1) const sma20 = await bth.getCandles('close', 20, 0) if (closePrice > sma20) { await bth.buy() } else { await bth.sell() } } ``` -------------------------------- ### Configuring Stop Loss and Take Profit (TypeScript) Source: https://github.com/backtestjs/framework/blob/main/README.md No description ```typescript // 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 it's 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%"}) ``` -------------------------------- ### Execute a Backtest Strategy Configuration (TypeScript) Source: https://github.com/backtestjs/framework/blob/main/docs/BASIC_USAGE.md Configures and runs a trading strategy using the Backtest.js framework. It specifies the strategy name, historical data sources, strategy parameters, and the initial amount for backtesting. ```typescript import { runStrategy } from '@backtest/framework' const result = await runStrategy({ strategyName: 'simpleMovingAverage', historicalData: ['BTCEUR-1d'], params: { period: 20 }, startingAmount: 1000 }) ``` -------------------------------- ### Place Orders at Specific Prices with Backtest.js Source: https://github.com/backtestjs/framework/blob/main/README.md Illustrates how to place buy or sell orders at a predetermined price point. This is useful for setting limit orders or entry/exit triggers based on specific market conditions. The 'price' parameter allows for precise control over trade execution. ```typescript // 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 }) ``` -------------------------------- ### Specifying Buy/Sell Amount (TypeScript) Source: https://github.com/backtestjs/framework/blob/main/README.md Shows how to specify the amount for buy and sell orders using either a fixed number or a percentage string. This allows for partial trades, controlling the exact value or proportion of the base currency to be traded. ```typescript // 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%' }) ``` -------------------------------- ### Advanced Buy/Sell Order Parameters (TypeScript) Source: https://github.com/backtestjs/framework/blob/main/README.md Illustrates the use of advanced parameters for buy and sell orders, including specifying the trade position ('short' or 'long'), setting stop-loss and take-profit levels, and defining the order amount using percentages. It also shows how to partially close a short position. ```typescript await bth.buy() /* or */ await bth.buy({ position: 'short', // or 'long' (default) amount: '10%', // or baseAmount note: 'a simple note here', stopLoss: stopLoss, percentSlippage: percentSlippage, percentFee: percentFee }) bth.sell() /* or */ await bth.sell({ amount: 250, // or baseAmount note: 'a simple note here' }) ``` -------------------------------- ### Retrieve Price Data Source: https://github.com/backtestjs/framework/blob/main/docs/STRATEGY.md The `getCandles` method allows fetching historical price data for various types (e.g., 'close', 'open', 'high', 'low', 'volume'). It accepts the data type, the number of candles, and an optional offset for historical data retrieval. This is crucial for technical analysis. ```typescript const close = await bth.getCandles('close', 1) // Latest close price const opens = await bth.getCandles('open', 10) // Last 10 open prices const highs = await bth.getCandles('high', 5, 2) // High prices from 5 to 2 candles ago ``` -------------------------------- ### Find Historical Data (TypeScript) Source: https://context7.com/backtestjs/framework/llms.txt Retrieves metadata and candle information for stored historical datasets. Functions are available to get all dataset names, all dataset metadata, or specific dataset details by name. Returns dataset names as strings, metadata as an array of objects, or a specific MetaCandle object. ```typescript import { findHistoricalData, findHistoricalDataNames, findHistoricalDataSets } from '@backtest/framework' // Get all historical data names const names = await findHistoricalDataNames() console.log('Available datasets:', names) // Returns: ['BTCEUR-1d', 'BTCEUR-8h', 'AAPL-1d'] // Get all metadata for all datasets const allSets = await findHistoricalDataSets() console.log('Total datasets:', allSets.length) // Returns: MetaCandle[] with name, symbol, interval, startTime, endTime, etc. // Get specific dataset with metadata const dataset = await findHistoricalData('BTCEUR-8h') console.log('Dataset info:', { name: dataset.name, symbol: dataset.symbol, interval: dataset.interval, candleCount: dataset.endTime - dataset.startTime }) // Returns: MetaCandle object or null if not found ``` -------------------------------- ### Specify Order Base Amount with Backtest.js Source: https://github.com/backtestjs/framework/blob/main/README.md Demonstrates how to place buy or sell orders using either a base amount (e.g., 0.25 bitcoin) or a direct currency amount (e.g., $500). Note that 'amount' and 'baseAmount' cannot be used in the same order call. This functionality is crucial for managing trade sizes. ```typescript 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 }) ``` -------------------------------- ### Backtest.js Framework: RunStrategy Interface Definition Source: https://github.com/backtestjs/framework/blob/main/README.md Defines the structure for the `RunStrategy` interface in the Backtest.js framework. This interface specifies all possible configuration options when running a strategy, including strategy name, historical data, starting capital, timeframes, custom parameters, fees, slippage, and more. The `params` property allows for multiple values, triggering permutations. ```typescript export interface RunStrategy { strategyName: string // name of the strategy to run historicalData: string[] // symbols to use for trading (e.g. ['BTCEUR-8h', 'BTCEUR-1d']) supportHistoricalData?: string[] // symbols to use as support (e.g. ['BTCEUR-1h', 'BTCEUR-8h', 'BTCEUR-1d']) startingAmount: number // how much money to start with startTime: number // from which date start to evaluate yor strategy endTime: number // to which date evaluate your strategy params: LooseObject // parameters to use for the strategy, you can pass multiple value for each parameter percentFee?: number // 0.1 means 0.1% fee percentSlippage?: number // 0.6 means 0.6% slippage rootPath?: string // sometimes is useful specify a different path (uncommon case) alwaysFreshLoad?: boolean // if true the file of the strategy is always reloaded by scratch, the default is false } ``` -------------------------------- ### Retrieve Candle Data with getCandles in Backtest.js Source: https://github.com/backtestjs/framework/blob/main/README.md Details the `getCandles` asynchronous function, which retrieves historical price data in the form of `Candle` objects. It allows fetching specific data points (like 'close' or 'open') or entire candle objects, using start and end indices relative to the current candle. This is essential for technical analysis and indicator calculations. ```typescript const closes = await bth.getCandles('close', 10, 0) // last ten closes const open = await bth.getCandles('open', 0) // last open const candles = await bth.getCandles('candle', 5, 0) // last five candles ``` -------------------------------- ### Get Candles in Strategy with Backtest.js Source: https://context7.com/backtestjs/framework/llms.txt Retrieves historical candle data within a strategy execution using the BTH interface. This function allows fetching specific data points like 'close', 'high', or the entire 'candle' object for a given number of periods and an offset. It also provides direct access to the current candle's information. ```typescript import { BTH } from '@backtest/framework' export async function runStrategy(bth: BTH) { // Get last 10 close prices const closes = await bth.getCandles('close', 10, 0) console.log('Last 10 closes:', closes) // Get current candle's close (last candle) const currentClose = await bth.getCandles('close', 0) console.log('Current close:', currentClose) // Get 5th candle from current (single candle) const fifthCandle = await bth.getCandles('candle', 5) console.log('5th candle:', fifthCandle) // Get last 20 high prices const highs = await bth.getCandles('high', 20, 0) // Get last 10 volumes const volumes = await bth.getCandles('volume', 10, 0) // Get candles from index 20 to 10 (excluding last 10) const midCandles = await bth.getCandles('candle', 20, 10) console.log('Middle candles:', midCandles.length) // Returns 10 candles // Get all OHLCV for last 5 candles const lastFiveCandles = await bth.getCandles('candle', 5, 0) lastFiveCandles.forEach(candle => { console.log({ time: candle.closeTime, open: candle.open, high: candle.high, low: candle.low, close: candle.close, volume: candle.volume }) }) // Access current candle directly console.log('Current candle:', bth.currentCandle) console.log('Trading interval:', bth.tradingInterval) console.log('Is tradable:', bth.tradingCandle) } ``` -------------------------------- ### Parameter Optimization for Strategies (TypeScript) Source: https://github.com/backtestjs/framework/blob/main/docs/ADVANCED_USAGE.md This code illustrates how to test various parameter combinations for a strategy. It showcases the input structure for parameter optimization, where arrays of values are provided for 'shortPeriod' and 'longPeriod', and the 'runStrategy' function is called with these parameters. ```typescript const result = await runStrategy({ strategyName: 'maStrategy', historicalData: ['BTCEUR-1d'], params: { shortPeriod: [5, 10, 15], longPeriod: [20, 30, 40] } }) ``` -------------------------------- ### Implement a Simple SMA Crossover Strategy in Backtest.js Source: https://github.com/backtestjs/framework/blob/main/README.md A basic implementation of a Simple Moving Average (SMA) crossover strategy. This strategy uses hard-coded SMA periods (3 and 45) to determine buy and sell signals. It fetches historical closing prices, calculates the SMAs, and executes trades based on their crossover. Note that hard-coding parameters limits parallel testing capabilities. ```typescript import { BTH } from '@backtest/framework' import { indicatorSMA } from '../indicators/moving-averages' export async function runStrategy(bth: BTH) { const lowSMACandles = await bth.getCandles('close', 3, 0) const highSMACandles = await bth.getCandles('close', 45, 0) // 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() } } ``` -------------------------------- ### Use Multiple Data Intervals in Strategies (TypeScript) Source: https://github.com/backtestjs/framework/blob/main/docs/ADVANCED_USAGE.md This snippet demonstrates how to utilize different trading intervals within a single strategy. It fetches data for the main trading interval and a support interval to perform confirmations, requiring the 'BTH' object for data retrieval and order execution. ```typescript export async function runStrategy(bth: BTH) { // Main trading interval if (bth.tradingCandle) { const shortMA = await bth.getCandles('close', 10) const longMA = await bth.getCandles('close', 20) if (shortMA > longMA) { await bth.buy() } } // Support interval for confirmations else { const volume = await bth.getCandles('volume', 1) const avgVolume = await bth.getCandles('volume', 20) console.log('Volume analysis:', volume > avgVolume) } } ``` -------------------------------- ### Environment Variables Configuration (.env file) Source: https://github.com/backtestjs/framework/blob/main/README.md Configuration file for environment variables required by the Backtest JS framework. It specifies the database connection URL and the logging level. The DATABASE_URL must include the path to the SQLite database file. ```env DATABASE_URL=file:/Users/backtesjs/quick-start/db/backtest.db FRAMEWORK_LOG_LEVEL=ERROR ```