ExecControl.Recalculate() error  [SOLVED]

Questions about MultiCharts .NET and user contributed studies.
eroleyikan
Posts: 22
Joined: 01 Jun 2016
Has thanked: 4 times
Been thanked: 6 times

ExecControl.Recalculate() error  [SOLVED]

Postby eroleyikan » 15 Jun 2016

Hello,
My strategy is generating the below error message upon executing the
ExecControl.Recalculate();
line (ie, this is the line 377 that is mentioned in the error message).
The code in the last bar calculation is running fine on its own. When the error occurs, the code execution does not even get into the CalcBar() method. What are the reasons why the recalculate call would fail like this?
Thank you

Here is the error message:
ManagedStudies.details._ELAPI_exception_Wrap_: Error in the application.
at ManagedStudies.details._ELAPI_exception_Wrap_Generator.raise(_ELAPI_exception_Wrap_Generator* )
at PowerLanguage.CExecutionControl.Recalculate()
at PowerLanguage.Strategy.EE_RTraderV3_6.OnRecalcLastBarAfterEvent() in c:\ProgramData\TS Support\MultiCharts .NET64\StudyServer\Techniques\CS\EE_RTraderV3_6.Strategy.CS:line 377 Exception caught.

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

Re: ExecControl.Recalculate() error

Postby Henry MultiСharts » 16 Jun 2016

Hello eroleyikan,

You do not need to catch this exception as it is an internal message for the system.

eroleyikan
Posts: 22
Joined: 01 Jun 2016
Has thanked: 4 times
Been thanked: 6 times

Re: ExecControl.Recalculate() error

Postby eroleyikan » 16 Jun 2016

Thanks Henry.
I can do that, but I will still have the problem of my strategy not recalculating.

I would like my strategy to recalculate based on real-time price conditions. I implemented the DataLoader example from the programming guide. I can get the current price of the symbol I am on. I want to be able to recalculate the strategy if a certain condition about the current price is true.

My sample code is below. As you can see in ResultCallBack() method, when real-time price is greater than the last price, the strategy should recalculate. But it does not.

What do you think is wrong?
Thanks
Erol

Code: Select all

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

namespace PowerLanguage.Strategy
{
public class EE_Test_Price_Adjust_v3 : SignalObject
{
public EE_Test_Price_Adjust_v3(object _ctx) : base(_ctx) { }
private IOrderMarket buy_order;
private IOrderPriced sell_Stop_1;
private double Point;
private int count = 0;
private double LastPrice;
private IDataLoaderResult iRes;
bool isLoaded = false;

protected override void Create()
{
buy_order = OrderCreator.MarketThisBar(new SOrderParameters(Contracts.UserSpecified, EOrderAction.Buy));
sell_Stop_1 = OrderCreator.Stop(new SOrderParameters(Contracts.UserSpecified, "Sell 3", EOrderAction.Sell, OrderExit.Total));
}

protected override void CalcBar()
{
//initiate loading real time data
int CurrentBar = Bars.CurrentBar + ExecInfo.MaxBarsBack;
if (Bars.CurrentBar == 9)
{
isLoaded = false;
InstrumentDataRequest Req = Bars.Request;
Req.Resolution = new Resolution { Size = 1, Type = EResolution.Tick };
Req.Range = DataRequest.CreateBarsBack(DateTime.Now, 10);
Req.FilterOutOfRangeData = true;
Output.WriteLine("My Request: 10 To {0}", DateTime.Now);
Req.Subscribe2RT = true;
iRes = DataLoader.BeginLoadData(Req, ResultCallback, null);
}

if (Bars.LastBarOnChart)
{
Point = Bars.Info.ASymbolInfo2.MinMove / Bars.Info.ASymbolInfo2.PriceScale;
buy_order.Send(4000);
sell_Stop_1.Send(Bars.Close[0] - (count + 10 ) * Point, 4000);
Output.WriteLine("In lastbar code " );
}
}

void ResultCallback(IDataLoaderResult Result)
{
if (Result.RTData != null)
{
Bar rt = Result.RTData.Value;

Output.WriteLine("In ResltCallBack() Current Price: " + rt.Close + " Last Price: " + LastPrice);

if (rt.Close > LastPrice)
{
LastPrice = rt.Close;
Output.WriteLine(" rt.Close > LastPrice is true. ");
count = count + 1;
ExecControl.Recalculate();
}
}
}
}
}

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

Re: ExecControl.Recalculate() error

Postby Henry MultiСharts » 17 Jun 2016

Recalculate should be called from the CalcBar.

eroleyikan
Posts: 22
Joined: 01 Jun 2016
Has thanked: 4 times
Been thanked: 6 times

Re: ExecControl.Recalculate() error

Postby eroleyikan » 17 Jun 2016

Henry,
Thanks for your response, I am not clear though... calcBar is what gets re-run when the recalculate command is issued, is it not? How does it make sense to call recalculate() from withing calcBar?

Can you point to an example or thread that demonstrates this behavior?
Thank you
Erol

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

Re: ExecControl.Recalculate() error

Postby Henry MultiСharts » 17 Jun 2016

Here is a sample code for you:

Code: Select all

protected override void StartCalc()
{
needRecalc = false;
}

protected override void CalcBar()
{
if (needRecalc)
ExecControl.Recalculate();

// ...............
}

bool needRecalc;
void ResultCallback(IDataLoaderResult Result)
{
// .........

needRecalc = true;

//...........
}

eroleyikan
Posts: 22
Joined: 01 Jun 2016
Has thanked: 4 times
Been thanked: 6 times

Re: ExecControl.Recalculate() error

Postby eroleyikan » 20 Jun 2016

Thanks Henry, this is working without an error now. But the last bar code is getting executed multiple times every second even though I am setting needRecalc = false each time.
In the example code below, I tried to recalculate only ONCE when the price changes but the lastbar code seems to run 4 or 5 times each iteration. What event is kicking off this repetition?


As an example, the code below is generating an output like this:

rt.Close != LastPrice is true.
In ResltCallBack() Current Price: 78.105 Last Price: 78.104 rt.time: 9:15 AM
In lastbar code 09:14:24 AM
In lastbar code 09:14:24 AM
In lastbar code 09:14:24 AM
In lastbar code 09:14:24 AM
In lastbar code 09:14:24 AM
In lastbar code 09:14:24 AM

rt.Close != LastPrice is true.
In ResltCallBack() Current Price: 78.106 Last Price: 78.105 rt.time: 9:15 AM
rt.Close != LastPrice is true.
In ResltCallBack() Current Price: 78.105 Last Price: 78.106 rt.time: 9:15 AM
In lastbar code 09:14:25 AM
In lastbar code 09:14:25 AM
In lastbar code 09:14:25 AM
In lastbar code 09:14:25 AM


Here is the code that goes with this output:

Code: Select all

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

namespace PowerLanguage.Strategy
{
[IOGMode(IOGMode.Enabled)]
public class EE_Test_Price_Adjust_v5 : SignalObject
{
public EE_Test_Price_Adjust_v5(object _ctx) : base(_ctx) { }
private IOrderMarket buy_order;
private IOrderPriced sell_Stop_1;
private double Point;
private int count = 0;
private double LastPrice;
private DateTime LastPriceUpdateTime;
private IDataLoaderResult iRes;
bool isLoaded = false;
private bool needRecalc = false;

protected override void Create()
{
buy_order = OrderCreator.MarketThisBar(new SOrderParameters(Contracts.UserSpecified, EOrderAction.Buy));
sell_Stop_1 = OrderCreator.Stop(new SOrderParameters(Contracts.UserSpecified, "Sell 3", EOrderAction.Sell, OrderExit.Total));
}

protected override void StartCalc()
{
needRecalc = false;
}

protected override void CalcBar()
{
if (needRecalc)
{
needRecalc = false;
ExecControl.Recalculate();
}
//initiate loading real time data
//int CurrentBar = Bars.CurrentBar + ExecInfo.MaxBarsBack;
//if (Bars.CurrentBar == 9 && isLoaded == false)
if (Bars.CurrentBar == 1 && isLoaded == false)
{
isLoaded = true;
InstrumentDataRequest Req = Bars.Request;
Req.Resolution = new Resolution { Size = 1, Type = EResolution.Minute };
Req.Range = DataRequest.CreateBarsBack(DateTime.Now, 1);
Req.FilterOutOfRangeData = true;
Output.WriteLine("My Request: 10 To {0}", DateTime.Now);
Req.Subscribe2RT = true;
iRes = DataLoader.BeginLoadData(Req, ResultCallback, null);
}

if (Bars.LastBarOnChart )
{
needRecalc = false;
Point = Bars.Info.ASymbolInfo2.MinMove / Bars.Info.ASymbolInfo2.PriceScale;
buy_order.Send(4000);
sell_Stop_1.Send(Bars.Close[0] - (count + 10 ) * Point, 4000);
Output.WriteLine("In lastbar code " + DateTime.Now.ToString("HH:mm:ss tt"));
}

}

void ResultCallback(IDataLoaderResult Result)
{
if (Result.RTData != null)
{
Bar rt = Result.RTData.Value;
if (rt.Close != LastPrice) //&& rt.Time != LastPriceUpdateTime
{
Output.WriteLine(" rt.Close != LastPrice is true. ");
Output.WriteLine("In ResltCallBack() Current Price: " + rt.Close + " Last Price: " + LastPrice + " rt.time: " + rt.Time.ToShortTimeString());
LastPrice = rt.Close;
LastPriceUpdateTime = rt.Time;

count = count - 1;
needRecalc = true;

}
}
}
}
}
thanks
Erol

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

Re: ExecControl.Recalculate() error

Postby Henry MultiСharts » 20 Jun 2016

You can output the CalculationReason to check it.

eroleyikan
Posts: 22
Joined: 01 Jun 2016
Has thanked: 4 times
Been thanked: 6 times

Re: ExecControl.Recalculate() error

Postby eroleyikan » 20 Jun 2016

The calcreason says "Default".
changed the code so that the needRecalc is set to true only if the price moves more than a point. That works, but the lastbar keeps recalculating what appears to be at every tick.
Is there any way to control this?

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

Re: ExecControl.Recalculate() error

Postby Henry MultiСharts » 21 Jun 2016

eroleyikan, you can turn off the IOG:
https://www.multicharts.com/trading-sof ... Calculated

eroleyikan
Posts: 22
Joined: 01 Jun 2016
Has thanked: 4 times
Been thanked: 6 times

Re: ExecControl.Recalculate() error

Postby eroleyikan » 29 Jun 2016

Thanks for everyone's help. I finalized my code. I thought I would post back a summary of the final solution in case it would be helpful for others.

Functionality: place one entry order and a pair of stop and limit orders ALL at the same time at the end of a bar. Then, during the next bar update the prices of the stop limit orders as needed.

How I did it:
I stopped using the Recalculate() function. When IOG mode is set to enabled, recalculate() call is not required. Bars recalculate every tick.
[IOGMode(IOGMode.Enabled)]

Then in the CalcBar() method, I placed all the code that I need to execute ONCE per bar in IF statement such as:
if (Bars.CurrentBar > 1 && Bars.Status == EBarState.Close)

EBarState.Close executes the code at the last tick of the bar.

I placed by order generation code inside an if statement such as
if (Bars.LastBarOnChart)
so the orders are sent/updated every tick. But the prices don't change every tick. So orders stay the same until I updated the stop/limit prices in the ResultCallback() function as needed.

Of course, if you update the stop/limit prices too often you would have a problem. So I modified the ResultCallBack() method to check the current market every 30 seconds for a certain amount of price change. Here is the code:

Code: Select all

void ResultCallback2(IDataLoaderResult Result)
{
if (DateTime.Now > LastPriceUpdateTime.AddSeconds(30))
{
if (Result.RTData != null)
{
Bar rt = Result.RTData.Value;
if (Math.Abs(rt.Close - LastPrice) > Point)
{
LastPrice = rt.Close;
//......other strategy specific code
}

}
}
}
I hope this is helpful. Let me know if you have any questions.


Return to “MultiCharts .NET”