before you get too exited to implement the above trading strategy , beaware that
short selling is risky
bid ask spreads and fills at the exact open-stretch values may not be possible on all the days
the transaction costs are not included in the above calculations
why is the daily stretch value 0 sometimes?
-> because the daily stretch value is the Min of ABS(open-low,high-open) of previous day ..
The "matching high" strategy (from his book) doesn't look anything like what he posted. I chose that one because he says it's the best performing strategy.
For Amibroker:
a = abs(Ref(H,-1)-H)<1;
BuyPrice = C;
Buy = a;
SellPrice = C;
Sell = C>0;
Run this on XJO and this is how badly it performs. It's a mess. I think he's having a lend. Can't be bothered looking at the other strategies.
Thanks for the direct reply asxiq.
So if there are 10 days with the stretch value at 0, do you buy market on open in this strategy? Is the listed "open" price for XJO tradeable?
Never said any of the strategies are best performing strategies BTW ..
here is the back test performance summary since Jan 2009
http://asxiq.com/blog/when-xjo-posts-a-matching-high-candle-stick/
let me know what differences you had found with Amibroker back test results ..
No point me doing that yet.
In your data, 7/3/2011 an obvious 'matching high' on XJO isn't included. Why not? There's heaps of such examples missing from your backtest. AB returns a lot more trades than 26 trades.
the OHLC for 7th and 4th are
7- Mar 2011 4,850.70 4,852.40 4,792.30 4,797.90
4 Mar 2011 4,821.50 4,864.30 4,821.20 4,864.30
How is that a matching high ??
My iress data is same as asxiq.
imo the argument is moot as OHL for XJO is generally garbage due to staggered open. The close is the only non distorted value.
Alright my apologies to asxiq, maybe my data is out, and so is Google Finance.
The close is the Buyprice. I assume he would buy the asx200 cfd at close.
Buying on close in an ORB system?
Are there backtest result issues since it seems to be using XJO (untradeable) data? Wondering if anyone has done any similar tests on SPI that can confirm?
Year | Dollars Profit | Max closed DD |
2009 | (1755) | 6085 |
2010 | 10455 | 5760 |
2011 | 7655 | 5765 |
2012 | 3265 | 4690 |
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
#endregion
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
/// <summary>
/// By TradingCoders.com for AsiaOnTheBid - takes a bracket trade from the opening range of the day
/// </summary>
[Description("By TradingCoders.com for AsiaOnTheBid - takes a bracket trade from the opening range of the day")]
public class saOpeningRangeBreakoutV2 : Strategy
{
#region Variables
// EXTERNAL INPUT PARAMETERS
private int entryOffsetTicks = 4; // Default setting for EntryOffsetTicks
private int positionSize = 1; // Default setting for PositionSize
private int stopLossOffsetTicks = 0; // Default setting for StopLossOffsetTicks
private double profitTargetRangeMultiplier = 4; // Default setting for ProfitTargetRangeMultiplier
private double triggerTrailStopAtRangeMultiplier = 2; // Default setting for ProfitTargetRangeMultiplier
private bool profitCeasesTrading = false; // Default setting for ProfitCeasesTrading
private TimeSpan _rangeDuration = new TimeSpan(2, 0, 0);
private TimeSpan getFlatTime = new TimeSpan(15,0,0);
private bool getFlatTime_Enabled = true;
#region anaChandeKrollStop
private int anaChandeKrollStop_length = 20;
private int anaChandeKrollStop_periodATR = 10;
private double anaChandeKrollStop_multiplier = 3.0;
private anaCKCalcMode anaChandeKrollStop_calcMode = anaCKCalcMode.Arithmetic;
private anaCKShiftMode anaChandeKrollStop_shiftMode = anaCKShiftMode.Prior_Bar;
private anaChandeKrollStop _anaChandeKrollStop;
#endregion
#region g3ASR
private g3ASR _g3ASR;
private int g3ASR_period = 20;
private bool g3ASR_updateIntraday = false;
#endregion
#region Filters
private bool narrowRange_Filter = true; // requires yesterday to be the narrowest range in the last X days.
private int narrowRange_Days = 3;
private double openRange_avgDailyRangePercent = 0.7;
private bool openRange_filter = true;
private bool gapFilter = true;
private double gapFilterPercent = 0.001;
private bool _dailyAtrFilter = true;
private int _dailyAtrPeriod = 14;
private double _dailyAtrLevel = 0.01;
private double _lastDailyAtrValue = 0;
private double _dailyAtrValue = 0;
private int _dailyBarInProgress = 0;
#endregion
// INTERNAL VARIABLES
private bool myHistorical = true;
private int myHistoricalBar = -10;
private List<double> dayRanges;
private double _openingRangeHigh = 0, _openingRangeLow = 0;
private DateTime _openingRangeFromTime = DateTime.MinValue, _openingRangeToTime = DateTime.MinValue;
private double _currentSessionOpenPrice = 0;
private double _previousSessionClosePrice = 0;
private IOrder LE,SE,LS,LT,SS,ST;
private TCStrategyPlotMulti orderPlots;
private bool _triggerTrailStop = false;
#endregion
/// <summary>
/// This method is used to configure the strategy and is called once before any strategy method is called.
/// </summary>
protected override void Initialize()
{
CalculateOnBarClose = true;
TraceOrders = true;
Unmanaged = true;
MaximumBarsLookBack = MaximumBarsLookBack.Infinite;
_anaChandeKrollStop=anaChandeKrollStop(anaChandeKrollStop_calcMode, anaChandeKrollStop_length, anaChandeKrollStop_multiplier, anaChandeKrollStop_periodATR, anaChandeKrollStop_shiftMode);
Add(_anaChandeKrollStop);
if (openRange_filter)
{
_g3ASR = g3ASR(g3ASR_period, g3ASR_updateIntraday);
Add(_g3ASR);
}
if (_dailyAtrFilter)
{
if (this.BarsPeriod.BasePeriodType == PeriodType.Day && BarsPeriod.Value == 1)
{
_dailyBarInProgress = 0;
}
else
{
this.Add(PeriodType.Day, 1);
_dailyBarInProgress = 1;
}
}
orderPlots = TCStrategyPlotMulti(1,4,true);
orderPlots.Name = "OrderPlots";
orderPlots.Plots[0].Name = "StopLoss";
orderPlots.Plots[0].Pen.Color = Color.Red;
orderPlots.Plots[0].PlotStyle = PlotStyle.Hash;
orderPlots.Plots[1].Name = "Target";
orderPlots.Plots[1].Pen.Color = Color.Blue;
orderPlots.Plots[1].PlotStyle = PlotStyle.Hash;
orderPlots.Plots[2].Name = "LongEntry";
orderPlots.Plots[2].Pen.Color = Color.Gold;
orderPlots.Plots[2].PlotStyle = PlotStyle.Hash;
orderPlots.Plots[3].Name = "ShortEntry";
orderPlots.Plots[3].Pen.Color = Color.Gold;
orderPlots.Plots[3].PlotStyle = PlotStyle.Hash;
Add(orderPlots);
}
protected override void OnStartUp()
{
// do-once
ClearOutputWindow();
if (BarsPeriod.Id != PeriodType.Minute)
{
if (CurrentBar < BarsRequired + 2)
DrawTextFixed("pterror", this.Name + " requires Minute bars", TextPosition.Center, Color.Red, new Font("Tahoma", 12), Color.Red, Color.Silver, 10);
return;
}
dayRanges = new List<double>();
}
/// <summary>
/// Called on each bar update event (incoming tick)
/// </summary>
protected override void OnBarUpdate()
{
if (_dailyAtrFilter && (_dailyBarInProgress== this.BarsInProgress))
{
//daily data
_lastDailyAtrValue = _dailyAtrValue;
_dailyAtrValue = ATR(_dailyAtrPeriod)[0];
//Print(Time[0] + " Daily ATR = " + _dailyAtrValue);
return;
}
// myHistorical
if ((!Historical) || (myHistoricalBar == Count-1 && myHistoricalBar == CurrentBar))
{
myHistorical = false;
}
myHistoricalBar = CurrentBar;
if (CurrentBar < BarsRequired)
return;
// ------------
if (Bars.FirstBarOfSession)
{
//new session detected
BuildDayRangeData();
//
_openingRangeHigh = High[0];
_openingRangeLow = Low[0];
_openingRangeFromTime = Time[0];
_openingRangeToTime = _openingRangeFromTime.Add(this._rangeDuration);
_currentSessionOpenPrice = Open[0];
_previousSessionClosePrice = Close[1];
// ensure nothing funny going on with pre-existing conditions
if (getFlatTime_Enabled)
{
CancelAllOrders(true, true);
if (Position.MarketPosition != MarketPosition.Flat)
Position.Close();
}
else
{
CancelAllOrders(true, false);
}
}
if (_openingRangeHigh > 0)
{
if (Time[0].CompareTo(_openingRangeFromTime) >= 0 && Time[0].CompareTo(_openingRangeToTime) < 0)
{
if (High[0] > _openingRangeHigh) _openingRangeHigh = High[0];
}
}
if (_openingRangeLow > 0)
{
if (Time[0].CompareTo(_openingRangeFromTime) >= 0 && Time[0].CompareTo(_openingRangeToTime) < 0)
{
if (Low[0] < _openingRangeLow) _openingRangeLow = Low[0];
}
}
// detect the moment we want to put a new trade on
var startTrading = (Time[1].CompareTo(_openingRangeToTime) < 0 && Time[0].CompareTo(_openingRangeToTime) >= 0);
if (AllOrdersInactive() && startTrading && Position.MarketPosition == MarketPosition.Flat)
{
//reset all variables
_triggerTrailStop = false;
PlaceBracketOrders();
}
else if (getFlatTime_Enabled &&
(Time[0].TimeOfDay == getFlatTime
|| (Time[1].TimeOfDay < getFlatTime && Now.TimeOfDay > getFlatTime)
)
)
{
GetFlat("GetFlatTime");
}
if (Position.MarketPosition == MarketPosition.Long)
{
if (High[0]-Position.AvgPrice>=TriggerTrailStopAtRangeMultiplier*(_openingRangeHigh-_openingRangeLow))
{
_triggerTrailStop = true;
}
if (_triggerTrailStop)
{
if (Close[0] > _anaChandeKrollStop.BullStop[0] && _anaChandeKrollStop.BullStop[0] > Position.AvgPrice)
{
string oco = "";
if (OrderIsActive(LT))
{
oco = LT.Oco;
}
// stoploss
if (OrderIsActive(LS))
{
ChangeOrder(LS, Position.Quantity, LS.LimitPrice, _anaChandeKrollStop.BullStop[0]);
}
else
LS = SubmitOrder(0, OrderAction.Sell, OrderType.Stop, Position.Quantity, 0, _anaChandeKrollStop.BullStop[0], oco, "LS");
}
}
}
if (Position.MarketPosition == MarketPosition.Short)
{
if (Position.AvgPrice - Low[0]>= TriggerTrailStopAtRangeMultiplier * (_openingRangeHigh - _openingRangeLow))
{
_triggerTrailStop = true;
}
if (_triggerTrailStop)
{
if (Close[0] < _anaChandeKrollStop.BearStop[0] && _anaChandeKrollStop.BearStop[0]<Position.AvgPrice)
{
string oco = "";
if (OrderIsActive(ST))
{
oco = ST.Oco;
}
// stoploss
if (OrderIsActive(SS))
{
ChangeOrder(SS, Position.Quantity, SS.LimitPrice, _anaChandeKrollStop.BearStop[0]);
}
else
SS = SubmitOrder(0, OrderAction.BuyToCover, OrderType.Stop, Position.Quantity, 0, _anaChandeKrollStop.BearStop[0], oco, "SS");
}
}
}
// show orders
ShowOrders();
}
// =============================================================================================================================================================================================================================
private void PlaceBracketOrders()
{
if (_openingRangeLow<=0 || _openingRangeHigh<=0)
{
TCPrint("Cannot place bracket orders - incomplete range data");
return;
}
bool narrowRangeFilterOK = GetNarrowRangeFilterApproval();
if (!narrowRangeFilterOK)
{
Print(Time[0]+" Narrow Range filter prohibits trade today.");
return;
}
double range = (_openingRangeHigh - _openingRangeLow) / TickSize;
if (this.openRange_filter)
{
if (range>=this.openRange_avgDailyRangePercent*_g3ASR.AverageDailyRange[0])
{
Print(Time[0] + " anaIBRangeBandsV42MTF Filter prohibits trade today.");
return;
}
}
if (this.gapFilter)
{
double gap = (Math.Abs(_currentSessionOpenPrice - _previousSessionClosePrice))/ TickSize;
if (gap/ _previousSessionClosePrice <= gapFilterPercent)
{
Print(Time[0] + " GAP Filter prohibits trade today.");
Print(String.Format("current session open {0}, prev. session close {1} , {2} <= {3}", _currentSessionOpenPrice, _previousSessionClosePrice, gap / _previousSessionClosePrice, gapFilterPercent));
return;
}
}
if (this._dailyAtrFilter)
{
if (_dailyAtrValue/ _currentSessionOpenPrice < _dailyAtrLevel)
{
Print(Time[0] + " Daily ATR Filter prohibits trade today.");
Print(String.Format("Current daily ATR {0} / Session open price {1} < {2}", _dailyAtrValue, _currentSessionOpenPrice, _dailyAtrLevel));
return;
}
}
var longEntryPrice = rnd(_openingRangeHigh + entryOffsetTicks * TickSize);
var shortEntryPrice = rnd(_openingRangeLow - entryOffsetTicks * TickSize);
TCPrint("Placing new bracket orders to enter Long at "+longEntryPrice+" and Short at "+shortEntryPrice);
// not OCO
LE = SubmitOrder(0,OrderAction.Buy,OrderType.Stop,positionSize,0,Math.Max(longEntryPrice,GetCurrentAsk()+TickSize),GetAtmStrategyUniqueId(),"LE");
SE = SubmitOrder(0,OrderAction.SellShort,OrderType.Stop,positionSize,0,Math.Min(shortEntryPrice,GetCurrentBid()-TickSize),GetAtmStrategyUniqueId(),"SE");
}
private void GetFlat(string reason)
{
if (!AllOrdersInactive())
CancelAllOrders(true,true);
if (Position.MarketPosition != MarketPosition.Flat)
{
TCPrint("Closing position because "+reason);
Position.Close();
}
}
protected override void OnExecution(IExecution e)
{
if (e==null || e.Order == null)
return;
IOrder o = e.Order;
Print(Now+ " Execution : "+e.ToString());
if (LE!=null && o==LE)
{
double stopPrice = rnd(_openingRangeLow - stopLossOffsetTicks * TickSize);
double targetPrice = rnd(_openingRangeHigh + (_openingRangeHigh - _openingRangeLow) *profitTargetRangeMultiplier);
string oco = GetAtmStrategyUniqueId();
// stoploss
if (OrderIsActive(LS))
{
oco = LS.Oco;
ChangeOrder(LS,o.Filled,LS.LimitPrice,LS.StopPrice);
}
else
LS =SubmitOrder(0,OrderAction.Sell,OrderType.Stop,o.Filled,0,Math.Min(stopPrice,o.AvgFillPrice-TickSize),oco,"LS");
// target
if (OrderIsActive(LT))
{
ChangeOrder(LT,o.Filled,LT.LimitPrice,LT.StopPrice);
}
else
LT =SubmitOrder(0,OrderAction.Sell,OrderType.Limit,o.Filled,targetPrice,0,oco,"LT");
}
if (SE!=null && o==SE)
{
double stopPrice = rnd(_openingRangeHigh + stopLossOffsetTicks * TickSize);
double targetPrice = rnd(_openingRangeLow - (_openingRangeHigh - _openingRangeLow) *profitTargetRangeMultiplier);
string oco = GetAtmStrategyUniqueId();
// stoploss
if (OrderIsActive(SS))
{
oco = SS.Oco;
ChangeOrder(SS,o.Filled,SS.LimitPrice,SS.StopPrice);
}
else
SS =SubmitOrder(0,OrderAction.BuyToCover,OrderType.Stop,o.Filled,0,Math.Max(stopPrice,o.AvgFillPrice+TickSize),oco,"SS");
// target
if (OrderIsActive(ST))
{
ChangeOrder(ST,o.Filled,ST.LimitPrice,ST.StopPrice);
}
else
ST =SubmitOrder(0,OrderAction.BuyToCover,OrderType.Limit,o.Filled,targetPrice,0,oco,"ST");
}
// cancel the other side if a profit is hit
if (profitCeasesTrading)
{
if (ST!=null && o==ST && OrderIsActive(LE))
CancelOrder(LE);
if (LT!=null && o==LT && OrderIsActive(SE))
CancelOrder(SE);
}
}
private bool OrderIsActive(IOrder o)
{
if ( o != null
&& o.OrderState != OrderState.Cancelled
//&& o.OrderState != OrderState.PendingCancel
&& o.OrderState != OrderState.Rejected
&& o.OrderState != OrderState.Filled
)
return true;
return false;
}
private bool AllOrdersInactive()
{
return !(OrderIsActive(LE) || OrderIsActive(SE) || OrderIsActive(LS) || OrderIsActive(SS) || OrderIsActive(LT) || OrderIsActive(ST));
}
private void ShowOrders()
{
if (OrderIsActive(LS))
orderPlots.Values[0].Set(LS.StopPrice);
if (OrderIsActive(SS))
orderPlots.Values[0].Set(SS.StopPrice);
if (OrderIsActive(LT))
orderPlots.Values[1].Set(LT.LimitPrice);
if (OrderIsActive(ST))
orderPlots.Values[1].Set(ST.LimitPrice);
if (OrderIsActive(LE))
orderPlots.Values[2].Set(LE.StopPrice);
if (OrderIsActive(SE))
orderPlots.Values[3].Set(SE.StopPrice);
}
#region Narrow Range Filter
private void BuildDayRangeData()
{
double yesterday =rnd( PriorDayOHLC().PriorHigh[1] - PriorDayOHLC().PriorLow[1]);
dayRanges.Add(yesterday);
}
private bool GetNarrowRangeFilterApproval()
{
if (!narrowRange_Filter)
return true;
if (dayRanges.Count < narrowRange_Days)
return false;
double yesterday = dayRanges[dayRanges.Count-1];
double narrowest = double.MaxValue;
Print(Time[0]+" range yesterday is "+yesterday);
for (int a = 0; a< narrowRange_Days; a++)
{
double thisDay = dayRanges[dayRanges.Count -1 - a];
Print("\t range on day "+a+" is "+thisDay);
if (thisDay < narrowest)
narrowest = thisDay;
}
return (yesterday) == (narrowest);
}
#endregion
#region Miscellaneous
/// <summary>
/// formats a nice looking price
/// </summary>
/// <param name="iVal"></param>
/// <returns></returns>
private string FormatPrice(double price)
{
return Bars.Instrument.MasterInstrument.FormatPrice(price) ;
}
private void TCPrint(string info)
{
Print(Now+" "+this.Name+" "+Instrument.FullName+" "+BarsPeriod.ToString()+" "+info);
}
private double rnd(double price)
{
return (Instrument.MasterInstrument.Round2TickSize(price));
}
protected DateTime Now
{
get {
DateTime now;
if (Bars != null && Bars.MarketData != null &&
Bars.MarketData.Connection.Options.Provider == Cbi.Provider.Replay) {
now = Bars.MarketData.Connection.Now;
}
else {
now = myHistorical ? Time[0] : DateTime.Now;
}
return now;
}
}
// from anaIBRangeBandsV42MTF
public class TZListConverter : TypeConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection((TimeZoneInfo.GetSystemTimeZones()).Select(x=>x.DisplayName).ToList());
}
}
#endregion
#region 01. Basic
///<summary
///</summary>
[Description("Range duration from the session open time")]
[GridCategory("01. Basic")]
[Gui.Design.DisplayName("01. Range duration (h:min)")]
public string S_rangeDuration
{
get
{
return string.Format("{0:D2}:{1:D2}", Math.Abs(_rangeDuration.Hours), Math.Abs(_rangeDuration.Minutes));
}
set
{
char[] delimiters = new char[] { ':' };
string[] values = ((string)value).Split(delimiters, StringSplitOptions.None);
_rangeDuration = new TimeSpan(Convert.ToInt16(values[0]), Convert.ToInt16(values[1]), 0);
}
}
[Description("Price must break the opening range by THIS many ticks")]
[GridCategory("01. Basic")]
[Gui.Design.DisplayName("02. Entry offset ticks")]
public int EntryOffsetTicks
{
get { return entryOffsetTicks; }
set { entryOffsetTicks = Math.Max(1, value); }
}
[Description("Number of contracts/shares/currency")]
[GridCategory("01. Basic")]
[Gui.Design.DisplayName("03. Position size")]
public int PositionSize
{
get { return positionSize; }
set { positionSize = Math.Max(1, value); }
}
[Description("StopLoss THIS many ticks beyond other side of opening range. (negative values allowed for 'inside' the range)")]
[GridCategory("01. Basic")]
[Gui.Design.DisplayName("04. Stoploss offset ticks")]
public int StopLossOffsetTicks
{
get { return stopLossOffsetTicks; }
set { stopLossOffsetTicks = value; }
}
[Description("Profit target is THIS factor of the opening range")]
[GridCategory("01. Basic")]
[Gui.Design.DisplayName("05. Profit target range multiplier")]
public double ProfitTargetRangeMultiplier
{
get { return profitTargetRangeMultiplier; }
set { profitTargetRangeMultiplier = Math.Max(0.0100, value); }
}
[Description("Trigger trailstop when reached at X times of range in profit")]
[GridCategory("01. Basic")]
[Gui.Design.DisplayName("06. Trigger trailstop range multiplier")]
public double TriggerTrailStopAtRangeMultiplier
{
get { return triggerTrailStopAtRangeMultiplier; }
set { triggerTrailStopAtRangeMultiplier = Math.Max(0.0100, value); }
}
[Description("If a profit on the first trade is achieved, the second trade on the other side of the opening range is not taken.")]
[GridCategory("01. Basic")]
[Gui.Design.DisplayName("07. Profit ceases trading")]
public bool ProfitCeasesTrading
{
get { return profitCeasesTrading; }
set { profitCeasesTrading = value; }
}
[Description("Get flat at a set time each trading day.")]
[GridCategory("01. Basic")]
[Gui.Design.DisplayName("08. GetFlatTime Enabled")]
public bool GetFlatTime_Enabled
{
get { return getFlatTime_Enabled; }
set { getFlatTime_Enabled = value; }
}
///<summary
///</summary>
[Description("Enter a chart bar time when any open trade must close.")]
[GridCategory("01. Basic")]
[Gui.Design.DisplayName("09. GetFlatTime (h:min)")]
public string S_GetFlatTime
{
get
{
return string.Format("{0:D2}:{1:D2}", Math.Abs(getFlatTime.Hours), Math.Abs(getFlatTime.Minutes));
}
set
{
char[] delimiters = new char[] {':'};
string[]values =((string)value).Split(delimiters, StringSplitOptions.None);
getFlatTime = new TimeSpan(Convert.ToInt16(values[0]),Convert.ToInt16(values[1]),0);
}
}
#endregion
#region 02. Filters
[Description("Requires yesterday to be the narrowest range within the last X days")]
[GridCategory("02. Filters")]
[Gui.Design.DisplayName("01.01 Use NarrowRange Filter")]
public bool NarrowRange_Filter
{
get { return narrowRange_Filter; }
set { narrowRange_Filter = value; }
}
[Description("Requires yesterday to be the narrowest range within the last THIS many days")]
[GridCategory("02. Filters")]
[Gui.Design.DisplayName("01.02 NarrowRange Filter Days")]
public int NarrowRange_Days
{
get { return narrowRange_Days; }
set { narrowRange_Days = Math.Max(2, value); }
}
[Description("Filter out trades where the 'open range' is greater than a certain % of the Average Daily Range")]
[GridCategory("02. Filters")]
[Gui.Design.DisplayName("02.01 Use Open Range Filter")]
public bool OpenRange_Filter
{
get { return openRange_filter; }
set { openRange_filter = value; }
}
[Description("Filter out trades where the 'open range' is greater than a certain % of the Average Daily Range")]
[GridCategory("02. Filters")]
[Gui.Design.DisplayName("02.02 % Average Daily Range")]
public double OpenRange_AverageTrueRangePercent
{
get { return this.openRange_avgDailyRangePercent; }
set { openRange_avgDailyRangePercent = value; }
}
[Description("filter trades based on the % GAP open")]
[GridCategory("02. Filters")]
[Gui.Design.DisplayName("03.01 Use GAP Filter")]
public bool GAP_Filter
{
get { return gapFilter; }
set { gapFilter = value; }
}
[Description("% GAP open (GAP as defined from prior close to open).")]
[GridCategory("02. Filters")]
[Gui.Design.DisplayName("03.02 % GAP Filter")]
public double GAP_Filter_Percent
{
get { return gapFilterPercent; }
set { gapFilterPercent = value; }
}
[Description("")]
[GridCategory("02. Filters")]
[Gui.Design.DisplayName("04.01 Use Daily ATR Filter")]
public bool DailyAtrFilter
{
get { return _dailyAtrFilter; }
set { _dailyAtrFilter = value; }
}
[Description("")]
[GridCategory("02. Filters")]
[Gui.Design.DisplayName("04.02 Daily ATR Period")]
public int DailyAtrPeriod
{
get { return _dailyAtrPeriod; }
set { _dailyAtrPeriod = Math.Max(1,value); }
}
[Description("")]
[GridCategory("02. Filters")]
[Gui.Design.DisplayName("04.03 Daily ATR Minimum Level %")]
public double DailyAtrLevel
{
get { return _dailyAtrLevel; }
set { _dailyAtrLevel = value; }
}
#endregion
#region 03. Average Daily Range
[Description("Period for Average")]
[GridCategory("03. Average Daily Range")]
[NinjaTrader.Gui.Design.DisplayName("Period for average")]
public int G3ASR_Period
{
get { return g3ASR_period; }
set { g3ASR_period = Math.Max(1, value); }
}
[Description("If true updates average session during day, false only at the beginning of the session")]
[GridCategory("03. Average Daily Range")]
[NinjaTrader.Gui.Design.DisplayName("Update average intraday?")]
public bool G3ASR_UpdateIntraday
{
get { return g3ASR_updateIntraday; }
set { g3ASR_updateIntraday = value; }
}
#endregion
#region 04. Trailstop
/// <summary>
/// </summary>
[Description("ATR period")]
[GridCategory("04. Trailstop")]
[Gui.Design.DisplayName("ATR period")]
public int AnaChandeKrollStop_PeriodATR
{
get { return anaChandeKrollStop_periodATR; }
set { anaChandeKrollStop_periodATR = Math.Max(1, value); }
}
/// <summary>
/// </summary>
[Description("Lookback period for trailing stop")]
[GridCategory("04. Trailstop")]
[Gui.Design.DisplayName("Reference period")]
public int AnaChandeKrollStop_Length
{
get { return anaChandeKrollStop_length; }
set { anaChandeKrollStop_length = Math.Max(1, value); }
}
/// <summary>
/// </summary>
[Description("ATR multiplier")]
[GridCategory("04. Trailstop")]
[Gui.Design.DisplayName("ATR multiplier")]
public double AnaChandeKrollStop_Multiplier
{
get { return anaChandeKrollStop_multiplier; }
set { anaChandeKrollStop_multiplier = Math.Max(0.0, value); }
}
/// <summary>
/// </summary>
[Description("Selects the formula for calculating the average true range.")]
[GridCategory("04. Trailstop")]
[Gui.Design.DisplayName("ATR formula")]
public anaCKCalcMode AnaChandeKrollStop_CalcMode
{
get { return anaChandeKrollStop_calcMode; }
set { anaChandeKrollStop_calcMode = value; }
}
/// <summary>
/// </summary>
[Description("Selects the bars for which the average true range is calculated")]
[GridCategory("04. Trailstop")]
[Gui.Design.DisplayName("Stops calculated from")]
public anaCKShiftMode AnaChandeKrollStop_ShiftMode
{
get { return anaChandeKrollStop_shiftMode; }
set { anaChandeKrollStop_shiftMode = value; }
}
#endregion
}
}
Open Range Breakout Fade with a 'twist'. Need more OOS data. I'll just test it forward for now. This is the DAX, not the XJO.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?