Situation
Instead of converting numeric values with standard format specifiers you want more control over how numeric values are transformed to a string by providing the exact template.

Programming example

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

namespace PowerLanguage.Indicator
{
    [SameAsSymbol(true), UpdateOnEveryTick(false)]
    public class Example_NumericCustomFormatSpecifiers : IndicatorObject
    {
        public Example_NumericCustomFormatSpecifiers(object _ctx) : base(_ctx) { }

        protected override void StartCalc()
        {
            Output.Clear();
        }
        
        protected override void CalcBar()
        {
            if (Bars.CurrentBar == 100)
            {
                Output.WriteLine("Bar close: {0:.00000}, high: {1}, and {2:000.000} low.",
                    Bars.Close[0],
                    Bars.High[0].ToString("#.###"),
                    Bars.Low[0]);

                Output.WriteLine("Upticks: {0:#,###,###}, Downticks: {1:0.00}, and ticks: {2:0.00E00}",
                    Bars.UpTicks[0],
                    Bars.DownTicks[0],
                    Bars.Ticks[0]);
            }
        }
    }
}

Output of the programming example

The example indicator generates the following text to the Output Window:

Bar close: ,78167, high: ,787, and 000,782 low.
Upticks: 665.974, Downticks: 0,00, and ticks: 6,66E05

The PowerLanguage .NET Editor Output Window

String formatting can be done in different ways, but for this example the PowerLanguage .NET Editor Output Window is used. The Output Window is a convenient way to output information from an indicator, trading strategy, or function. Its methods, accessible in any override method (MultiCharts, 2013), are the following (PowerLanguage .NET Help, n.d.):

  • Every Output.Clear() method call empties the Output Window;
  • Both Output.Write() and Output.WriteLine() write text to the Output Window, but the latter automatically adds a line break after the end of each string.

Numeric values can be converted to strings in two ways: with standard format specifiers (that consist out of a single character) or with custom format specifiers, that allow flexible micromanaging with a template (Albahari & Albahari, 2012).

For more on formatting text, see composite formatting, escape characters, numeric values with standard formatting, dates to string, and times to string.

C#’s custom format specifiers for converting numeric values to a string

These custom format specifiers can be used with all of the numeric types (Dorman, 2010). Strings with these specifiers can be used in overloaded ToString() methods and with composite formatting (Microsoft Developer Network, n.d.), such as with the Output.WriteLine() method. Both of these ways are used in the example.

The custom numeric format specifiers in C# are the following (Albahari & Albahari, 2012; Dorman, 2010; MSDN, n.d.):

Custom format string Description Example
"0" Zero placeholder: replaces the zero with the corresponding digit if one is present; otherwise, zero appears in the result string. It can pad a number with zeros before and after the digit. 9.87 returns "09.87" with "00.00" and "009.9" with "000.0".
"#" Digit placeholder that limits the number of digits: is replaced with the corresponding digit if present; otherwise, no digit appears in the result. 12.3456 returns "12.35" with ".##" and "12.3456" with ".####". 0.123 returns ".12" with "#.##".
"." Returns the decimal separator. This decimal point is culture dependent. For example, for US culture settings it returns . and with Dutch culture settings ,. 0.654 returns "0.65" with "0.00".
"," Group separator and number scaling.

As a group separator, it inserts the localised group separator character (like the dot or comma).

Acts a number scaling specifier when the comma is at the end or before the digit placeholder. In that case it divides the number by 1000 for each comma specified.
123456 returns "0,123,456" with "0,000,000" and "123" with "#,".
"%" Multiplies a number by 100 and inserts a localised percent symbol in the result string. 0.12 returns "12%" with "0%".
"‰" Multiplies a number by 1000 and inserts a localised per mille symbol in the result. The ‰ symbol is the Unicode symbol U+2030. 0.3456 returns 346‰ with the "#‰" format string.
"E0", "E+0", "E-0", "e0", "e+0", "e-0" Exponential notation. The case ("E" or "e") determines the case of the exponent symbol and the number of zeros determines the minimum number of digits in the exponent. A plus sign indicates that a sign character always precedes the exponent, while a minus sign indicates that a sign character only precedes negative exponents. 1234 is returned as "1E3" with "0E0", as "1E+3" with "0E+0", as "1.23E03" with "0.00E00", and returned as "1.23e03" with "0.00e00".
";" Defines sections with different format strings for positive, negative, and zero numbers.

The default is one section, in which case the format string applies to all values. When two sections are included, the first applies to all positive values and zero while the second applies to negative values. With three sections, the first applies to positive values, the second to negative, and the third to zeros.
The custom format string "#;(#);zero" returns "5" when the numeric value is 5, "(5)" when the value is -5, and "zero" when the value is 0.
"string", 'string' Literal string delimiter. The enclosed characters are copied to the result unchanged. The format string "'The value: '#.##" returns "The value: .35" when the number is 0.3456.
\ Escape character that causes the next character to be interpreted as a literal character rather than a custom format specifier. Use in conjunction with the @ prefix or use \\. 25 returns "#25" with "\\#0" or @"\#0".
Other All other characters that are not format specifiers are copied to the result string unchanged. Use the literal string delimiter to prevent a character from being interpreted as a format specifier. 10 returns "10 percent" with the "0 percent" custom format string.

MultiCharts .NET programming example

The example begins with setting MultiCharts .NET class attributes:

[SameAsSymbol(true), UpdateOnEveryTick(false)]

The SameAsSymbol attribute set to true plots the indicator on the main price chart. For more efficient calculation, UpdateOnEveryTick is set to false so that the indicator is only calculated on bar close.

Clearing the PowerLanguage .NET Editor Output Window

Next is the StartCalc() override method:

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

This method is executed once at the beginning of every calculation cycle (MultiCharts, 2013). By calling the Output.Clear() method here the Output Window is cleared regularly.

Outputting prices with custom format specifiers in MultiCharts .NET

The last part is the CalcBar() method, which has the following if statement:

if (Bars.CurrentBar == 100)
{
    Output.WriteLine("Bar close: {0:.00000}, high: {1}, and {2:000.000} low.",
        Bars.Close[0],
        Bars.High[0].ToString("#.###"),
        Bars.Low[0]);

    Output.WriteLine("Upticks: {0:#,###,###}, Downticks: {1:0.00}, and ticks: {2:0.00E00}",
        Bars.UpTicks[0],
        Bars.DownTicks[0],
        Bars.Ticks[0]);
}

To only print the output once, the expression in the if statement evaluates whether the current bar number (Bars.CurrentBar) is 100.

When that expression evaluates to true, the body of the if statement is executed. Price data of the current bar is outputted first (lines 22-25). The closing price is converted to a string with the .00000 format string in the first substitution parameter. The high is transformed to a string with ToString() and the #.### format string as an argument, while the low is formatted with the 000.000 format specifier.

This Output.WriteLine() statement prints the following to the Output Window:

Bar close: ,78167, high: ,787, and 000,782 low.

Outputting volume data with custom format specifiers in MultiCharts .NET

The next part in the if statement prints volume data (lines 27-30). Up ticks are converted with the #,###,### format string to print non-zero numbers with the thousands separator. Down ticks are printed with 0.00 and the total number of ticks for the bar with the 0.00E00 format string (which gives exponential notation).

This Output.WriteLine() statement prints the following:

Upticks: 665.974, Downticks: 0,00, and ticks: 6,66E05

Key points

  • Text can be printed to the Output Window with Output.Write() and Output.WriteLine();
  • Custom format specifiers in C# allow micromanaging with a template how a numeric value is converted to a string;
  • These format specifiers can be provided in the overloaded ToString() methods or with composite formatting and substitution parameters.
References

Albahari, J. & Albahari, B. (2012). C# 5.0 in a Nutshell: The Definitive Reference (5th edition). Sebastopol, CA: O'Reilly Media.

Dorman, S. (2010). Sams Teach Yourself Visual C# 2010 in 24 Hours. Indianapolis, IN (USA): Sams/Pearson Education.

Microsoft Developer Network [MSDN] (n.d.). Custom Numeric Format Strings. Retrieved on September 22, 2014, from http://msdn.microsoft.com/en-us/library/0c899ak8%28v=vs.110%29.aspx

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

PowerLanguage .NET Help (n.d.). Retrieved on May 16, 2014, from http://www.multicharts.com/downloads/PowerLanguage.NET.chm