コンテンツにスキップ

cTraderでテクニカルインジケーターを作成する

この記事では、cTraderでのアルゴリズム取引またはマニュアル操作のためのツールを含む、カスタムテクニカルインジケーターを作成する手順を説明します。

Algoアプリのインジケータータブで、新規ボタンをクリックしてアルゴリズム作成ウィザードを開きます。

インジケーターの名前を入力し、C#Pythonの間でプログラミング言語を選択します。

以下から作成方法を選択します:

  • ゼロから作成 – 新しいインジケーターには基本的なテンプレートのみが含まれます。

  • テンプレートを使用Python#またはC#テンプレートのリストから事前に作成されたアルゴリズムを選択できます。これらは、さまざまなインジケータータイプ、テクニカル分析ツールなどをカバーしています。

注意

事前に作成されたアルゴリズムには、計算とカスタマイズ可能なパラメーターのロジックが既に含まれています。 このようなインジケーターは、保存してビルドするとすぐにチャートに表示できます。

作成をクリックすると、コードエディターが開き、インジケーターコードの編集を開始できます。

コードを編集する

作成方法に応じて、インジケーターコードサンプルには以下の要素の1つ以上が含まれている必要があります:

 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
[Indicator(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class SimpleIndicator : Indicator
{
    [Parameter(DefaultValue = "Hello world!")]
    public string Message { get; set; }

    [Output("Main")]
    public IndicatorDataSeries Result { get; set; }

    protected override void Initialize()
    {
    // Called once when the indicator is launched
    // Initialise variables, nested indicators or series

        Print(Message);
    }

    public override void Calculate(int index)
    {
    // Called automatically on each historical bar
    // Also called in real-time on each tick
    // Place the indicator formula and logic here
    }

    // === Custom Methods ===
    // Add helper methods below to structure your indicator logic

}

Indicator属性とそのオプションのプロパティ(TimeZoneAccessRightsなど)は、インジケータークラス(SimpleIndicator)の宣言の前に置かれます。

これらのメソッドは、デフォルトですべてのインジケーターに含まれています:

  • Initialize()メソッドは、インジケーターが開始するときに1回呼び出されます。 これは通常、最初から準備しておく必要がある変数、ネストされたインジケーター、シリーズを設定するために使用されます。
  • Calculate()メソッドは、各履歴バーで自動的に、そしてリアルタイムで新しいティックごとに呼び出されます。 ここでインジケーターの式を実装し、結果の計算と表示方法を定義します。

[Output()]属性は、インジケーターが生成する値とそれらがチャート上にどのように表示されるかを指定します。 各出力の名前やスタイルをカスタマイズできます。たとえば、ラインの色を設定することができます。

Initialize()Calculate()メソッドは、すべてのカスタムインジケーターの基盤であり、決して省略してはいけません。 cBotをコーディングするときと同様に、独自のメソッドを追加して機能を拡張できます。 アルゴリズムについて詳しく学ぶには、C#の基本ガイドから始め、インジケーターコードの例を参照してください。

注意

リファレンスには、cTraderでアルゴリズムを構築するためのすべてのクラス、イベント、メソッド、変数などが含まれており、完全なアルゴリズムの例とテンプレートはGitHubリポジトリで利用できます。"

新しい知識を適用して、インジケーターコードを編集し、ニーズに合わせて調整します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class SimpleIndicator:
    def initialize(self):
        # Called once when the indicator is launched
        # Initialise variables, nested indicators or series
        api.Print(api.Message)

    def calculate(self, index):
        # Called automatically on each historical bar
        # Also called in real-time on each tick
        # Place the indicator formula and logic here
        api.Result[index] = 100 # Example calculation

    # === Custom Methods ===
    # Add helper methods below to structure your indicator logic

SimpleIndicatorクラスは、Pythonでカスタムインジケーターを定義します。

これらのメソッドは、デフォルトですべてのインジケーターに含まれています:

  • initialize(self)メソッドは、インジケーターが開始するときに1回呼び出されます。 これは通常、最初から準備しておく必要がある変数、ネストされたインジケーター、シリーズを初期化するために使用されます。
  • calculate(self, index)メソッドは、各履歴バーで自動的に、そしてリアルタイムで新しいティックごとに呼び出されます。 ここでインジケーターの式を実装し、結果の計算と表示方法を定義します。

initialize(self)calculate(self, index)メソッドは、すべてのカスタムインジケーターの基盤であり、決して省略してはいけません。 cBotをコーディングするときと同様に、クラス内に独自のヘルパーメソッドを追加して機能を拡張できます。 アルゴリズムについて詳しく学ぶには、Pythonの基本から始め、インジケーターコードの例を参照してください。

新しい知識を適用して、インジケーターコードを編集し、ニーズに合わせて調整します。

保存とビルド

コードエディターの上部にある保存ボタンをクリックするか、Ctrl+Sショートカットを使用してコードを保存します。

インジケーターを使用する前に、インジケータープロジェクトをビルドしてコードを検証する必要があります。 コードエディターの上部にあるビルドボタンをクリックするか、Ctrl+Bを押します。

コードエディターの上部にある保存アイコンをクリックするか、Cmd+Sショートカットを使用してコードを保存します。

インジケーターを使用する前に、インジケータープロジェクトをビルドしてコードを検証する必要があります。 コードエディターの上部にあるビルドアイコンをクリックするか、Cmd+Bを押します。

ビルドが成功すると、ビルド結果に確認メッセージが表示されます。 ビルドが失敗した場合は、発生したすべてのエラーの概要が代わりに表示されます。

最後のビルド以降にコードに変更がある場合、ビルドアイコンの横にアスタリスクが表示されます。 この場合、チャートにインジケーターのインスタンスを追加する前に、再度ビルドする必要があります。

チャート上でインジケーターを使用または表示するには、インジケーターのインスタンスを追加するか、セクションで説明されているようにインジケーターコードを引き続き変更できます。

NaN演算を使用

インジケーターは特定の視覚効果を出力するために計算を実行します。これらの計算中に、コードがフリンジケースや境界条件を正しく処理することが重要です。

以下は、デトレンド価格オシレーターを出力するインジケーターからのスニペットです:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
private MovingAverage movingAverage;

protected override void Initialize()
{
    movingAverage = Indicators.SimpleMovingAverage(Source, Periods);
}

public override void Calculate(int index)
{
    Result[index] = Source[index] - movingAverage.Result[index - Periods / 2 - 1];
}

上記のコードは一般的な計算ルールを定義していますが、境界条件を省略しています。 たとえば、Periods10に設定されていて、index0–9の範囲にある場合、計算はNaN(Not a Number)を返します。 この問題は、インジケーターが負のインデックスを持つバーチャートの値を計算できないために発生します。

この問題に対処するために、以下のように条件を追加できます:

1
2
3
4
5
6
7
public override void Calculate(int index)
{
    if (index >= Periods + Periods / 2 + 1)
    {
        Result[index] = Source[index] - movingAverage.Result[index - Periods / 2 - 1];
    }
}

単純移動平均自体のコードも、index >= Periodsをチェックする必要があります。 別のタイプの移動平均などのネストされたインジケーターを使用する場合、追加の計算を考慮して条件が異なります。

明示的な境界条件を定義することもできますが、C#ではNaN演算を使用してこれらの問題を回避する便利な方法があります。 具体的には、doubleデータ型はNaN計算を完全にサポートしています。 例えば:

1
2
3
4
5
double result = double.NaN + 1.4; 
// result will be NaN

bool isNaN = double.IsNaN(result); 
// isNaN will be true

ただし、計算中のオペランドがNaNの場合、結果もNaNになります。 カスタムcTraderインジケーターはDataSeriesタイプで動作するため、負のインデックスでDataSeries要素にアクセスしようとすると、NaNが返され、値は取引チャート上に描画されません。 この動作により、インジケーターは例外をスローせずに動作を続けることができます。 ほとんどの場合、境界条件を安全に無視し、一般的な計算ロジックにのみ集中できます。

明示的なチェックを追加する

NaN演算は境界条件の処理を簡素化しますが、いくつかのケースでは明示的なNaNチェックが必要です。 再帰的なインジケーターはその一般的な例です。 再帰的なインジケーターは、以前に計算された値に基づいて現在の値を計算します。

以下の指数移動平均の実装を考えてみましょう:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public override void Calculate(int index)
{
    var previousValue = Result[index - 1];

    if (double.IsNaN(previousValue))
    {
        Result[index] = Source[index];
    }
    else
    {
        Result[index] = Source[index] * _exp + previousValue * (1 - _exp);
    }
}

インジケーターが最初の期間を計算する際、初期値を明示的に非NaN型に設定する必要があります。 そうしないと、すべての後続の計算がNaNを返し、インジケーターが無効になります。

上記のコードでは、これはdouble.IsNaN(previousValue)メソッドで処理されています。 ==演算子はこのチェックに使用できません(previousValue == double.NaN)。なぜなら、NaNと他の値(それ自体を含む)との比較は常にfalseと評価されるためです。

インジケーターコードに満足したら、ビルドし、インスタンスを追加してチャートに使用します。

Image title