コンテンツにスキップ

チャートオブジェクトと図

チャートオブジェクト(図)を使用すると、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", "This is the text that will be shown", VerticalAlignment.Center, HorizontalAlignment.Center, Color.Red);

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

Image title

垂直線

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

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

水平線

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

1
2
3
/* We use the maximum of the high prices
of the last ten bars as the Y coordinate. */ 
var horizontalLine = Chart.DrawHorizontalLine("line", Bars.HighPrices.Maximum(10), Color.Red);

トレンドライン

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

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

1
2
3
4
5
6
7
/* We draw a line from the low price
 of the first visible bar to the high price
 of the last visible bar on the chart. */
var trendLine = Chart.DrawTrendLine("line", Chart.FirstVisibleBarIndex, Bars.LowPrices[Chart.FirstVisibleBarIndex], Chart.LastVisibleBarIndex, Bars.HighPrices[Chart.LastVisibleBarIndex], Color.Red);

// Alternatively, consider the following.
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
4
5
6
7
var rectangle = Chart.DrawRectangle("rectangle", Chart.FirstVisibleBarIndex + 1, Bars.LowPrices[Chart.FirstVisibleBarIndex + 1], Chart.LastVisibleBarIndex, Bars.HighPrices[Chart.LastVisibleBarIndex], Color.Red);

/* We fill the rectangle with a transparent color.
By using its current color, we only change the alpha
channel. */
rectangle.IsFilled = true;
rectangle.Color = Color.FromArgb(80, rectangle.Color);

三角形

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
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.LowPrices[Chart.FirstVisibleBarIndex], Color.Red);

// We fill the triangle with a transparent color
// by using it's current color, we change only the alpha channel

/* We fill the triangle with a transparent color.
By using its current color, we only change the alpha
channel. */
triangle.IsFilled = true;
triangle.Color = Color.FromArgb(80, triangle.Color);

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

簡潔にするため、上記のコードスニペットではいくつかのチャートオブジェクトに言及していません。 これらのオブジェクトには以下が含まれますが、これらに限定されません:

  • 楕円形
  • アイコン
  • アンドリューズピッチフォーク
  • 等間隔価格チャネル
  • フィボナッチ・エクスパンション
  • フィボナッチ・ファン
  • フィボナッチリトレースメント

これらすべてのオブジェクトは、同様のパラメータを受け取るDraw...()メソッドを使用して描画できます。

リスクリワード

ChartRiskRewardインターフェースは、チャート上でリスクリワードオブジェクトをプログラム的に作成および管理するためのタイプを提供します。

以下のコードは、リスクリワードオブジェクトを描画するインジケーターを作成する方法を示しています:

 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
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo
{
    [Indicator(AccessRights = AccessRights.None, IsOverlay = true)]
    public class SimpleRiskReward : Indicator
    {
        protected override void Initialize()
        {
            var type = new ChartRiskRewardFixedRiskType(
                ChartRiskRewardAmountType.BalancePercentage, 
                1                                            
            );
            var tradeType = TradeType.Buy;
            var orderType = OrderType.Market;

            var entryPrice = Chart.Bars.LastBar.Close;
            var time1 = Chart.LastVisibleBarIndex - 20; 
            var time2 = Chart.LastVisibleBarIndex;      

            var rr = Chart.DrawRiskReward(
                "SimpleRR",     
                time1,           
                time2,            
                entryPrice,       
                orderType,        
                tradeType,        
                type              
            );

            rr.IsInteractive = true;

            rr.RiskColor = Color.Yellow;
            rr.RiskLineStyle = LineStyle.DotsRare;
            rr.RiskThickness = 3;

            rr.RewardColor = Color.Blue;
            rr.RewardLineStyle = LineStyle.LinesDots;
            rr.RewardThickness = 2;

            PrintRRInfo(rr);
        }

        private void PrintRRInfo(ChartRiskReward rr)
        {
            Print($"Name: {rr.Name} | Type: {rr.Type.GetType().Name} | Order Type: {rr.OrderType} | Trade Type: {rr.TradeType} | Time 1: {rr.Time1:o} | Time 2: {rr.Time2:o} | Entry: {rr.EntryPrice} | SL: {rr.StopLossPrice} | TP: {rr.TakeProfitPrice} | RR: {rr.RiskRewardRatio} | Volume: {rr.VolumeInUnits}");
        }

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

キーオブジェクト設定

チャートオブジェクトの命名

チャートオブジェクトを描画しようとするときは常に、描画メソッドの引数としてその名前を指定する必要があります。

すべてのチャートオブジェクト名は一意でなければなりません。 この要件が満たされていない場合、実行時間に応じて同じ名前のチャートオブジェクトが上書きされるリスクがあります。 各オブジェクトの一意の名前を生成するために、現在のバーインデックス値または現在の時間を使用できます。

チャートオブジェクトへのアクセス

すべてのチャートオブジェクトはObjectsコレクション内に含まれています。 このコレクションにはユーザー描画オブジェクトも含まれます。 その結果、Objectsコレクションにアクセスして、チャートからオブジェクトを削除したり、そのプロパティを変更したりできます。

以下の例は、Objectsコレクションのメンバーにアクセスする方法を示しています:

 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メソッドを使用してインタラクティブオブジェクトをクリーンアップするようにしてください。

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

ロックされたオブジェクトとロックされていないオブジェクト

チャートオブジェクトをロックすると、ユーザーがそれを変更または更新できなくなります。 これは、Trader(チャートプロパティ)ボックスを使用するか、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 メソッドには、バーインデックスとチャート時間の異なるオーバーロードがあります。