Situation
You want to know how to plot textual information in the chart’s Status Line. As an example this article displays the average bid/ask spread in the Status Line.

Programming example

using System;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;
using System.Collections.Generic;       // Added for list

namespace PowerLanguage.Indicator
{
    [SameAsSymbol(true)]
    [UpdateOnEveryTick(true)]
    public class BidAsk_SL : IndicatorObject
    {
        private IPlotObjectStr strPlot;

        [Input]
        public int ListLength { get; set; }

        private List sprdList = new List();

        public BidAsk_SL(object _ctx) : base(_ctx) { }

        protected override void Create()
        {
            strPlot    = AddPlot(new StringPlotAttributes());
            ListLength = 10;       // Default value
        }

        protected override void CalcBar()
        {
            if (Environment.IsRealTimeCalc == true)
            {
                // Update the list with bid/ask spread values
                sprdList = UpdateBidAskList(sprdList);

                // Update the status line plot
                strPlot.Set(string.Format("Avg: {0} [{1} - {2}]",
                        Math.Round(sprdList.Average(), 2),
                        sprdList.Min(),
                        sprdList.Max()
                    ),
                    Color.Yellow);
            }
        }

        // This method updates the bid/ask spread array
        private List UpdateBidAskList(List myList)
        {
            // Calculate bid/ask spread in number of ticks
            int bidAskSprd = 
                (int)((Bars.StatusLine.Ask - Bars.StatusLine.Bid) /     // Difference between bid/ask
                (Bars.Info.MinMove / Bars.Info.PriceScale));            // On a tick basis

            // If the list is already as long as the input, remove the first value
            if (myList.Count == ListLength)
                myList.RemoveAt(0);

            // Add the recent bid/ask spread to the list
            myList.Add(bidAskSprd);

            return myList;
        }
    }
}

Output of the programming example

Applied to a chart, the indicator looks line:

Example of plotting text in the MultiCharts .NET Status Line

Creating text plots in MultiCharts .NET

With text plots textual information (meaning, a string) can be displayed in the chart Status Line. This requires the use of the IPlotObjectStr interface (MultiCharts, 2013). We added this in line 13 of the example:

private IPlotObjectStr strPlot;

With the SameAsSymbol and UpdateOnEveryTick attributes (lines 9-10) the indicator is plotted on the same chart as the symbol and updated on every tick. In lines 15 to 18 the input for the list length is added and an instance of the generic list with integers (List<Int32>) created:

[Input]
public int ListLength { get; set; }

private List sprdList = new List();

The benefit of using a list here instead of an array is that a list length does not have to be specified in advance (Liberty & MacDonald, 2009). Instead, the length of a list is automatically incremented by adding a new value to it. For our purposes this means that the average bid/ask spread is calculated correctly when the list length is less than the ListLength input. Furthermore, a list provides a convenient way to remove the oldest value from it (meaning, the RemoveAt() method).

To conveniently use a list and its methods, the System.Collection.Generic namespace needs to be added (line 5):

using System.Collections.Generic;       // Added for list

Creating a string plot in MultiCharts .NET

Then in the Create() override method we create the string plot and assign a default value to the ListLength input:

protected override void Create()
{
    strPlot    = AddPlot(new StringPlotAttributes());
    ListLength = 10;       // Default value
}

Next we arrive at the CalcBar() method:

protected override void CalcBar()
{
    if (Environment.IsRealTimeCalc == true)
    {
        // Update the list with bid/ask spread values
        sprdList = UpdateBidAskList(sprdList);

        // Update the status line plot
        strPlot.Set(string.Format("Avg: {0} [{1} - {2}]",
                Math.Round(sprdList.Average(), 2),
                sprdList.Min(),
                sprdList.Max()
            ),
            Color.Yellow);
    }
}

Here we first check whether or not the calculation is performed on real-time data, in which case the Environment.IsRealTimeCalc property returns true. Then the list of bid/ask spread values is updated by assigning the output of the UpdateBidAskList() method to the sprdList integer list.

Calculating the bid-ask spread in MultiCharts .NET

The UpdateBidAskList() method is implemented as follows:

// This method updates the bid/ask spread array
private List UpdateBidAskList(List myList)
{
    // Calculate bid/ask spread in number of ticks
    int bidAskSprd = 
        (int)((Bars.StatusLine.Ask - Bars.StatusLine.Bid) /     // Difference between bid/ask
        (Bars.Info.MinMove / Bars.Info.PriceScale));            // On a tick basis

    // If the list is already as long as the input, remove the first value
    if (myList.Count == ListLength)
        myList.RemoveAt(0);

    // Add the recent bid/ask spread to the list
    myList.Add(bidAskSprd);

    return myList;
}

Three things are done by this method before returning the list. First, the difference between the ask and bid price is calculated and converted to the number of ticks. Since this is a calculation performed with double type variables, we need to explicitly cast this to int since our bid/ask spread list is a list with integers.

Second, the condition is evaluated whether or not the length of the list is equal to the ListLength input. If that is the case, the oldest value is removed from the list so that when the newest value is added, the list does not become too long. And thirdly, the most recent bid/ask spread is added to the list.

The returned list is then used in the CalcBar() method for updating the Status Line text:

// Update the status line plot
strPlot.Set(string.Format("Avg: {0} [{1} - {2}]",
        Math.Round(sprdList.Average(), 2),
        sprdList.Min(),
        sprdList.Max()
    ),
    Color.Yellow);

The formatted string outputs three things here: (1) the average bid/ask spread (calculated with the list Average() method), (2) the minimum bid/ask spread value that is in the list (retrieved with the Min() method), and (3) the maximum bid/ask spread value in the list (returned by the Max() method). After that the plot colour is set to yellow.

If the length of the Status Line text becomes more than 30 characters, additional characters are cut-off (MultiCharts Support, personal communication, November 20, 2013).

Note that this example does not give a 100% accurate bid/ask spread calculation. This is due to the fact that the CalcBar() override method is only updated when the price bar is updated (see MultiCharts, 2013).

References

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