Situation
You want to know how to perform some basic, conditional ‘debugging’ in the PowerLanguage .NET Editor by including or excluding certain parts of programming code from the compilation process.

Programming example

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

namespace PowerLanguage.Indicator
{
    public class Example_DebugWithPLEditor : IndicatorObject
    {
        private IPlotObject highLowDiff;

        public Example_DebugWithPLEditor(object _ctx) : base(_ctx) { }
        
        protected override void Create()
        {
            highLowDiff = AddPlot(new PlotAttributes("HighLowDifference", EPlotShapes.Line, Color.Red));
        }

        protected override void StartCalc()
        {
            Output.Clear();
        }

        protected override void CalcBar()
        {
            highLowDiff.Set(Bars.High[0] - Bars.Low[0]);

            #if DEBUG
                Output.WriteLine("{0} - Previous value of plot is: {1}",
                    Bars.Time[0].ToString("d-M HH:mm:ss"),
                    highLowDiff.Values[1]);
            #else
                if (Bars.CurrentBar < 30)
                {
                    Output.WriteLine("{0} - Compilation mode is not set to Debug",
                        Bars.Time[0].ToString("d-M HH:mm:ss"));
                }    
            #endif

            // Preprocessing directives can also be used for more things than outputting data.
            // For example, changing the plot value and colour when the release compilation mode is used:
            #if (DEBUG == false)
                highLowDiff.Set(highLowDiff.Values[1] + 10, Color.Yellow); 
            #endif
        }
    }
}

Output of the programming example

When the compilation mode in the PowerLanguage .NET Editor is set to release, the indicator generates the following output:

27-1 09:30:00 - Compilation mode is not set to Debug
27-1 10:00:00 - Compilation mode is not set to Debug
27-1 10:30:00 - Compilation mode is not set to Debug
27-1 11:00:00 - Compilation mode is not set to Debug
27-1 11:30:00 - Compilation mode is not set to Debug
27-1 12:00:00 - Compilation mode is not set to Debug
27-1 12:30:00 - Compilation mode is not set to Debug
27-1 13:00:00 - Compilation mode is not set to Debug
27-1 13:30:00 - Compilation mode is not set to Debug
27-1 14:00:00 - Compilation mode is not set to Debug
27-1 14:30:00 - Compilation mode is not set to Debug
27-1 15:00:00 - Compilation mode is not set to Debug
27-1 15:30:00 - Compilation mode is not set to Debug
27-1 16:00:00 - Compilation mode is not set to Debug
27-1 16:30:00 - Compilation mode is not set to Debug
27-1 17:00:00 - Compilation mode is not set to Debug
27-1 17:30:00 - Compilation mode is not set to Debug

With the compilation mode set to debug, a different output is generated:

20-2 23:00:00 - Previous value of plot is: 0,000340000000000007
20-2 23:30:00 - Previous value of plot is: 0,000299999999999967
20-2 23:59:00 - Previous value of plot is: 0,000320000000000098
21-2 00:30:00 - Previous value of plot is: 0,000489999999999879
21-2 01:00:00 - Previous value of plot is: 0,000329999999999941
21-2 01:30:00 - Previous value of plot is: 0,000279999999999836
21-2 02:00:00 - Previous value of plot is: 0,000490000000000101
21-2 02:30:00 - Previous value of plot is: 0,00030999999999981
21-2 03:00:00 - Previous value of plot is: 0,000359999999999916
21-2 03:30:00 - Previous value of plot is: 0,000500000000000167
21-2 04:00:00 - Previous value of plot is: 0,000279999999999836
21-2 04:30:00 - Previous value of plot is: 0,000290000000000123
21-2 05:00:00 - Previous value of plot is: 0,000210000000000043
21-2 05:30:00 - Previous value of plot is: 0,000450000000000061
21-2 06:00:00 - Previous value of plot is: 0,000239999999999796
21-2 06:30:00 - Previous value of plot is: 0,000409999999999799
21-2 07:00:00 - Previous value of plot is: 0,000279999999999836
21-2 07:30:00 - Previous value of plot is: 0,000399999999999956
21-2 08:00:00 - Previous value of plot is: 0,000400000000000178
21-2 08:00:00 - Previous value of plot is: 0,000400000000000178

Debugging programming code with MultiCharts .NET

While debugging (meaning, searching for and getting rid of programming errors) can also be done with the PowerLanguage .NET Editor, this is quite a different process than using the Microsoft Visual Studio debugger, despite the similar terms.

There are different ways in which you can search for programming errors in MultiCharts .NET (MultiCharts, 2013):

In this article we will take a closer look at this last option. But let’s first take an introductory look at C#’s preprocessor directives.

Using C# preprocessor directives in MultiCharts .NET

Preprocessor directives are statements that instruct the compiler to alter the compilation process in some way and, by doing so, affects the behaviour or outcome of the build process (Joshi, 2013; Patnayak, 2012).

Compiling is the process of turning programming code into code that the computer can read (Liberty & MacDonald, 2009). And generally speaking, when you build your program the source code is compiled into an usable, executable file (Stellman & Greene, 2010).

The MultiCharts PowerLanguage .NET Editor has two compilation modes: Release and Debug, whereby this latter is required for ‘debugging’ (MultiCharts, 2013). When you select the debug compilation mode, the DEBUG preprocessing variable is defined during compilation (Sur, 2013).

If we translate the above into everyday English, it means the following:

  • If you set the compilation mode in the PowerLanguage .NET Editor to Debug, a DEBUG preprocessor variable is defined;
  • Then we can use preprocessor directives such as #if and #else to conditionally check if a variable, DEBUG in this case, is defined;
  • And by doing so, we can include or exclude certain parts of the programming code.

To see how this might be helpful, let’s take a look at the programming example.

MultiCharts .NET programming example

The programming example started with declaring a plot object (line 10), which was then initialised in the Create() method (line 16).

Then in the StartCalc() method the PowerLanguage .NET Editor Output Window was cleared by calling Output.Clear() (line 21).

Using the DEBUG preprocessing variable

Next we arrive in the CalcBar() override method were we, after setting the plot to the difference between the current high and current low (line 26), start applying preprocessing directives:

#if DEBUG
    Output.WriteLine("{0} - Previous value of plot is: {1}",
        Bars.Time[0].ToString("d-M HH:mm:ss"),
        highLowDiff.Values[1]);
#else
    if (Bars.CurrentBar < 30)
  {
        Output.WriteLine("{0} - Compilation mode is not set to Debug",
            Bars.Time[0].ToString("d-M HH:mm:ss"));
  }    
#endif

Here we use the preprocessing directive #if to check if the DEBUG preprocessing variable has been defined. As noted above, this is the case when the debug compilation mode in the PowerLanguage .NET Editor has been selected.

Should the release compilation mode had been used, the DEBUG variable would not have been defined and the #else preprocessing directive with its accompanying code block (lines 33-37) would have been included into the programming code at compilation.

Using conditional expressions with preprocessing directives

In the next part of the example we use a relational operator to see if the DEBUG variable would have been false or not:

// Preprocessing directives can also be used for more things than outputting data.
// For example, changing the plot value and colour when the release compilation mode is used:
#if (DEBUG == false)
    highLowDiff.Set(highLowDiff.Values[1] + 10, Color.Yellow); 
#endif

If the compilation mode is set to release, in which case the DEBUG variable is false, we change the value and colour of the plot.

Key points:

  • With C# preprocessor directives we can conditionally include or exclude certain parts of programming code;
  • The DEBUG preprocessing variable can be used to differentiate between release and debug compilation modes;
  • When the debug compilation mode is used, the DEBUG preprocessing variable returns true;
  • With the help of preprocessor directives, we can make two versions of a MultiCharts .NET indicator or strategy in one source file, depending on the compilation mode used.
References

Joshi, B. (April 2013). Using Preprocessor Directives in C#. Retrieved on February 18, 2014, from http://www.codeguru.com/csharp/.net/using-preprocessor-directives-in-c.htm

Liberty, J. & MacDonald, B. (2009). Learning C# 3.0: Master the Fundamentals of C# 3.0. Sebastopol, CA: O’Reilly Media.

MultiCharts (April 2013). MultiCharts .NET Programming Guide (version 1.0). Retrieved from http://www.multicharts.com/downloads/MultiCharts.NET-ProgrammingGuide-v1.0.pdf

Patnayak, S. (February 2012). Preprocessor Directives in C#. Retrieved on February 19, 2014, from http://www.codeproject.com/Articles/304175/Preprocessor-Directives-in-Csharp

Stellman, A. & Greene, J. (2010). Head First C#: A Brain-Friendly Guide (2nd edition). Sebastopol, CA: O’Reilly Media.

Sur, A. (October 2013). Conditional Compilation with Precompiler Directives in C#. Retrieved on February 19, 2014, from http://dailydotnettips.com/2013/10/08/conditional-compilation-with-precompiler-directives-in-c/