Creating a Pricemap

Overview



Creating a Pricemap



In order to backtest a strategy, you need to have pricing data to run the backtest against. In general, price data will come as an array of price records, with a data and id (typically a ticker). We assume that the price records will look like:


let prices = [
	{date:'2000-01-01', close:100,open:100,high:100,low:100, id:'IBM'},
	{date:'2000-01-02', close:101, open:100,high:100,low:100,id:'IBM'},
	{date:'2000-01-01', close:100, open:100,high:100,low:100,id:'MSFT'},
	{date:'2000-01-02', close:102, open:100,high:100,low:100,id:'MSFT'},
  ];
					


It will be convenient for us to have one record per date, with the prices a dictionary on that record


let record = {
  date : '2000-01-01',
  prices:{
    'MSFT' : {date:'2000-01-01', close:100,open:100,high:100,low:100, id:'IBM'},
    'AAPL' : {date:'2000-01-01', close:100, open:100,high:100,low:100,id:'MSFT'}
  }
}
					


In addition, we will only want records that has a price for each asset we are tracking. That is, if we are building a pairs strategy for trading between AAPL and MSFT, we will only want to include dates for which we have price data for both assets.

To accomplish this, we will utilize the group api. The following code first groups the data by date and then by id and places that information in a dictionary.

Next, the code calculates the maximum number of assets for each date. It filters the records for only those with number of assets matching the max. This makes sure that we have all prices on each date.


let gp = await import("/lib/group/v1.0.0/group.mjs");
let prices = [
	{date:'2000-01-01', close:100,open:100,high:100,low:100, id:'IBM'},
	{date:'2000-01-02', close:101, open:100,high:100,low:100,id:'IBM'},
	{date:'2000-01-01', close:100, open:100,high:100,low:100,id:'MSFT'},
	{date:'2000-01-02', close:102, open:100,high:100,low:100,id:'MSFT'},
  ];

let data = $list(prices)
			.group(p=>p.date)
			.filter(p=>p.values.length===2)
			.map(p=>p.values)
			.flat()
			.items;

let map = gp.group(data, p=>[p.date, p.id]).map((keys, values)=>values[0]).toObject();				
					
Try it!


Note this code does a bit of cleanup as well. For example, it renames the prices dictionary on each record from the default name "value" given by the group api, to "prices". It renames "key" to be "date".

In addition to this, the price dictionary will contain a single element array for each ticker at each date. This is because the group api groiups all the records together in an array that matches the group criteria, even if there is only one item. Here, we know that there will only be one price for each asset for each date, so we replace each array by its first item. This will simplify calculations later.

This calculation has been encapsulated in the prices method in the trading library. The follwoing code accomplishes the same task as the code above.


let td = await import('/lib/finance/trading/v1.0.0/trading.js');

let prices = td.prices(priceData);
					
Try it!


Contents