自家製クオンツ

ソフトウェア技術を使って金融や投資の考察をしています。

インジケーターをチャートに表示する方法(前編)

f:id:yooce:20211130154136p:plain

ひとりアドベントカレンダー13日目です。今日は、インジケーターをチャートに表示する方法を解説します。

MagicalNuts.UI.TradingChartでインジケーターをチャートに表示するには、IPlotterインターフェイスを実装します。

/// <summary>
/// プロッターのインターフェースを表します。
/// </summary>
public interface IPlotter : IPropertyHolder
{
    /// <summary>
    /// Seriesの配列を取得します。
    /// </summary>
    Series[] SeriesArray { get; }

    /// <summary>
    /// ChartAreaを設定します。
    /// </summary>
    /// <param name="mainChartArea">主ChartArea</param>
    /// <returns>使用する従ChartAreaの配列</returns>
    SubChartArea[] SetChartArea(MainChartArea mainChartArea);

    /// <summary>
    /// 非同期で準備します。
    /// </summary>
    /// <returns>非同期タスク</returns>
    Task SetUpAsync();

    /// <summary>
    /// データをプロットします。
    /// </summary>
    /// <param name="code">銘柄コード</param>
    /// <param name="candles">ロウソク足のリスト</param>
    void Plot(string code, List<Candle> candles);
}

下2つは、SetUpAsync()が準備処理、Plot()がグラフのプロット処理です。

C#System.Windows.Forms.DataVisualization.Charting.Chartを使ったグラフプロットの経験がある方はご存じだと思いますが、一番上のSeriesArrayはプロットした一連のデータを持ったSeriesクラスの配列です。SetChartArea()MainChartAreaSubChartAreaの理解が必要ですので、TradingChartSampleの画面を見てみましょう。

f:id:yooce:20211121202417p:plain

上図は縦方向に3つの領域に分かれており、一番上は価格チャートと出来高ボリンジャーバンドがプロットされた領域、2番目はATRがプロットされた領域、3番目はMACDがプロットされた領域です。一番上の価格チャートがプロットされた領域がMainChartAreaで、下2つの価格チャート以外の領域がSubChartAreaです。

MagicalNutsでは、チャートにインジケーターをプロットするクラスをプロッターと呼びます。TradingChartSampleSamplePlotterを実装しましたので、そのSetChartArea()を見てみましょう。

private Series Series = new Series();

public override SubChartArea[] SetChartArea(MainChartArea mainChartArea)
{
    Series.ChartArea = mainChartArea.Name;
    return null;
}

まず、使用するSeriesをメンバー変数に持ちます。SetChartArea()にはチャートからMainChartAreaが引数として渡されるので、メンバーのSeriesの描画対象領域として設定し、このプロッターはSubChartAreaを使用しないのでnullを返しています。

SubChartAreaを使うMagicalNuts.UI.TradingChart.Plotter.AtrPlotterSetChartArea()を見てみましょう。

private Series Series = new Series();
private ChartArea ChartArea = null;

public override SubChartArea[] SetChartArea(MainChartArea mainChartArea)
{
    SubChartArea subChartArea = new SubChartArea();
    Series.ChartArea = subChartArea.Name;
    ChartArea = subChartArea;
    return new SubChartArea[] { subChartArea };
}

プロット先となるSubChartAreaを作ってSeriesに設定し、その存在をチャートに教えるために返しています。ここでは例示しませんが、MainChartAreaSubChartAreaを同時に使用するプロッターも実装可能です。