When backtesting a Strategy on daily data which uses AtStop/AtLimit orders in Portfolio Simulation mode, some trades can be dropped due to insufficent funds. Setting Position.Priority would help to instruct Wealth-Lab which trades to take and which to discard. For realistic results, higher priority should be assigned to those trades that would have been filled earlier, looking at intraday data.
Syntax
public double LimitPriorityLong(double p, int bar)
Parameter Description
| p |
Limit price |
| bar |
Signal bar |
This function, created by Andrew (
avishn), helps to estimate which limit orders will realistically be hit first - without dropping to the intraday data level. According to its author, it gives quick and dirty approximation and is useful when scanning large data sets.
Syntax
public double IntradayFillPriorityEstimate(bool longPos, bool limit, double price, int eodBar)
Parameter Description
| longPos |
true for long, false for short positions |
| limit |
true for limit, false for stop orders |
| price |
Signal price |
| eodBar |
Alert bar |
This function, created by
Andrew (avishn), helps estimate which limit orders will realistically be hit first - without dropping to the intraday data level. Like the original
LimitPriorityLong, superseded by this function, it gives an approximation and is useful when scanning large data sets. It supports both long and short as well as limit and stop orders.
Example
Here is a code example to illustrate the
IntradayFillPriorityEstimate method:
if (BuyAtLimit(bar + 1,price, "") != null) {
LastActivePosition.Priority = IntradayFillPriorityEstimate(true, true, price, bar + 1);
}
Syntax
public void SetTimeOfDayPriority(IList<Position> positions, string intradayDataSet)
Parameter Description
| positions |
Pass the list of Positions that have been established to date by the Strategy. |
| intradayDataSet |
Exact name of the DataSet with corresponding intraday data |
This method, created by Robert Sucher (
Cone), avoids the task of rewriting the original Strategy to work on intraday data, and accesses corresponding intraday data from the same Strategy running on daily data. (For more details, see this KB article:
Intraday / Multi-Time Frame | Accessing Intraday data from Daily.
- Automatically sets priority: Trades that occur earlier are assigned higher priority
- Works for all AtStop/AtLimit order types
- Assumes 0 Slippage
- Update your intraday DataSet(s) before running, or, disable File > Update Data on Demand.
- Recommended usage with intraday DataSet interval 5 minute or higher.
- Note: Valid for scripts that trade 1-symbol only
Description
Quote the QuickRef:
Generally speaking, you should not assign Priority for Strategies that use AtLimit/AtStop entries. Doing so may create a peeking effect since it's often not possible to know which limit (or stop) orders will execute first when orders are placed for multiple instruments. You can, however, realistically use the inverse of the HHmm time-of-day as the correct Priority value. In other words, trades that occur earlier in the day should be assigned higher priority.
These methods help you solve this problem, one by providing a quick approximation, and another being precise (but requires intraday data).
Example
Here is a code example to illustrate the
SetTimeOfDayPriority method:
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using Community.Components;
namespace WealthLab.Strategies
{
public class MyStrategy : WealthScript
{
protected override void Execute()
{
PositionHelper ph = new PositionHelper( this );
ClearDebug();
for(int bar = 20; bar < Bars.Count; bar++)
{
if (IsLastPositionActive)
{
Position p = LastPosition;
if (bar - p.EntryBar > 2) SellAtMarket(bar + 1, p);
}
else
{
double limitPrice = 0.96 * Close[bar];
Position p = BuyAtLimit(bar + 1, limitPrice);
}
}
/* Call the method after the trading loop */
ph.SetTimeOfDayPriority(Positions, "[i] ActiveTrader Standard Stock Portfolio (M5)");
/* Check priority */
int j = 0;
foreach (Position p in Positions)
{
j++;
PrintDebug(j + "\t" + p.Priority + "\t" + p.EntryDate.ToShortDateString());
}
}
}
}