Begin time of strategy & max bars back setting  [SOLVED]

Questions about MultiCharts .NET and user contributed studies.
User avatar
JoshM
Posts: 2195
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1544 times
Been thanked: 1565 times
Contact:

Begin time of strategy & max bars back setting

Postby JoshM » 05 Aug 2012

I have the following in a strategy:

Code: Select all

private TimeSpan beginTime = new TimeSpan(6, 0, 0);

private XAverage quickMAfunction;
private XAverage slowMAFunction;

protected override void Create()
{
quickMAfunction = new XAverage(this);
slowMAFunction = new XAverage(this);
}

protected override void CalcBar()
{
quickMAfunction.Price = Bars.Close;
slowMAFunction.Price = Bars.Close;

if (Bars.TimeValue.TimeOfDay < beginTime) // Return if time is before begin time
return;
}
I expected that this code would cause the strategy to start submitting orders when a) an entry condition occurred and b) as soon as the time is beyond 6:00.

That's not the case, since the strategy starts after the MaxBarsBack number of bars have passed since 6:00:00.

If I include the TimeOfDay check in the entry conditions, like

Code: Select all

if (Bars.TimeValue.TimeOfDay >= beginTime &&
PublicFunctions.DoubleGreater(quickMAfunction[0], slowMAFunction[0]) &&
PublicFunctions.DoubleLess(quickMAfunction[1], slowMAFunction[1]))
{
// ..
}
the orders still aren't generated until the MaxBarsBack setting number of bars after 6:00:00. In other words, if the MaxBarsBack is set to 50, on bar 50 after 6:00 the first orders are submitted, even if the enter long conditions happen already before that.

My question: how can I give a strategy a begin time without this MaxBarsBack limitation? So that orders can be submitted directly after the begin time has passed, and not after MaxBarsBack number of bars have passed after the begin time?

User avatar
Henry MultiСharts
Posts: 9165
Joined: 25 Aug 2011
Has thanked: 1264 times
Been thanked: 2957 times

Re: Begin time of strategy & max bars back setting

Postby Henry MultiСharts » 06 Aug 2012

Hello Josh,

Please send me a complete sample code for reproducing this behavior and the workspace you are using to support@multicharts.com

User avatar
JoshM
Posts: 2195
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1544 times
Been thanked: 1565 times
Contact:

Re: Begin time of strategy & max bars back setting  [SOLVED]

Postby JoshM » 07 Aug 2012

I haven't been able to replicate this behavior, and it's probably/almost certainly caused by the use of return in conjunction with not using a VariableSeries<Double> to store the EMA values in.

In the wrong code, I called the PublicFunctions.DoubleGreater() and PublicFunctions.DoubleLess() on the two instances of the XAverage() object (ema quick & ema slow). That went "good" untill the return keyword was used, which was triggered every day till 6:00 am. Since there was no VariableSeries<Double> in which the EMA values were stored, every day from 6 am onward the ema quick & ema slow values had to be repopulated again with new values until MaxBarsBack + 1 before the first trade could be made.

That explains why it looked that the strategy "waited" every day till the MaxBarsBack has passed, and why changing the MaxBarsBack to a lower value caused the strategy to respond much earlier.

The correct code is below - nothing fancy but just as an update and a small example of using TimeSpan() to define times when the strategy should close positions or should start trading.

Code: Select all

using System;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;
using ATCenterProxy.interop;

namespace PowerLanguage.Strategy
{
public class MACrossOver_Test : SignalObject
{
public MACrossOver_Test(object _ctx):base(_ctx){}

// Strategy variables
private int quickMa = 9;
private int slowMA = 20;
private int posSize = 5000;
private TimeSpan exitTime = new TimeSpan(22, 00, 00);
private TimeSpan beginTime = new TimeSpan(6, 0, 0);

// Strategy objects
private XAverage quickMAfunction;
private XAverage slowMAFunction;
private VariableSeries<Double> m_fastEMA;
private VariableSeries<Double> m_slowEMA;

// Strategy inputs
[Input]
public int LengthMA1
{
get { return quickMa; }
set { quickMa = value; }
}

[Input]
public int LengthMA2
{
get { return slowMA; }
set { slowMA = value; }
}

// Orders
private IOrderMarket buy_order;
private IOrderMarket sell_order;
private IOrderMarket short_order;
private IOrderMarket cover_order;

// create variable objects, function objects, order objects etc.
protected override void Create()
{
buy_order = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.UserSpecified, "MACrossLE", EOrderAction.Buy));
sell_order = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.UserSpecified, "MACrossXL", EOrderAction.Sell));
short_order = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.UserSpecified, "MACrossSE", EOrderAction.SellShort));
cover_order = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.UserSpecified, "MACrossXS", EOrderAction.BuyToCover));

quickMAfunction = new XAverage(this);
slowMAFunction = new XAverage(this);
m_fastEMA = new VariableSeries<Double>(this);
m_slowEMA = new VariableSeries<Double>(this);
}

// Assign inputs
protected override void StartCalc()
{
Output.Clear();

quickMAfunction.Length = quickMa;
slowMAFunction.Length = slowMA;

quickMAfunction.Price = Bars.Close;
slowMAFunction.Price = Bars.Close;
m_fastEMA.DefaultValue = 0;
m_slowEMA.DefaultValue = 0;
}

// Strategy logic
protected override void CalcBar()
{
m_fastEMA.Value = quickMAfunction[0];
m_slowEMA.Value = slowMAFunction[0];

if (Bars.TimeValue.TimeOfDay < beginTime) // Return if time is before begin time
{
return;
}

// Enter long
if (PublicFunctions.DoubleGreater(m_fastEMA[0], m_slowEMA[0]) &&
PublicFunctions.DoubleLess(m_fastEMA[1], m_slowEMA[1]))
{
buy_order.Send(posSize);
}

// Enter short
if (PublicFunctions.DoubleLess(m_fastEMA[0], m_slowEMA[0]) &&
PublicFunctions.DoubleGreater(m_fastEMA[1], m_slowEMA[1]))
{
short_order.Send(posSize);
}

// Manage open positions
if (StrategyInfo.MarketPosition != 0)
{

// Exit long
if (PublicFunctions.DoubleLess(m_fastEMA[0], m_slowEMA[0]) || Bars.TimeValue.TimeOfDay >= exitTime)
{
sell_order.Send(posSize);
}

// Exit short
if (PublicFunctions.DoubleGreater(m_fastEMA[0], m_slowEMA[0]) || Bars.TimeValue.TimeOfDay >= exitTime)
{
cover_order.Send(posSize);
}
}

}
}
}


Return to “MultiCharts .NET”