MultiCharts .NET attributes that affect a strategy’s order behaviour include IOGMode
for submitting orders intra-bar and ExitFromOneEntryOnce
for reusing an exit order numerous times. But these attributes still require real-time ticks to occur before orders can be submitted. How can we submit orders whenever we want?
Sending orders for any script calculation with AllowSendOrdersAlways
A C# attribute is a way to add metadata to code elements like classes (Dorman, 2010) and doing so influences how these operate (e.g., see Stephens, 2014). Such attributes are used in MultiCharts .NET to set script options programmatically.
One of these attributes is AllowSendOrdersAlways
(see PowerLanguage .NET Help, n.d.). When this attribute is set to true, autotrading orders can always be generated – even when a symbol’s bar status is -1 or the equivalent EBarState.None
enum value (see Henry MultiCharts, 2014; MultiCharts Wiki, 2014a; PowerLanguage .NET Help, n.d.).
Bar status in MultiCharts .NET explained: open, inside, close, or none
A symbol’s bar status indicates the status of the current price in the bar of the specified data series that’s currently processed by the script (see MultiCharts, 2014; MultiCharts Wiki, 2014b). For example, when the primary data series’ current tick is the bar’s closing price, then Bars.Status
returns EBarState.Close
(see PowerLanguage .NET Help, n.d.).
Other bar status values are EBarState.Open
(for opening ticks), EBarState.Inside
(for ticks that are within a bar), and EBarState.None
for undefined bar statuses (MultiCharts Wiki, 2014b; PowerLanguage .NET Help, n.d.). Those undefined bar statuses can happen in two situations: when a script periodically recalculates with RecalcLastBarAfter()
while the bar is closed and no opening tick has been received yet or when bars from multiple data series don’t align (Henry MultiCharts, 2012, 2014; MultiCharts Support, personal communication, February 10, 2015).
When a bar status is not defined (EBarState.None
), orders cannot be send by design (Henry MultiCharts, 2012). But that behaviour can be changed with the AllowSendOrdersAlways
attribute so that orders can be submitted at any time.
Setting the AllowSendOrdersAlways attribute in MultiCharts .NET
Set AllowSendOrdersAlways
to true to allow orders to be generated always:
[AllowSendOrdersAlways(true)] public class Example_AllowSendOrdersAlways : SignalObject { // Strategy code }
And set the attribute to false to only submit orders during the opening, inside, or closing status of a price bar:
[AllowSendOrdersAlways(false)] public class Example_AllowSendOrdersAlways : SignalObject { // Strategy code }
The default behaviour of no order generation for undefined bar statuses applies when the attribute is missing from the code (see MultiCharts Wiki, 2014a). There’s no manual option for AllowSendOrdersAlways
— it can only be set programmatically.
Example: using AllowSendOrdersAlways to generate orders on illiquid instruments
One benefit of AllowSendOrdersAlways
is that orders on relatively illiquid instruments can be generated with periodic script recalculations instead of having to wait for a new tick. An example of this is EUR/CZK:

Sending orders with periodic script recalculations can be done as follows:
[AllowSendOrdersAlways(true), IOGMode(IOGMode.Enabled)] public class Example_AllowSendOrdersAlways : SignalObject { public Example_AllowSendOrdersAlways(object _ctx) : base(_ctx) { } private IOrderMarket marketBuy, marketSell; protected override void Create() { marketBuy = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, EOrderAction.Buy)); marketSell = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, EOrderAction.Sell)); } int counter = 0, noneBars = 0; protected override void CalcBar() { if (Environment.CalcReason == CalculationReason.Timer) { if (StrategyInfo.MarketPosition == 0) { Output.WriteLine("BarStatus: {0}. Number of None bars: {1}." + " Submitting buy order", Bars.Status, noneBars); marketBuy.Send(); counter = 0; } if (StrategyInfo.MarketPosition > 0 && counter > 25) { Output.WriteLine("BarStatus: {0}. Number of None bars: {1}." + " Submitting sell order", Bars.Status, noneBars); marketSell.Send(); } counter++; } if (Bars.Status == EBarState.None) noneBars++; ExecControl.RecalcLastBarAfter(new TimeSpan(0, 0, 1)); } protected override void OnRecalcLastBarAfterEvent() { this.CalcBar(); } //> BarStatus: None. Number of None bars: 482\. Submitting buy order //> BarStatus: None. Number of None bars: 513\. Submitting buy order //> BarStatus: None. Number of None bars: 544\. Submitting buy order //> BarStatus: None. Number of None bars: 575\. Submitting buy order //> BarStatus: Inside. Number of None bars: 577\. Submitting sell order }
We start with setting AllowSendOrdersAlways
to true. This attribute also requires intra-bar order generation (Andrew MultiCharts, 2014) because otherwise orders would only be generated on bar close (EBarState.Close
), and so the IOGMode
attribute is also enabled. Then two IOrderMarket
market orders are declared (marketBuy
and marketSell
), which are subsequently created in the Create()
method.
After that two integer variables are declared and set to zero: counter
will keep track of the number of periodic recalculations and is used for the exit, while noneBars
will count the number of script calculations with a EBarState.None
undefined bar status. This latter gives an idea of the amount of script calculations on which we normally couldn’t send an order.
Calculating the strategy and submitting orders in MultiCharts .NET
The strategy’s logic is implemented in the CalcBar()
method. In it we begin with an if statement that checks if the script’s calculation reason (Environment.CalcReason
) equals CalculationReason.Timer
, which it does when a periodic recalculation is performed. We deliberately check for this condition because it increases the odds of coming across EBarState.None
so that AllowSendOrdersAlways
’s effect can be noticed.
Inside that if statement a nested if statement checks whether there’s no open market position, in which case StrategyInfo.MarketPosition
returns 0 (see MultiCharts, 2014). When flat, the bar status of the primary data series (Bars.Status
) and the number of undefined bar statuses (noneBars
) is outputted to the PowerLanguage .NET Editor. The marketBuy
order is then submitted with its Send()
method and the counter
variable is reset to zero so that it can start counting towards the exit.
The exit order is submitted when there’s an open long position (StrategyInfo.MarketPosition
will then return a positive value larger than 0; MultiCharts, 2014) and counter
is greater than 25. Then we again output data with Output.WriteLine()
before calling the sell order’s Send()
method.
Below that nested if statement the counter
variable is incremented with 1 with the postfix increment operator (++
) and an if statement checks whether the current bar status equals an undefined bar status (EBarState.None
). When it does, the noneBars
variable is also increased with 1.
Periodically recalculating a strategy in MultiCharts .NET
The script’s periodic recalculation is done by calling the ExecControl.RecalcLastBarAfter()
method with a TimeSpan
of 1 second. After this time interval has elapsed, MultiCharts .NET will execute the OnRecalcLastBarAfterEvent()
method (PowerLanguage .NET Help, n.d.). And in that method we execute CalcBar()
again by calling it with the this
keyword, which refers to the current instance of an object (Liberty & MacDonald, 2009) that is in this case our Example_AllowSendOrdersAlways
example strategy.
This periodic recalculation ensures that the strategy is calculated every so often even with the absence of incoming real-time ticks, which enables the strategy to send orders during ‘slow’ periods or on relatively illiquid instruments.
Other MultiCharts .NET attributes that change how a trading strategy’s orders operate are CalcAtOpenNextBar, IOGMode, and ExitFromOneEntryOnce.
Summary
With the AllowSendOrdersAlways
attribute orders can be submitted at any time, even when a bar’s status is undefined due to a script’s recalculation before a new bar has formed or when data series bars are unaligned.
Want to learn more about C#, the programming language that drives MultiCharts .NET? Checkout my C# programming tutorials.
References
Andrew MultiCharts (2014, April 16). Code on to cancel orders at session end before after hours – forum discussion. Retrieved on February 5, 2015, from http://www.multicharts.com/discussion/viewtopic.php?f=1&t=46449#p104194
Dorman, S. (2010). Sams Teach Yourself Visual C# 2010 in 24 Hours. Indianapolis, IN (USA): Sams/Pearson Education.
Henry MultiCharts (2012, August 1). closing status of a bar sometimes takes too long – forum discussion. Retrieved on February 5, 2015, from http://www.multicharts.com/discussion/viewtopic.php?f=1&t=10642#p52424
Henry MultiCharts (2014, September 9). What in the world could be wrong with this picture?! – forum discussion. Retrieved on February 5, 2015, from http://www.multicharts.com/discussion/viewtopic.php?f=1&t=46827#p108056
Liberty, J. & MacDonald, B. (2009). Learning C# 3.0: Master the Fundamentals of C# 3.0. Sebastopol, CA: O’Reilly Media.
MultiCharts (2014). MultiCharts .NET Programming Guide (version 1.1). Retrieved from http://www.multicharts.com/downloads/MultiCharts.NET-ProgrammingGuide-v1.1.pdf
MultiCharts Wiki (2014a, December 26). AllowSendOrdersAlways. Retrieved on February 5, 2015, from http://www.multicharts.com/trading-software/index.php/AllowSendOrdersAlways
MultiCharts Wiki (2014b, August 12). BarStatus. Retrieved on February 6, 2015, from http://www.multicharts.com/trading-software/index.php/BarStatus
PowerLanguage .NET Help (n.d.). Retrieved on November 18, 2014, from http://www.multicharts.com/downloads/PowerLanguage.NET.chm
Stephens, R. (2014). C# 5.0 Programmer Reference. Indianapolis, IN: John Wiley & Sons.
Visit programming tutorials for more helpful coding articles.