チャートオブジェクト/描画

イントロダクション

チャートオブジェクト(描画)は、cTraderチャートにラインや図形を描くためのものです。これを使うことで、cBotやインジケーターのデータに基づいてチャートにパターンを描いたり、特定のイベントを表示したりできます。

チャートオブジェクトは、位置決めのためにX座標とY座標を使用します。

  • X軸はチャートの時間またはバーのインデックスを表します。
  • Y軸はシンボルの価格です。

すべてのチャートオブジェクトは ChartObject 基底クラスから派生しており、これによりすべてのオブジェクトが特定の基本機能を継承しています。

チャートオブジェクトのコードサンプル

インジケーターウィンドウ内の描画

チャートオブジェクトを作成する際、’メイン’シンボルチャートに制限されるわけではありません。実際には、インジケーターの出力が表示される任意のウィンドウ内にチャートオブジェクトを描くことができます。

Chart クラスには IndicatorAreas コレクションがあります。これには、インジケーターが出力を表示できるすべてのオーバーレイまたは別ウィンドウが含まれています。

現在のインジケーターエリアには、Indicator クラスの IndicatorArea プロパティを使用してアクセスすることもできます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
using cAlgo.API;
namespace NewIndicator
{
    [Indicator(IsOverlay = false, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var verticalLine = IndicatorArea.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);
        }

        public override void Calculate(int index)
        {
        }
    }
}

上記のインジケーターのインスタンスを実行すると、別のインジケーターウィンドウに赤いラインが表示されるはずです。別のインジケーターエリアにチャートを作成する際は、ChartIndicatorArea が両方とも ChartArea 基底クラスから派生しているため、すべての描画メソッドを使用できます。

静的テキスト

XおよびY座標を使用する代わりに、静的テキストは静的な水平および垂直の整列を使用します。静的テキストを表示または描画するには、DrawStaticText() メソッドを使用します。

1
var staticText = Chart.DrawStaticText("static", "これは表示されるテキストです", VerticalAlignment.Center, HorizontalAlignment.Center, Color.Red);

このチャートオブジェクトをインジケーターに添付し、インスタンスを実行すると、メインチャートに以下のテキストが表示されます。

Image title

縦線

縦線を描画するには、DrawVerticalLine() メソッドを使用します。

1
2
3
var verticalLine = Chart.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);
// または
var verticalLine = Chart.DrawVerticalLine("line", Bars.OpenTimes[Chart.LastVisibleBarIndex], Color.Red);

横線

横線を描画するには、DrawHorizontalLine() メソッドを使用します。

1
2
3
/* 最後の10バーの最高値の最大値をY座標として使用します。 */ 
var horizontalLine = Chart.DrawHorizontalLine("line", Bars.HighPrices.Maximum(10), Color.Red);

トレンドライン

トレンドラインは、チャートの特定の点から始まり、別の点で終わります。トレンドラインは、異なる形状や複雑なパターンを作成するのに役立ちます。

トレンドラインを描画するには、DrawTrendLine() メソッドを使用します。

1
2
3
4
5
6
7
/* 最初の表示バーの安値から最後の表示バーの高値までラインを描画します。 */
var trendLine = Chart.DrawTrendLine("line", Chart.FirstVisibleBarIndex, Bars.LowPrices[Chart.FirstVisibleBarIndex], Chart.LastVisibleBarIndex, Bars.HighPrices[Chart.LastVisibleBarIndex], Color.Red);
// または、以下のように考えてみてください。
var trendLine = Chart.DrawTrendLine("line", Bars.OpenTimes[Chart.FirstVisibleBarIndex], Bars.LowPrices[Chart.FirstVisibleBarIndex], Bars.OpenTimes[Chart.LastVisibleBarIndex], Bars.HighPrices[Chart.LastVisibleBarIndex], Color.Red);

矩形

矩形を描画するには、DrawRectangle() メソッドを使用します。

1
2
3
/* 最初の表示バーの次から最後の表示バーまでの範囲で矩形を描画します。 */
var rectangle = Chart.DrawRectangle("rectangle", Chart.FirstVisibleBarIndex+1, Bars.LowPrices[Chart.FirstVisibleBarIndex+1], Chart.LastVisibleBarIndex, Bars.HighPrices[Chart.LastVisibleBarIndex], Color.Red);
// 矩形を透明な色で塗りつぶすには、次のようにします。
rectangle.IsFilled = true;
rectangle.Color = Color.FromArgb(80, rectangle.Color);

三角形

三角形を描画するには、DrawTriangle() メソッドを使用します。

1
2
3
/* チャートの中央に向かって三角形を描画します。 */
var middleX = (Chart.FirstVisibleBarIndex+ Chart.LastVisibleBarIndex-Chart.FirstVisibleBarIndex) / 2;
var middleY = (Bars.LowPrices[Chart.FirstVisibleBarIndex] + (Bars.HighPrices[Chart.LastVisibleBarIndex] - Bars.LowPrices[Chart.FirstVisibleBarIndex]) / 2;
var triangle = Chart.DrawTriangle("triangle", Chart.FirstVisibleBarIndex, Bars.LowPrices[Chart.FirstVisibleBarIndex], middleX, middleY, Chart.LastVisibleBarIndex, Bars.HighPrices[Chart.LastVisibleBarIndex], Color.Red);

その他のチャートオブジェクト

楕円やフィボナッチツールなどのその他のチャートオブジェクトについても簡単に説明しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using cAlgo.API;
using System.Linq;
namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            foreach (var chartObject in Chart.Objects)
            {
                /* If the object is a trend line 
                we change its Y1/2 properties */
                if (chartObject is ChartTrendLine trendLine)
                {
                    trendLine.Y1 = Chart.BottomY;
                    trendLine.Y2 = Chart.TopY;
                }
            }

            /* Here, we filter all objects of the 'ChartRectangle'
            type. */
            var rectangles = from chartObject in Chart.Objects
                             where chartObject is ChartRectangle
                             select chartObject as ChartRectangle;

            /* We select only the chart objects with a name that
            begins with "MyObjects". */
            var myObjects = from chartObject in Chart.Objects
                            where chartObject.Name.StartsWith("MyObjects", System.StringComparison.OrdinalIgnoreCase)
                            select chartObject;

            /* We select only interactive objects. If an object
            is interactive, it will not be removed when the 
            indicator is removed or reloaded. */
            var interactiveObjects = from chartObject in Chart.Objects
                                     where chartObject.IsInteractive
                                     select chartObject;

            /* We remove all objects with a name 
            that begins with "ToRemove". */
            var chartObjectsCopy = Chart.Objects.ToArray();

            foreach (var chartObject in chartObjectsCopy)
            {
                if (chartObject.Name.StartsWith("ToRemove", System.StringComparison.OrdinalIgnoreCase))
                {
                    /* Chart 'RemoveObject' gets the object name
                    as a parameter. */
                    Chart.RemoveObject(chartObject.Name);
                }

            }
        }

        public override void Calculate(int index)
        {
        }
    }
}

イベント

チャートオブジェクトには、オブジェクトが描画、更新、または削除されたことを知るために使用できるいくつかのイベントがあります。

  • ObjectsAdded。このイベントは、1つまたは複数のチャートオブジェクトがチャートに追加されたときにトリガーされます。
  • ObjectsRemoved。このイベントは、1つまたは複数のチャートオブジェクトがチャートから削除されたときにトリガーされます。
  • ObjectsUpdated。このイベントは、1つまたは複数のチャートオブジェクトが更新されたときにトリガーされます(ユーザーまたはアクティブなインジケーター/cBotによってプロパティの1つが変更されたとき)。
  • ObjectsSelectionChanged。このイベントは、1つまたは複数のチャートオブジェクトがユーザーによって選択されたときにトリガーされます。
  • ObjectHoverChanged。このイベントは、マウスカーソルがチャートオブジェクトの上にホバーしたときにトリガーされます。

以下の例は、すべての5種類のイベントタイプを使用しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using cAlgo.API;
namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            Chart.ObjectsAdded += Chart_ObjectsAdded;
            Chart.ObjectsRemoved += Chart_ObjectsRemoved;
            Chart.ObjectsUpdated += Chart_ObjectsUpdated;
            Chart.ObjectsSelectionChanged += Chart_ObjectsSelectionChanged;
            Chart.ObjectHoverChanged += Chart_ObjectHoverChanged;
        }

        private void Chart_ObjectHoverChanged(ChartObjectHoverChangedEventArgs obj) => throw new System.NotImplementedException();

        private void Chart_ObjectsSelectionChanged(ChartObjectsSelectionChangedEventArgs obj) => throw new System.NotImplementedException();

        private void Chart_ObjectsUpdated(ChartObjectsUpdatedEventArgs obj) => throw new System.NotImplementedException();

        private void Chart_ObjectsRemoved(ChartObjectsRemovedEventArgs obj) => throw new System.NotImplementedException();

        private void Chart_ObjectsAdded(ChartObjectsAddedEventArgs obj) => throw new System.NotImplementedException();

        public override void Calculate(int index)
        {
        }
    }
}

インタラクティブオブジェクト / ノンインタラクティブオブジェクト

インタラクティブオブジェクトを操作する際、ユーザーはオブジェクトの位置、色、コメントなどのプロパティを変更できます。すべてのユーザー描画オブジェクトは、デフォルトでインタラクティブです。

注意

ChartStaticTextプロパティは、関連するオブジェクトがインタラクティブであるかどうかに関係なく変更できません。

オブジェクトをインタラクティブにするには、以下のようにそのIsInteractiveプロパティをtrueに設定します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using cAlgo.API;
namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var verticalLine = Chart.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);

            verticalLine.IsInteractive = true;
        }

        public override void Calculate(int index)
        {
        }
    }
}

すべてのチャートオブジェクトにはIsInteractiveプロパティがあります。デフォルトの値はfalseです。

チャートオブジェクトがインタラクティブであれば、インジケーター/cBotインスタンスが削除または停止されても削除されません。それに対して、ノンインタラクティブオブジェクトはインジケーター/cBotが停止すると自動的に削除されます。

混雑を避けるために、関連するインスタンスが削除された後は、インジケーターのDestroyメソッドやcBotのOnStopメソッドを使用して、インタラクティブオブジェクトを「クリーン」するようにしてください。

チャートオブジェクトがインタラクティブでない場合、チャートオブジェクトのリストやコレクションにも表示されません。

ロックされたオブジェクト / アンロックされたオブジェクト

チャートオブジェクトをロックすると、ユーザーがそれを変更または更新することを防げます。これを行うには、トレーダーの「チャートプロパティ」ボックスを使用するか、IsLockedプロパティをtrueに設定します。デフォルトの値はfalseです。

ロックを使用して、オブジェクトをインタラクティブにしつつ、ユーザーによる更新を防ぐことができます。以下の例では、縦線オブジェクトをロックします。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using cAlgo.API;
namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var verticalLine = Chart.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);

            verticalLine.IsLocked = true;
        }

        public override void Calculate(int index)
        {
        }
    }
}

表示 / 非表示

チャート上にオブジェクトを描画した後、それを非表示にすることができます。オブジェクトはチャート上に存在し続けますが、完全に見えなくなります。

これを行うには、IsHiddenプロパティをtrueに設定します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using cAlgo.API;
namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var verticalLine = Chart.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);

            verticalLine.IsHidden = true;
        }

        public override void Calculate(int index)
        {
        }
    }
}

リソース使用量がこの機能を使用する際の主な考慮事項です。チャート上に頻繁に表示される必要があるオブジェクトがある場合(しかし、常にではない)、そのオブジェクトを削除して再描画するのではなく、非表示にする方が良いです。

オブジェクトの選択 / 外観インデックス (ZIndex)

チャート上で複数のオブジェクトが交差する場合、特定のオブジェクトを選択するのが難しい、または不可能な場合があります。交差するチャートオブジェクトのグループ上にマウスカーソルをホバーすると、最後に描画されたオブジェクトのみが選択可能になります。

この動作を変更するには、ZIndexプロパティを使用できます。これは、複雑なパターンのチャートオブジェクトを表示しようとする際に便利です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using cAlgo.API;
namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var firstVerticalLine = Chart.DrawVerticalLine("line1", Chart.LastVisibleBarIndex, Color.Red);

            firstVerticalLine.IsInteractive = true;

            var secondVerticalLine = Chart.DrawVerticalLine("line2", Chart.LastVisibleBarIndex, Color.Yellow);

            secondVerticalLine.IsInteractive = true;

            firstVerticalLine.ZIndex = secondVerticalLine.ZIndex + 1;
        }

        public override void Calculate(int index)
        {
        }
    }
}

チャートに添付された場合、上記のインジケーターは黄色ではなく赤い縦線を表示します。最初の線のZIndexプロパティの値が2番目の線の対応する値よりも高いため、2番目の(黄色い)線よりも優先されます。

言い換えれば、ZIndexプロパティは、オーバーラップしたときにどのチャートオブジェクトが最初に表示されるかを決定します。すべての描画されたチャートオブジェクトには、ZIndexプロパティの一定の値が自動的に割り当てられます。

オブジェクトが削除されたかどうかの確認

すべてのチャートオブジェクトは、ChartObjectベースクラスからIsAliveプロパティを継承します。このプロパティの値は、オブジェクトがチャート上に存在する限りtrueです(表示されているかどうかに関係なく)。オブジェクトがチャートから削除されると、値はfalseに設定されます。

チャートオブジェクトへの参照を保存し、このオブジェクトがユーザーによって削除された場合、IsAliveプロパティをチェックして、オブジェクトが「生存」しているか「死亡」しているかを確認できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using cAlgo.API;
namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        private ChartVerticalLine _verticalLine;

        protected override void Initialize()
        {
            _verticalLine = Chart.DrawVerticalLine("line1", Chart.LastVisibleBarIndex, Color.Red);
            _verticalLine.IsInteractive = true;

            Chart.ObjectsRemoved += Chart_ObjectsRemoved;

            Print(_verticalLine.IsAlive);
        }

        private void Chart_ObjectsRemoved(ChartObjectsRemovedEventArgs obj)
        {
            Print(_verticalLine.IsAlive);

            /* If the object is removed, we should rid of its
            reference. Otherwise, it will remain in memory. */
            if (_verticalLine.IsAlive is false)
            {
                _verticalLine = null;

                Print("Object reference removed");
            }
        }

        public override void Calculate(int index)
        {
        }
    }
}

このインジケーターのインスタンスを実行し、赤い線を右クリックして削除すると、ログには"Object reference removed"というメッセージが出力されるはずです。

「死亡」したチャートオブジェクトへの参照を保持すると、メモリリークが発生します。ガーベジコレクション中に、オブジェクトは「生存」と見なされ、コレクションプロセスを「生き延びる」ことになります。

この問題を回避するには、ObjectsRemovedイベントをIsAliveプロパティと組み合わせて使用してください。

バーインデックスと時間のどちらを使用するか?

チャートオブジェクトをコーディングする際には、X軸にチャートの時間またはバーインデックスを使用することができます。

私たちの意見では、チャート時間の方が優れたオプションです。バーインデックスを使用する場合、将来の値を計画することができず(必要なインデックスがまだ存在しないため)、バー間のスペースを考慮することもできません。ただし、バーインデックスは、比較的単純なチャートオブジェクトの場合、使いやすいかもしれません。

すべてのChart.Drawメソッドには、バーインデックスとチャート時間の異なるオーバーロードがあります。

目次

このページについて