Algo Trading
The Algo Trading tool runs a trading algorithm that you write in JavaScript. The code receives the market data one date at a time, sends buy and sell orders, and gets the same results as the Portfolio tool.
Fields:
- Tickers - The assets the algorithm can trade. Use any of the ticker types, up to 10.
- Balance - The initial cash, in the currency selected at the top of the page.
- Range - The start and end dates of the simulation.
- Leverage - When enabled, allows short selling, so the algorithm can sell assets it does not hold, within the margin limits below. The proceeds of a short sale are not added to the cash. Use it with caution, as it increases both potential returns and risks.
- Init. Margin - A percentage (default 50%) that limits new short positions: the total short value can be up to (cash + long positions) / Init. Margin. For example, 50% allows short positions up to 2 times the cash plus long positions.
- Min. Margin - A percentage (default 30%) of the short value that must stay available as margin. If the margin falls below it, the simulation stops with an error. There is no automatic margin call.
- Code - The JavaScript code of the algorithm (see below).
Code (AlgoWorkspace):
The code runs as the body of an async function, with this bound to the AlgoWorkspace. Register the event listeners, then call start() at the end of the code to begin the simulation. The code must have exactly one data listener, and every listener must call next() when it finishes.
Available events:
this.on('start', async (next, timeseries) => { ... })- Runs once before the first date. timeseries has all the price data, keyed by date (Record<string, AssetDataFlat[]>). this.assets and this.portfolio are not set yet.this.on('data', async (next) => { ... })- Runs once for each date with data. Orders are filled after the listener calls next(), at the price of that date.this.on('end', async (next, result) => { ... })- Runs after the last date, with the final result. result.summary.alpha and beta are Promises.this.on('error', async (next, errors) => { ... })- Runs when orders of a date are cancelled, e.g. not enough cash or margin. errors is a string[]. An exception in your code stops the simulation and shows in the Warnings tab.
Properties and methods:
this.date- The current date.this.assets- The prices of the current date (AssetDataFlat[]: assetCode, date, value, currency). Only tickers with data on that date are included.this.portfolio- A copy of the current portfolio (cash, assets, total, longValue, shortValue, totalProfit, realizedProfit, margin). Changing it has no effect, use the methods below.this.index- The number of the current date, from 1 to this.length.this.length- The number of dates with data.this.inputs- The inputs of the simulation.this.state- An object to store your own data between events.this.buy(assetCode: string, quantity: number): void- Sends a buy order. The quantity must be a finite number other than zero.this.sell(assetCode: string, quantity: number): void- Sends a sell order. Selling more than the position opens a short position, if Leverage is enabled.this.print(...msgs: any[]): void- Adds a message, with the current date, to the Messages tab.this.depositCash(amount: number): void- Adds cash to the portfolio.this.loadScript(url: string): Promise<number>- Loads an external JavaScript library. Loaded scripts are removed after the run.this.download(obj: any, name?: string): Promise<void>- Downloads obj as a JSON file named name.json (default invest-tester.json).
The default code on the Algo Trading page is a complete example. It loads a library, places random orders and makes monthly deposits.