Log in to see Cloud of Tags

Wealth-Lab Wiki

Page History: Setting Priority for AtStop/AtLimit Orders

Compare Page Revisions



« Older Revision - Back to Page History - Current Revision


Page Revision: 2013/05/11 14:54


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.

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.

LimitPriorityLong

Syntax

public static double LimitPriorityLong(this WealthScript ws, double p, int bar)

public double LimitPriorityLong(double p, int bar)

Parameter Description

pLimit price
barSignal bar

This function, created by Andrew Vishnyakov (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.



IntradayFillPriorityEstimate

Syntax

public static double IntradayFillPriorityEstimate(this WealthScript ws, bool longPos, bool limit, double price, int eodBar)

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:

Example using C# extension methods:

...
if (BuyAtLimit(bar + 1,price) != null) {
	LastActivePosition.Priority = this.IntradayFillPriorityEstimate(true, true, price, bar + 1);

Legacy syntax example:


using Community.Components; // IntradayFillPriorityEstimate is here
/*** Requires installation of Community.Components Extension from www.wealth-lab.com > Extensions ***/

... // Create an instance of the PositionHelper class PositionHelper ph = new PositionHelper( this );

... for(int bar = 20; bar < Bars.Count-1; bar++) { ... if (BuyAtLimit(bar + 1,price) != null) { LastActivePosition.Priority = ph.IntradayFillPriorityEstimate(true, true, price, bar + 1); ... }



SetTimeOfDayPriority

Syntax

public static void SetTimeOfDayPriority(this WealthScript ws, IList<Position> positions, string intradayDataSet)     // baseline method syntax
public static void SetTimeOfDayPriority(this WealthScript ws, int barInterval)
public static void SetTimeOfDayPriority(this WealthScript ws, int barInterval, DataSource dataSource)

public void SetTimeOfDayPriority(IList<Position> positions, string intradayDataSet) public void SetTimeOfDayPriority(int barInterval) // This call is valid only for the Fidelity DataStore

Parameter Description

positionsPass the list of Positions that have been established to date by the Strategy.
intradayDataSetThe exact name of any intraday DataSet that corresponds to the WealthLab.DataStore provider to be used to set priorities. For example, if you were running the script on a Russell 1000 DataSet, you could specify a 1-minute intraday DataSet for the Dow 30 provided that it was a WealthLab.DataStore of 1-minute data that also contained data for the Russell 1000 symbols.
barIntervalThe intraday interval of the DataSource you want to use to set priority by time of day. This "barInterval" method call assumes the FidelityStaticProvider.

Description

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.
  • Assumes 0 Slippage
  • Automatically sets priority: Trades that occur earlier in the day are assigned higher priority
  • Works for all AtStop/AtLimit order entry types
  • Identifies probable Data Spikes in Daily data when the trade price occurs outside the range of the intraday data.

Usage Notes:
  1. Valid for scripts that trade 1-symbol only
  2. Before running the trading script, update your intraday DataSet(s), or, disable File > Update Data on Demand.
  3. Can be used with any WealthLab.DataStore intraday data (Fidelity, IQFeed, etc.)
  4. In general, following the backtest, check the debug window for status messages occurring during the priority-setting process.
  5. When a probable data spike is detected, the output is shown in Wealth-Lab's debug window. This output will also contain the OHLC/V data based on the intraday data, which you can use to manually correct the Daily bar. After making corrections, re-run the backtest. Note that Position.Priority is set to -10000 for suspected spikes. Instead of correcting the data, you could use the Position Options sizer to "Reject a Position with Priority... Less than -1700" to filter these unrealistic trades.



Example

Here is a code example to illustrate the SetTimeOfDayPriority method:

Example using C# extension methods:

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;

namespace WealthLab.Strategies { public class MyStrategy : WealthScript { protected override void Execute() { 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 */

// For Fidelity WLP users with Fidelity intraday data (only) //this.SetTimeOfDayPriority(5);

// Universal approach for any intraday data provider this.SetTimeOfDayPriority(Positions, "[i] ActiveTrader Standard Stock Portfolio (M5)"); /* Check priority - OPTIONAL! */ //int j = 0; //foreach (Position p in Positions) //{ // j++; // PrintDebug(Bars.Symbol + "\t" + j + "\t" + p.Priority + "\t" + p.EntryDate.ToShortDateString()); //} } } }


Legacy syntax example:


using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using Community.Components; // SetTimeOfDayPriority here
/*** Requires installation of Community.Components Extension from www.wealth-lab.com > Extensions ***/

namespace WealthLab.Strategies { public class MyStrategy : WealthScript { protected override void Execute() { /* Create an instance of the PositionHelper class */ 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 */

// For Fidelity WLP users with Fidelity intraday data (only) //ph.SetTimeOfDayPriority(5);

// Universal approach for any intraday data provider ph.SetTimeOfDayPriority(Positions, "[i] ActiveTrader Standard Stock Portfolio (M5)"); /* Check priority - OPTIONAL! */ //int j = 0; //foreach (Position p in Positions) //{ // j++; // PrintDebug(Bars.Symbol + "\t" + j + "\t" + p.Priority + "\t" + p.EntryDate.ToShortDateString()); //} } } }

Important Disclaimer: The information provided by Wealth-Lab is strictly for informational purposes and is not to be construed as advice or solicitation to buy or sell any security.  The owner of Wealth-Lab.com assumes no liability resulting from the use of the material contained herein for investment purposes. By using this web site, you agree to the terms of this disclaimer and our Terms of Use.


ScrewTurn Wiki. Some of the icons created by FamFamFam.