コンテンツにスキップ

Grid cBot

戦略概要

Grid cBotは、通貨ペアの複数の買い注文または売り注文を一定の価格間隔または「ステップ」で配置し、ポジションの「グリッド」を形成するグリッド取引戦略を実装します。 通貨ペアの価格が変動すると、価格変動を利用するために新しいポジションが常に開かれます。

Grid cBotは、単純な算術と論理チェックの組み合わせを使用して、ポジションを開き、利益を計算し、取引操作を管理します。 これはレンジ相場または横ばい相場で最も効果的です。 また、ボラティリティの低い状況や、既知の抵抗線と支持線がある市場でもうまく機能します。

cBotの作成

C#またはPythonを使用してcBotを作成する方法を、ステップバイステップのガイドで学びます。

Grid cBotのコードは、公開されているC#およびPythonリポジトリで利用可能です。 同じコードが、cTrader WindowsまたはMacのアルゴリズム作成ウィザードでテンプレートとして提供されており、以下のスニペットをコピーして使用することもできます:

 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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class Grid : Robot
    {
        [Parameter("Volume (lots)", DefaultValue = 0.01, MinValue = 0.01, Step = 0.01)]
        public double VolumeInLots { get; set; }

        [Parameter("Trade Side")]
        public TradeType TradeType { get; set; }

        [Parameter("Step (pips)", DefaultValue = 5, MinValue = 0.1, Step = 0.1)]
        public double StepPips { get; set; }

        [Parameter("Target Profit", DefaultValue = 20)]
        public double TargetProfit { get; set; }

        private bool enoughMoney = true;

        protected override void OnStart()
        {
            if (GridPositions.Length == 0)
                OpenPosition();
        }

        protected override void OnTick()
        {
            if (GridPositions.Sum(p => p.NetProfit) >= TargetProfit)
            {
                Print("Target profit is reached. Closing all grid positions");
                CloseGridPositions();
                Print("All grid positions are closed. Stopping cBot");
                Stop();
            }
            if (GridPositions.Length > 0 && enoughMoney)
            {
                var lastGridPosition = GridPositions.OrderBy(p => p.Pips).Last();
                var distance = CalculateDistanceInPips(lastGridPosition);

                if (distance >= StepPips)
                    OpenPosition();
            }
        }

        private Position[] GridPositions
        {
            get
            {
                return Positions
                    .Where(p => p.SymbolName == SymbolName && p.TradeType == TradeType)
                    .ToArray();
            }
        }

        private double CalculateDistanceInPips(Position position)
        {
            if (position.TradeType == TradeType.Buy)
                return (position.EntryPrice - Symbol.Ask) / Symbol.PipSize;
            else
                return (Symbol.Bid - position.EntryPrice) / Symbol.PipSize;
        }

        private void OpenPosition()
        {
            var result = ExecuteMarketOrder(TradeType, SymbolName, Symbol.QuantityToVolumeInUnits(VolumeInLots), "Grid");
            if (result.Error == ErrorCode.NoMoney)
            {
                enoughMoney = false;
                Print("Not enough money to open additional positions");
            }
        }

        private void CloseGridPositions()
        {
            while (GridPositions.Length > 0)
            {
                foreach (var position in GridPositions)
                {
                    ClosePosition(position);
                }
            }
        }
    }
}
 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
import clr

clr.AddReference("cAlgo.API")

# Import cAlgo API types
from cAlgo.API import *

# Import trading wrapper functions
from robot_wrapper import *

class GridSample():
    def on_start(self):
        self.volumeInUnits = api.Symbol.QuantityToVolumeInUnits(api.VolumeInLots)
        self.enoughMoney = True
        if len(self.get_grid_positions()) == 0:
            self.open_position()

    def on_tick(self):
        grid_positions = self.get_grid_positions()
        net_profit_sum = sum([p.NetProfit for p in grid_positions])
        if net_profit_sum >= api.TargetProfit:
            api.Print("Target profit is reached. Closing all grid positions")
            self.close_grid_positions()
            api.Print("All grid positions are closed. Stopping cBot")
            api.Stop()

        if len(grid_positions) > 0 and self.enoughMoney == True:
            position_with_highest_pips = sorted(grid_positions, key=lambda pos: pos.Pips, reverse=True)[0]
            distance = self.get_distance_in_pips(position_with_highest_pips)          
            if distance >= api.StepPips:
                self.open_position()

    def get_grid_positions(self):
        return [pos for pos in api.Positions if pos.SymbolName == api.SymbolName and pos.TradeType == api.TradeType]

    def open_position(self):
        result = api.ExecuteMarketOrder(api.TradeType, api.SymbolName, self.volumeInUnits, "Grid")
        if result.Error == ErrorCode.NoMoney:
            self.enoughMoney = False
            api.Print("Not enough money to open additional positions")

    def close_grid_positions(self):
        for position in self.get_grid_positions():
            position.Close()

        if len(self.get_grid_positions()) > 0:
            self.close_grid_positions()

    def get_distance_in_pips(self, position):
        return (position.EntryPrice - api.Symbol.Ask if position.TradeType == TradeType.Buy else api.Symbol.Bid - position.EntryPrice) / api.Symbol.PipSize

インジケーターの統合

Grid cBotは、グリッド戦略を定義するためにインジケーターに依存しません。通貨ペアの価格が上がるか下がるかを予測しようとしません。 代わりに、あらゆる方向の価格変動から利益を得ることを目指します。

cBotは、この単純なルールに基づいて取引を実行します:通貨ペアの価格が指定されたpips数(StepPipsパラメーターで定義)を超えて動いた場合、cBotは新しいポジションを開きます。

計算とロジック

初期取引の実行

cBotが開始すると、グリッド内にオープンポジションがあるかどうかをチェックします。 オープンポジションがない場合、cBotはOpenPosition()メソッドを通じて即座に最初のポジションを開きます。 この最初のステップにより、指定された取引サイド(TradeType)に基づいて初期取引でグリッドが開始されます。

利益のモニタリング

各ティック(例えば、各価格更新)で、cBotはすべてのオープングリッドポジションの累積純利益が指定された目標利益(TargetProfit)に達しているかまたは超えているかをチェックします。 目標利益に達した場合、すべてのオープンポジションが決済され、cBotは実行を停止します。

目標利益は、グリッド内の各ポジションの純利益の合計です。

\[ \text{総純利益} = \sum_{i=1}^{n} \text{純利益}(p_i) \]

\(n\) – グリッド内のオープンポジションの数

\(\text{NetProfit}(p_i)\) – ポジション\(i\)の純利益

ポジションの開設

目標利益に達していない場合で、オープンポジションがある場合、cBotは最後に開いたグリッドポジションと現在の市場価格との間の距離(pips)を計算します。

買いポジションの場合:

\[ D_b = \frac{P_e - P_a}{S} \]

売りポジションの場合:

\[ D_s = \frac{P_b - P_e}{S} \]

\(D_b\) – エントリー価格と現在の買値の間の距離(pips)。

\(D_s\) – 現在の売値とエントリー価格の間の距離(pips)。

\(P_e\) – 通貨ペアの最後の買いポジションが開かれた価格。

\(P_a\) – 通貨ペアの現在の買値。

\(P_b\) – 通貨ペアの現在の売値。

\(S\) – 通貨ペアの1 pipの価値。

計算された距離が定義されたステップサイズ(StepPips)以上の場合、OpenPosition()メソッドを使用して新しいポジションが開かれます。

新しいポジションを開く前に毎回、cBotは操作に十分な資金があることを確認します。 資金が不足している場合、cBotは新しいポジションを開こうとするのを停止し、「追加のポジションを開くのに十分な資金がありません」というメッセージをログに記録します。

ポジションの決済

TargetProfitに達すると、cBotは「目標利益に達しました。すべてのグリッドポジションを決済します」 というメッセージをログに記録します。

その後、CloseGridPositions()メソッドがグリッド内のすべてのオープンポジションをループ処理し、それらを決済し、cBotは「すべてのグリッドポジションが決済されました。 cBotを停止します」というメッセージをログに記録します。 その後、cBotは停止されます。

パラメーター

パラメーター 単位 定義 ヒント
数量 ロット 各取引の取引高。 保守的なトレーダーは、特にボラティリティの高い市場でエクスポージャーを減らし、リスクを慎重に管理するために、小さなロットサイズを指定することがあります。 これにより、市場がグリッドに反して動いた場合の潜在的な損失が最小限に抑えられます。

積極的なトレーダーは、市場に自信がある場合に利益を最大化するために大きなロットサイズを指定することがあります。 このアプローチはよりリスクが高いですが、グリッドが大きな価格変動を効果的に捉えた場合、より大きなリターンをもたらします。
トレードサイド 取引の方向(買いまたは売り)。 上昇相場では、トレーダーは買いを選択することがあります。 通貨ペアが一時的に下方修正する際、cBotは低い水準で買いを入れます。 市場が再び上昇すると、各買いポジションが利益を生みます。

下落相場では、トレーダーは売りを選択することがあります。 通貨ペアの価格が一時的に上方修正する際、cBotは高い水準で売りを入れます。 市場が再び下落すると、各売りポジションが利益を生みます。
ステップ Pip 2つの連続するグリッドポジション間の距離。 ステップが小さいほど、新しい取引が頻繁に開かれ、ステップが大きいほど取引回数が少なくなります。 横ばいまたは低ボラティリティ市場では、トレーダーは小さい値を設定することがあります。 この設定により、cBotがより頻繁にポジションを開き、特に価格が狭いバンド内で動く場合に小さな価格変動を捉えることができます。

トレンドのある、またはよりボラティリティの高い市場では、トレーダーは大きい値を設定することがあります。 この設定により、開かれる取引の数が減少し、cBotがより大きな動きを捉えることができ、強いトレンド中のオーバートレードを避けるのに役立ちます。
目標利益 cBotが全ての開いているポジションを閉じて取引を停止する前に達成しなければならない、口座通貨での累積利益。 素早く小さな利益を求めるトレーダーは、低い値を設定することがあります。 この設定により、小さな利益が出た時点でグリッドが閉じられ、ボラティリティの高い市場でポジションを長く保持するリスクを最小限に抑えます。

大きな利益を待つことを好むトレーダーは、高い値を設定することができます。 この設定により、グリッドをより長く開いたままにし、cBotが全てのポジションを閉じる前に、一連の大きな市場の動きを通じて利益を蓄積することができます。

応用

レンジ相場または横ばい相場

Grid cBotは、価格がサポートとレジスタンスのレベルの間で振動する、レンジ相場で最も効果的です。 このような市場では、価格が定義された範囲内で頻繁に上下するため、cBotは定期的にポジションを開き、変動を利用します。

ユースケース

EURUSDが1.1000から1.1100の範囲内にとどまるシナリオを考えてみましょう。 cBotは価格が1.1000に近づくと買いポジションを開き、1.1100付近で売りポジションを開きます。 価格がこれらのレベルの間で振動するにつれ、cBotは各スイングから利益を得ます。

!!! info "情報" 「ベストプラクティス」

- 頻繁な価格スイングを捉えるために小さなステップサイズを設定します。
- 適度な目標利益を設定し、グリッドが頻繁に閉じるようにして、小さくても一貫した利益を確保します。
- レンジからのブレイクアウトを引き起こし、大きなドローダウンを引き起こす可能性のある市場ニュースや今後のイベントを監視します。

低ボラティリティ市場

低ボラティリティ市場では、価格の動きは緩やかで、あまり顕著ではない傾向があります。 価格が徐々に動くにつれて、Grid cBotは大きな急速な市場変動のリスクに直面することなく、複数のポジションを開くための十分な時間を得ることができます。

ユースケース

アジア取引セッション中によく見られるように、USDJPYが低ボラティリティを示すシナリオを考えてみましょう。 Grid cBotは小さなステップサイズでポジションを開き、その静かな時間帯に発生する小さな緩やかな価格の動きを捉えることができます。

!!! info "情報" 「ベストプラクティス」

- 低ボラティリティ市場に典型的な小さな価格の動きを活用するために、狭いステップサイズを使用します。
- ボラティリティが予期せず上昇した場合のリスクを減らすために、低い取引量を設定します。
- 市場の状況、予期せぬニュースやイベントに注意を払い、cBotを素早く停止できるよう準備しておきます。

既知のレベルがある市場

Grid cBotは、強力で明確に定義されたサポートとレジスタンスのレベルがある市場でうまく機能します。 これらのレベルは価格の障壁として機能し、市場が頻繁に反発する原因となり、cBotが利用できるレンジを生み出します。

ユースケース

金(XAUUSD)の価格が、2,000ドルの強力なサポートレベルと2,050ドルのレジスタンスレベルの間で振動するシナリオを考えてみましょう。 Grid cBotは2,000ドル付近で買い注文を、2,050ドル付近で売り注文を出し、これらのレベル間で価格が跳ね返ることから利益を得ます。

!!! info "情報" 「ベストプラクティス」

- 市場のボラティリティに基づいてステップサイズを設定します。 高ボラティリティ市場ではより大きなステップサイズが必要かもしれませんが、低ボラティリティ市場では小さなステップを使用できます。
- ブレイクアウトに巻き込まれるのを避けるために、確立されたサポートとレジスタンスレベルがある市場の周辺でGrid cBotを使用します。
- 大きな損失を避けるために、ブレイクアウトを引き起こす可能性のあるイベントやニュースに注意してください。 cBotは、市場がサポートまたはレジスタンスレベルを突破する状況に対処する準備ができていません。

方向性のないマーケット

特定の通貨ペアは、頻繁な価格変動を示すものの、長期的な強い傾向を示さない非方向性の動きを示します。 Grid cBotは、長期的なトレンドに巻き込まれるリスクなく頻繁な変動を捉えることができるため、このような市場でうまく機能します。

ユースケース

EURCHFが非方向性の動きをする場合を考えてみましょう。これは、ユーロ圏とスイス経済の安定性を考えると、よくあることです。 Grid cBotは小さなステップサイズでポジションを開くことができ、大きな方向性のあるトレンドを心配することなく、頻繁な変動から利益を得ることができます。

!!! info "情報" 「ベストプラクティス」

- 小さなステップサイズを使用して、頻繁な価格変動を捉えます。
- 市場がトレンドに突入した場合のリスク管理のため、低い取引量の設定を検討します。

概要

Grid cBotは、強気市場と弱気市場の両方で、リトレースメントまたはプルバックが発生するという前提で動作します。 強気市場では安く買って高く売り、弱気市場では高く売って安く買います。cBotは、リトレースメント後に市場が主要トレンドに戻った時に利益を得ます。

cBotはインジケーターを使用しないため、市場がトレンド中かレンジ中かを評価できません。 単に価格の動きのみに基づいてポジションを開き、市場センチメントやトレンドの強さを無視します。

インジケーターがないため、取引プロセスは純粋に機械的です。cBotは一定の間隔でポジションを開くための事前に定義されたルールのみに依存します。 このアプローチはレンジ相場では収益性が高い可能性がありますが、トレンド相場や高ボラティリティ、急激に変化する市場では苦戦する傾向があります。

トレーダーは、cBotを個人の戦略に合わせて設定するだけでなく、市場状況に基づいて取引をフィルタリングするためにインジケーターを導入することを検討できます:

  • Moving Averages (MA)は市場のトレンドを特定するのに役立ち、cBotがトレンドの方向にのみ取引することを可能にします。
  • Relative Strength Index (RSI)は、過買または過売の状態を示すことができ、市場が一方に偏っているときに新しいポジションを開くのを避けるのに役立ちます。
  • Bollinger Bandsは価格のボラティリティに関する洞察を提供し、cBotがグリッドの間隔を調整したり、高いボラティリティの期間中に取引を控えたりすることを可能にします。