-
Simple Backtester in q
Good morning everyone, I’m trying to create a backtest engine for trading strategies that processes signals from tick datasets and verifies the performance position by position, according to stop loss and target levels.
.Backtester.Engine:{[data] entry_time: data`ts_event; entry_prc: data`entry_price; tp: data`target; sl: data`stop; id: data`order_id; sig: data`signal; idx1: data`idx; dataset: ?[sig = 1;first select idx1, idx2:idx, id, entry_time, exit_time: ts_event, sig, entry_prc, stop:sl, target: price from final_6E where (ts_event > entry_time) & ((price > tp) | (price < sl)); ?[sig = -1;first select idx1, idx2:idx, id, entry_time,exit_time:ts_event, sig, entry_prc, stop:sl, target: price from final_6E where (ts_event > entry_time) & ((price < tp) | (price > sl));0]]; dataset: update result: ?[(sig = 1) & (target > entry_prc); 1; ?[(sig = -1) & (target < entry_prc); 1; -1]] from dataset; dataset: update pips_result: ?[sig = 1; target - entry_prc; ?[sig = -1; entry_prc - target; 0]] from dataset; dataset: update trade_duration: (exit_time.minute - entry_time.minute) from dataset; :dataset; }; results: .Backtester.Engine each final_table;
Specifically, one of the parts I’m managing in a totally inefficient way is the backtest function itself. With this function, the goal is to find the first point where the price reaches either the stop loss or target level, operation by operation, recording the results of the trade. The sig column represents (1 for long signals, -1 for short signals).
The input table to the function is the one that filters all generated signals, while “final_6E” represents the complete tick-by-tick table, necessary to identify the exact point where events occur.
How can I optimize this process, considering that I’m using idx (index number) to perform a loop where I search for the first useful point between stop and take profit?
Thank you.
Log in to reply.