コンテンツにスキップ

バーイベントの処理方法

バーイベントは、あらゆるcBotのライフサイクルにおいて重要です。 これらのイベントを適切に処理することは、cBotが新しい市場条件にどのように反応するかを管理するために不可欠です。 この記事と対応するビデオでは、主要なタイプのバーイベントをデモンストレーションし、cTrader APIによって公開されているこれらのイベントのハンドラーについて説明します。

  • バー - cTraderによって取引チャート上に順次描画されるさまざまなタイプのオブジェクトを指します。 ローソク足、Renkoブリック、レンジバー、または平均足キャンドルなどが含まれます。

BarOpenedイベントを処理する

バーイベントは、cBotにリンクされた取引チャート上に新しいバーが描画され始めたときに発生します。 BarOpenedイベントは、チャート上に描画され始めた新しいバーに対して発生します。

このイベントの処理は、基本クラスRobotから継承されたOnBar()メソッドを介して行われます。 ここでは、市場センチメントを分析するための戦略の一部としてBarOpenedイベントを処理するcBotを作成します。 テンプレートからOnStart()OnStop()メソッドを削除し、OnTick()ハンドラーをOnBar()ハンドラーに置き換えます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
protected override void OnBar()
{
    var previousBar = Bars[Bars.Count - 2];
    var priceDifference = ((Bars.LastBar.Open - previousBar.Open) / previousBar.Open) * 100;
    if (priceDifference > 1)
    {
        ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000);
    }
    else if (priceDifference < -1)
    {
        ExecuteMarketOrder(TradeType.Sell, SymbolName, 10000);
    }
    else 
    {
        foreach (var position in Positions) 
        {
            position.Close();
        }
    }
}

このcBotは、D1(日足)のタイムフレームでチャート上で起動されることを想定しています。 各バーで、前のバーの始値との差を比較し、適切な方向に新しい注文を出します。 価格差が無視できる場合、ボットは代わりに現在開いているすべてのポジションをクローズします。

このシンプルなボットをバックテストすると、結果は有望に見えます。

BarClosedイベントを処理する

新しいバーが開いたとき、それは実質的に始値を除いて価格データを持っていません。 多くの場合、cBotが前のバーのデータにアクセスして、戦略の実行をスムーズにしたい場合があります。 これが、BarClosedイベントがちょうどクローズしたバー(新しいバーの直前のバー)に対して発生し、その価格とボリュームデータを簡単に使用できる理由です。 BarClosedイベントがトリガーされると、新しく開かれたバーはBarsコレクションから完全に除外されます

BarClosedイベントを処理するために、APIはOnBarClosedメソッドを公開しています。

注意

前の例では、Bars.LastBar.Openプロパティを使用して、新しく開かれたバーの始値を取得しました。 OnBarClosed()メソッドで同じプロパティを使用すると、ちょうどクローズしたバーの始値を取得できます。

以下のようにOnBarClosed()ハンドラーを使用するシンプルなcBotを作成します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
protected override void OnBarClosed()
{
    var lowCloseDifference = ((Bars.LastBar.Close - Bars.LastBar.Low) / Bars.LastBar.Close) * 100;
    if (lowCloseDifference > 0.5)
    {
        foreach (var position in Positions)
        {
            position.Close();
        }
        ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000, null, null, 50);

    }
}

このcBotは、キャンドルの下ヒゲの長さを評価して強気(ハンマー)パターンを検出します。 ハンマーパターンが検出された場合、以前に開いていたすべてのポジションをクローズし、50ピップの損切り付きで新しい買い注文を出します。

このボットをバックテストすると、良好な結果が得られます。

カスタムイベントハンドラーの追加

BarOpened および BarClosed イベントを処理する際、これらのイベントにカスタムハンドラーを割り当てることで、少し異なる構文を使用することもできます。 OnBar() および OnBarClosed() は一度しかトリガーされませんが、カスタムハンドラーは必要なだけ割り当てることができ、複雑なロジックを追加することが可能です。

注意

カスタムイベントハンドラーは OnStart() メソッド内で追加する必要があります。 また、カスタムハンドラーは BarOpened イベントの場合は BarOpenedEventArgs 型、BarClosed イベントの場合は BarClosedEventArgs 型の引数を受け取る必要があります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
protected override void OnStart() 
{
    Bars.BarClosed += BarClosedHandler;
    Bars.BarClosed += AnotherClosedHandler;
    Bars.BarOpened += BarOpenedHandler;
}

void BarClosedHandler(BarClosedEventArgs args) {}
void AnotherClosedHandler(BarClosedEventArgs args) {}
void BarOpenedHandler(BarOpenedEventArgs args) {}

BarOpened イベントに対して2つのカスタムハンドラーを使用して、可能な強気と弱気の反転に対応する別のcBotを作成します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
protected override void OnStart() 
{
    Bars.BarOpened += BullishReversal;
    Bars.BarOpened += BearishReversal;

}

private void BullishReversal(BarOpenedEventArgs args) 
{
    if (Bars.LastBar.Open > Bars.Last(1).Close && Bars.LastBar.Open > Bars.Last(2).Close) 
    {
        ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000, null, 10, 50);
    }
}

private void BearishReversal(BarOpenedEventArgs args) 
{
    if (Bars.LastBar.Open < Bars.Last(1).Close && Bars.LastBar.Open < Bars.Last(2).Close) 
    {
        ExecuteMarketOrder(TradeType.Sell, SymbolName, 10000, null, 10, 50);
    }
}

このcBotは、新しく開かれたバーの始値が前の2つのバーの終値よりも高いかどうかをチェックします。 これが該当する場合、買い注文が実行されます。 始値が前の2つのバーの終値よりも低い場合、売り注文が実行されます。 2つの別々のイベントハンドラーを使用することで、取引ロジックを小さなコンポーネントに分割し、後で必要に応じて簡単に変更できるようになります。

D1タイムフレームでのバックテストの結果も良好です。

概要

バーイベントを適切に処理する方法を学ぶことで、cBotに正確に望む動作をさせることができます。