The events are happening asynchronously, i.e. once MultiCharts has information regarding position change at broker it calls OnBrokerPositionChange event, while internal variables are not yet updated with this info. If you add a timeout before output (for example 100 ms (System.Threading.Thread.Sleep(100);)) - variables will be already updated. You can try playing around with the timeout value - it can be less for powerful PCs.
Hmm, is there a workaround for this?
Even with a basic test strategy, see below, that trades one LMAX instrument (30 seconds chart) I have to set the `Thread.Sleep()` to 4000 (4 seconds!) before the output is correct. This is with one trading strategy active on a one-year old pc, so I would be surprised if the pc can't keep up.
(Edit: Even with the sleep set to 4 seconds, the OnBrokerPositionChange() info is sometimes still lagging, so it might even need to be set higher than 4).
Edit 2: This is the output with a five second Sleep:
Code: Select all
----------------------------
20:22:32.941 - Submit buy order
20:22:38.112 - MP signal: 0, MP broker: 0
Entry price signal: 0, entry price broker: 0
----------------------------
20:23:32.796 - Submit sell (exit long) order
20:23:37.964 - MP signal: 1, MP broker: 1
Entry price signal: 1,26094, entry price broker: 1,26094
----------------------------
The time stamp show that the strategy properties are still not updated after five seconds:
Five seconds after the buy order, there was still no position according to PowerLanguage .NET. But the filled time stamp in the OPT for this trade is 20:22:33 (4 seconds before the output).
Five seconds after the sell order, there was still an open position according to PowerLanguage .NET. But the time stamp (from the OPT) says this order was completed at 20:23:33 (almost four seconds before the output).
Code: Select all
using System;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;
using ATCenterProxy.interop;
namespace PowerLanguage.Strategy
{
public class Practice_AlertBrokerPositionChange : SignalObject
{
private IOrderMarket buyOrder, sellOrder;
public Practice_AlertBrokerPositionChange(object _ctx) : base(_ctx) { }
private double avgEntryPriceBroker, marketPosBroker;
protected override void Create()
{
buyOrder = OrderCreator.MarketNextBar(new SOrderParameters(
Contracts.Default, EOrderAction.Buy));
sellOrder = OrderCreator.MarketNextBar(new SOrderParameters(
Contracts.Default, EOrderAction.Sell));
}
protected override void CalcBar()
{
if (!Environment.IsAutoTradingMode || !Bars.LastBarOnChart)
{
Output.Clear();
return;
}
if ((StrategyInfo.MarketPosition > 0) && (Bars.CurrentBar % 4 == 0))
{
sellOrder.Send();
Output.WriteLine("{0} - Submit sell (exit long) order",
DateTime.Now.ToString("HH:mm:ss.fff"));
}
else if ((StrategyInfo.MarketPosition == 0) && (Bars.CurrentBar % 2 == 0))
{
buyOrder.Send();
Output.WriteLine("{0} - Submit buy order",
DateTime.Now.ToString("HH:mm:ss.fff"));
}
}
protected override void OnBrokerPositionChange()
{
System.Threading.Thread.Sleep(4000); // 3000 does not work
Output.WriteLine("{0} - MP signal: {1}, MP broker: {2}\r\n" +
"Entry price signal: {3}, entry price broker: {4}",
DateTime.Now.ToString("HH:mm:ss.fff"),
StrategyInfo.MarketPosition,
StrategyInfo.MarketPositionAtBrokerForTheStrategy,
StrategyInfo.AvgEntryPrice,
StrategyInfo.AvgEntryPriceAtBrokerForTheStrategy);
Output.WriteLine("----------------------------");
}
}
}