Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Coppock Chart

0.00/5 (No votes)
25 May 2010 1  
This article demonstrates building a web based interactive chart and is my attempt to assimilate some of the recent updates and best practices that have emerged with Visual Studio 2010 and .NET Framework 4 into my software lexicon.

Introduction

Keeping up with new tooling, technologies, and techniques is a challenge for software developers that requires some dedicated effort. This article demonstrates building a web based interactive chart, and is my attempt to assimilate some of the recent updates and best practices that have emerged with Visual Studio 2010 and .NET Framework 4 into my software lexicon.

Requirements

The chart for this article is a visualisation of the Coppock Indicator for the ASX (Australian Stock Exchange). The Coppock Indicator provides a signal for investors that a bear market has ended and it is time to begin building long term positions in strong companies. The chart will be integrated into a web page that discusses the management of risk when investing in shares. There is over 100 years of data available for the Coppock Indicator, so the interactivity for this chart will be an ability to filter the range.

CoppockChart.png

Chart Basics

Charts are one of the fun parts of math. They show how variables relate in a visual way that conveys meaning at a glance. The variables for the Coppock Indicator are dates and a corresponding value. The date is identifiable as an independent variable (its value is not influenced by other factors), and the value is identifiable as a dependent variable (it's affected by the average price of stocks over time). It is typical to display the independent variable as the horizontal (X) axis and the dependent variable as the vertical (Y) axis. The chart most suitable for the Coppock Indicator is a Point-to-Point graph because the Coppock Indicator is calculated on the last day of each month.

Choosing the Technologies

My background is in enterprise development using C# and the .NET Framework, and I wanted to try out the latest Visual Studio 2010. The choice of technology then starts with which platform to target (web, desktop, or mobile) to reach my intended user. My initial research started with Silverlight because of its ability to target all of the platforms (including Mobile with Windows Phone 7) with an extensive set of components in the Silverlight Toolkit. Another option considered was the web standards platform of HTML and JavaScript (JQuery has charting components). The web standards platform tools are light-weight and, when targeting online users, are likely an ideal choice. As an enterprise developer, I want to focus my learning on targeting a broad audience (customers, external business partners, and users within the business). My choice for building the Coppock Indicator Chart is Silverlight 4 with ASP.NET, and will demonstrate Silverlight's ability to encapsulate rich user experiences into a component that can be integrated with web pages. You can download the tools required for compiling and running the Coppock Charting application from the Silverlight website.

Charting Component for Silverlight

The Silverlight Toolkit contains charting components that provide design time support and also dynamic update at runtime when the underlying data source changes. These chart controls behave consistently with the standard Silverlight controls, e.g., are defined declaratively in XAML and can be styled or completely re-templated if required to achieve a desired layout. The chart components also provide extensibility points; e.g., individual parts of the chart can be replaced with custom built components if the existing functionality doesn’t meet requirements. Note: The charting components in the Silverlight Toolkit are still in the ‘Preview Band’, and could change before being added to the Silverlight SDK.

Declarative User Interface

XAML is a fundamental part of Silverlight. It ensures a separation of concern between user interface layout and application logic because in XAML, it's only possible to declare interface components and their interaction (via triggers). Business logic must be specified in code, and is wired up to elements in the XAML through databinding to properties, events, and commands. XAML can be thought of as declarative programming because every element corresponds to either a class in the .NET Framework or a class in your application.

<chartingToolkit:Chart x:Name="coppockChart"
     Title="{Binding ChartTitle}"
     Margin="10,5,15,5"
     Style="{StaticResource chartStyle}">
     <chartingToolkit:LineSeries Title="Coppock Indicator"
         DependentValuePath="Value"
         IndependentValuePath="Date"
         ItemsSource="{Binding Source={StaticResource coppockDataView}}"
         DataPointStyle="{StaticResource simpleLineDataPointStyle}"
         LegendItemStyle="{StaticResource legendItemStyle}"
         Loaded="LineSeries_Loaded">
     </chartingToolkit:LineSeries>
     <chartingToolkit:Chart.Axes>
        <chartingToolkit:LinearAxis Orientation="Y"
             Minimum="{Binding AxisYMinimum}"
             Maximum="{Binding AxisYMaximum}"
             Interval="{Binding AxisYInterval}"
             ShowGridLines="True"
             Location="Right" />
         <chartingExtensions:EndOfMonthAxis Orientation="X"
             Title=""
             ShowGridLines="False"
             Maximum="{Binding AxisXMaximum}"
             Interval="{Binding AxisXInterval}"
             IntervalType="{Binding AxisXIntervalType}"
             AxisLabelStyle="{StaticResource axisLabelStyle}">
         </chartingExtensions:EndOfMonthAxis>
    </chartingToolkit:Chart.Axes>
</chartingToolkit:Chart>

Databinding and MVVM

The databinding mechanism in Silverlight ensures that modified values are synchronised between the user interface and the underlying code; e.g., when the date range for the Coppock Indicator chart is changed, the chart title is updated to show the new date values. Code classes implementing the INotifyPropertyChanged Interface can participate in this databinding mechanism.

Title="{Binding ChartTitle}"
Code:
/// <summary>
/// Gets ChartTitle.
/// </summary>
public string ChartTitle
{
    get
    {
        return this.chartTitle;
    }

    private set
    {
        this.chartTitle = value;
        this.NotifyPropertyChanged("ChartTitle");
    }
}

An important best practice to emerge in programming for Silverlight is the MVVM (Model-View-ViewModel) design pattern. This pattern encourages separation of business logic code from code that manipulates the view directly. ViewModel classes can be statically initialised in XAML.

<UserControl.Resources>
    <viewModels:CoppockViewModel x:Key="coppockViewModel"
        SeriesChanged="ViewModel_SeriesStartChanged" />
</UserControl.Resources>

The ViewModel is then made available to all elements in XAML through the DataContext property.

DataContext="{Binding Source={StaticResource coppockViewModel}}"

Making the Chart Interactive

Clicking the Coppock Charts date range HyperlinkButtons will execute a command that causes the chart's datasource to be filtered to reflect the chosen date range. A binding applied to the HyperlinkButton's Command property connects it to the ChangeSeriesStart DelegateCommand which is located in the ViewModel class.

<HyperlinkButton x:Name="TenYearSeriesButton"
        Content="10yr"
        HorizontalContentAlignment="Center"
        Command="{Binding ChangeSeriesCommand}"
        CommandParameter="{Binding TenYearSeriesCommandParameter}"
        Width="30" />

When the ChangeSeriesStart DelegateCommand is initialised, an event handler is assigned to its Action property, which executes when the HyperlinkButton is clicked.

this.ChangeSeriesCommand = new DelegateCommand(this.ChangeSeriesStart, 
                                               this.CanChangeSeriesStart);

The ability to filter the chart by date range is enabled by the CollectionViewSource type. CollectionViewSource wraps the actual DataSource of the CoppockChart and exposes a View property that is implicitly used when DataBinding occurs. When CollectionViewSource is refreshed, it executes the Filter event which allows each item in the DataSource to be examined to determine if it should be included in the View. DataBinding ensures that this change to the CollectionViewSource View is reflected in the chart.

<Grid.Resources>
    <CollectionViewSource x:Key="coppockDataView"
        Source="{Binding CoppockData.SeriesData}"
        Filter="SeriesData_Filter"/>
</Grid.Resources>
Code:
/// <summary>
/// Handle SeriesData_Filter event.
/// </summary>
/// <param name="sender">sender parameter</param>
/// <param name="e">FilterEventArgs parameter</param>
private void SeriesData_Filter(object sender, FilterEventArgs e)
{
    if (e.Item != null)
    {
        e.Accepted = this.ViewModel.IncludeInSeries(((DataItem)e.Item).Date);
    }
}

Locating the Signal Markers

The purpose of the Coppock Indicator is to provide a signal that indicates when the bear market has ended. The algorithm to determine this signal looks for DataItems where the value is less than zero but greater than the previous month's value. A LinkedList is used as the underlying datasource because of this need to inspect the previous item. When a DataItem is found that represents the Coppock Indicator signal, a line and an ellipse with a ToolTip is drawn onto a Canvas that overlays the chart (this technique is described in another article).

/// <summary>
/// Handle ViewModel_SeriesStartChanged event.
/// </summary>
/// <param name="sender">sender parameter</param>
/// <param name="e">SeriesStartChangedEventArgs parameter</param>
private void ViewModel_SeriesStartChanged(object sender, SeriesStartChangedEventArgs e)
{
    this.DataView.View.Refresh();

    this.ChartAreaCanvas.Children.Clear();                
    this.DrawSignalMarkers();            
}

Chart Extensibility

Each component that makes up the chart (Series and Axis) is a control. This means that styles can be applied, templates can be modified, or the control can be derived from or even totally replaced with a custom component. To properly display the Coppock Indicator data, end of month values were required for the horizontal X axis. The DateTimeAxis available with the Silverlight Toolkit didn't support this scenario, but by creating a class derived from the standard DateTimeAxis, it was possible to override the GetMajorAxisValues method and modify the DateTime value to display.

/// <summary>
/// EndOfMonth Axis control.
/// </summary>
public class EndOfMonthAxis : DateTimeAxis
{
    /// <summary>
    /// Get MajorAxisValues.
    /// </summary>
    /// <param name="availableSize">availableSize parameter</param>
    /// <returns>IEnumerable of DateTime</returns>
    protected override IEnumerable<DateTime> GetMajorAxisValues(Size availableSize)
    {           
        // Roll each date value back one day i.e. to the last day of the month.
        return base.GetMajorAxisValues(availableSize).
            Select(date => date.AddDays(-1));
    }
}

Then a style is applied to the StringFormat property of the AxisLabel to format the date.

<Style x:Key="axisLabelStyle" TargetType="chartingToolkit:AxisLabel">
    <Setter Property="StringFormat" Value="{}{0:MMM yy}" />
</Style>

Integration with the HTML page

This Coppock Indicator chart emphasises Silverlight as a component part of a web page. This, I think, requires the Silverlight application to be configurable by its hosting page; i.e., as the web page renders in the browser, I would like to perform custom initialisation on the Silverlight component. Initialisation parameters are specified as name value pairs in the initParams member of the object tag hosting the Silverlight application. Any number of name value pairs can be specified in the initParams value (comma separated). The Silverlight Plug-in Object Reference provides a complete reference for integration with the HTML page.

<name="initParams" value="Chart=Coppock" />

These parameters can then be extracted from StartupEventArgs in the Application_Startup event.

/// <summary>
/// Handle Application_Startup event.
/// </summary>
/// <param name="sender">sender parameter</param>
/// <param name="e">StartupEventArgs parameter</param>
private void Application_Startup(object sender, StartupEventArgs e)
{
    this.RootVisual = new MainView(e.InitParams);                     
}

Parameters are iterated over using the Keys property.

foreach (var key in this.InitParams.Keys)
{
    var param = this.InitParams[key];
     ...
}

Making the Business Case for Silverlight

Silverlight is a rich client technology built on the .NET Framework that can target web, desktop, and mobile platforms using the rich debugging environment provided by Visual Studio. Silverlight brings us closer to the concept of a single code base targeting multiple platforms. This article has discussed Silverlight's abilities as a component in a web page with HTML and JavaScript integration. This approach to using Silverlight opens the door to SAAS (Software as a Service), where Silverlight applications can be independently hosted, e.g., using the Windows Azure Platform and integrated into a website by specifying the web address. This enables scenarios where an enterprise may want to expose application functionality to business partners or may want to consume components built externally and integrate them into web based applications.

References

History

  • 29 May, 2010: Version 1.0 (Initial version).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here