cTrader/cBotの開発部屋

Mr. Robo Traderの開発ブログ


ブルベア型自家製『レバナス』自動売買取引ボット

最近はウクライナ戦争の地政学的リスクもあり、為替相場の動きが不安定になってきたので、より流動性が高く(相場操縦が難しい)、マクロ経済にも正直な動きをする米国株価指数に注目してみましょう。

レバナス(レバレッジNASDAQ100)とは

レバナスは米国のレバレッジ投資信託ETFのひとつです。当然、レバレッジを掛けると上昇局面では大きな利益を生みだす反面、下落相場やもみ合い相場では大きな損失となるリスクの高い金融商品です。

投資信託
・米国ETFの「TQQQ(NASDAQ100の3倍の値動き)」など
・大和アセットマネジメントの「iFreeレバレッジ NASDAQ100(NASDAQ100の2倍の値動き)」(大和レバナス)
楽天証券の「楽天レバレッジNASDAQ-100」(楽天レバナス)
NY株が右肩上がりの頃は、証券会社も最も利益の上がる金融商品として売り出したものの、今のような地政学的にも不安定な株式市場では大きな損失を被るハイリスクの金融商品となっている。金融庁もNISAの対象外にしたようです。


米国株価指数の留意点

もっと安全なブルベア型自家製「レバナス」スキャルピング・ボットが作れないか?
cTraderは、米国株価指数も普通に取引できます。cBotを使えば、自動売買取引も可能になります。
米国株価指数のcBotを作る際、FX通貨ペアのロットサイズや、ピップサイズと大きく異なり、しかもFX業者ごとに変数が異なるため汎用ボットの普及は難しくなり、プログラムも難しくなります。


ここでは、cTraderの使える海外FX業者「Axiory」を使ってcBotプログラムを組んでみます。
AxioryのNSDQ指数は、レバレッジが100倍、スプレッドが2.1ピップス、業界としては決して有利とは言えませんが、海外FX業者の数字は客寄せ目的が多く数字はあまり信用しなくて良いですw要するに安定して利益を出せる業者が良い業者です。


レバレッジが100倍と聞いて驚く人もいるかもしれませんが、これは大きな間違いです。ロット数さえ減らせば、レバレッジ1倍であろうと、それ以下であろうと作れるのです。むしろ、国内業者の方が、投資家保護といいながら低レバにして、強制ロスカットをより頻繁に行い、さらに業者が損した場合は追証まで一般投資家に押し付けて暴利を貪っている状態で極めて悪質なのです。金融庁や証券取引委はまったく機能していません。


要するに、安全な自動売買取引を実施するためには、業者のレバレッジではなく、ロット数を正確にコントロールして資産のリスク管理をすることが重要となります。そのためには、為替通貨ペアとは異なり、FX業者によっても異なる、米国株価指数のロットサイズやピップサイズを正確に知る必要があるのです。

NSDQのロットサイズ、ピップサイズ、ティックサイズ
為替通貨ペアのロットサイズは、通貨ペア共通で海外FXの場合10万通貨です。
ティックサイズは、決済通貨によって異なり、クロス円の場合0.001(小数点以下3桁)、ドルストレートの場合0.00001(小数点以下5桁)、ピップサイズは通常10倍となります。


それでは、NSDQ指数のロットサイズ、ピップサイズ、ピップバリュー、ティックサイズ、ティックバリューについて調べてみます。
NSDQ指数のロットサイズ、ピップサイズは、為替通貨とは大きく異なっているのが分かります。特にNSDQ指数のロットサイズは20 Indicesと中途半端な値になるため、ロット数の資産リスク管理では注意する必要があります。もうひとつ、MT4に使い慣れている人はティックサイズに慣れていますが、cTraderではティックバリューが"1"だったこともあり、ピップサイズやピップバリューを使った方が無難です。

Code

double lotSize = Symbol.LotSize;
double pipSize = Symbol.PipSize;
double pipValue = Symbol.PipValue;
double tickSize = Symbol.TickSize;
double tickValue = Symbol.TickValue;

Print("LotSize={0}, PipSize={1}, PipValue={2}, TickSize={3}, TickValue={4}", lotSize, pipSize, pipValue, tickSize, tickValue);

ログ出力

LotSize=20, PipSize=1, PipValue=136.611, TickSize=0.1, TickValue=13.6611



ブルベア型自家製「レバナス」スキャルピング・ボットの開発

米国株価指数の資産管理が行えるようになったら、次は、ストラテジー・ロジックの開発です。
まず、上げ相場でも下げ相場でも利益を出すためには、トレンドフォロー型で買いと売りができること。安全と健康のためには宵越しの含み損は抱え無いこと。待つのは苦手、1日に数回は取引したい。年利100%、月利10%、DD10%以下を目指したい。などなど。


細かいフィルターやロット調整等は割愛しますが、大まかで大胆な新規注文・決済方法
・新規注文:Hull MA(10)移動平均1本だけ使う(スキャルピングはインジが少ない方がいい)
・決済注文:ATR(14)係数で決済注文する(Pipsに惑わされない)
・閉場:日計りクローズ(含み損ゼロ、マイナススワップゼロ)



ブルベア型自家製「レバナス」スキャルピング・ボットのバックテスト結果
年利:85.74%、PF:1.21、最大DD:11.80%、勝率:52.72%
1日当たり取引回数:約4.67回
100点満点とは行きませんが、レバナスのスキャルピング投資信託より利回りがよく、さらに安全設計なら良いでしょう。

ブルベア型レバナス・スキャルピングcBot

米国株価指数先物 裁定取引ボットの開発

ナスダック・ダウ株価指数先物 裁定取引(鞘取り)

相場が右肩上がりのときは、株や商品を買って保持しておくだけで資産は増えますが、相場が下落相場になったり乱高下すると資産は逆に減ってしまいます。
 
相場が上がっても下がっても利益を出すためには、相場に応じて買ったり売ったりしなければなりませんが、最近の株価や為替相場ビッグデータAIを活用したアルゴリズムを使って相場が動いていますのでなかなか儲けさせてくれません。Bloombergの記事によると、最近5年間で閉鎖されたヘッジファンドの本数は3,550本に及ぶと言われています。投資家に恐れられていた『ヘッジファンド神話』も、最近は儲かっていないということです。
 
すでに古典的テクニカル指標と言われる「移動平均」や「MACD」や「ボリンジャーバンド」等では、最近のHFT(高速高頻度取引)AIアルゴリズム相場ではまったく歯が立ちません。AIと言えば最近は無知の象徴のように聞こえますので(笑)、相場を動かしてるAIは、多くの投資家の取引情報を収集して、もっとも利益があがる相場形成方法を最適化計算している近似計算手法と申しておきます。cTraderやMT4/5の最適化近似計算とほぼ同じですね。
 
高度に情報技術化された現代の市場取引で生き残るためには、単純にEAを使って自動売買取引するような、従来の取引方法では難しくなってきました。そこで、相場を動かしているマーケットメイク業者が自由に相場を動かすことが困難な取引方法を考える必要があります。
 
ニューヨーク株式市場の株価指数先物は、もっとも流動性が高く、欧米の取引時間中は市場参加者も大変多くマーケットメイカーだけで相場を動かすことは困難と思われます。そこで、米国株価指数先物に焦点をあてて、しかも、急な下落相場でも耐えられるように複数の株価指数も織り混ぜて裁定取引(鞘取り)を行うHFT自動売買取引ボットの開発を行ってみました。
 
NY株価指数先物として、似たような動きをする「ナスダック指数先物「ダウ指数先物を選んで、cAlgo APIを用いて裁定取引ボットを作ってみました。そのバックテスト結果を動画にしたのでリンクに貼っておきます。
 
www.dropbox.com

ウォーク・フォワード テスト結果

パラメータを使って最適化したあと、パラメータを固定したままそれ以降のバックテストを実施したものをウォーク・フォワードテストと呼びます。
 
上の最適化したバックテスト結果から数日して、「ウォーク・フォワード」テストしたものが下図です。ウォーク・フォワード以降、収益曲線が急に変化するようであれば、それは「過剰フィッティング」と呼ばれ実践では使えませんが、図を見る限り問題無さそうですね。これから、リアル・フォワードテストの実施を行います。
 


NSDQ/DOW指数先物 裁定取引 ウォーク・フォワード結果
20220201023531

cTraderの初心者向け解説動画集(Forextech)

 cTraderは海外FXでは使われていますが、国内ブローカーではまだ普及していないため、cTraderの使い方を日本語で解説した書籍は見当たりません。
 ForextechさんのブログにcTraderの初心者向けの分かり安い日本語解説動画がありましたので、その中から特に役立つと思われる動画を抜粋して、ここでも紹介しておきたいと思います。
 cTraderは大変多くの機能が備わっているため、初心者だけでなく、すでにcTraderを使われている方にも参考になると思います。
 
【Forextechさんのブログ】https://forextech.jp/

cTraderの注文方法や種類

cTraderの注文について解説動画です。初めて利用する方だけでなく、cTraderを使われている方にも参考になります。
動画では、クイックトレード、新規注文ウインドウ、アドバンス設定について分かり安く解説しています。
 
【内容】
・クイックトレード
・新規注文ウインドウ
・アドバンス設定
 
youtu.be

cTraderのツールバー機能

cTraderは機能が多いので、cTraderを使ってる方でもすべての機能を使いこなせている人は少ないと思います。
この動画では、ツールバーの様々な機能を紹介しています。ツールバー機能を使えばテクニカル解析も十分可能です。
 
【内容】
ツールバーの様々な機能(チャート、ライン、描画、フィボナッチ等)
 
youtu.be

インジケーターとcBotの利用方法

cTraderで取引が出来るようになると、次はインジケーターやcBotを使ってみたくなります。
MT4/5と比べてcTraderはインジケーターが少ないと言われていますが標準的なものはそろっています。またカスタムインジケーターも公式サイトから簡単にDLできます。
 
【内容】
・インジケーターの利用方法
・cBotの利用方法
 
youtu.be

バックテストと最適化

cBotを手に入れたら、次はバックテストと最適化です。
cTraderのバックテストと最適化は数あるプラットフォームの中では最も優れているのではないかと思います。実際に使ってみるとよく分かります。
 
【MT4/5と比較して優れている点】
・利用業者のリアルティックでバックテストや最適化ができる
・最適化は、パラメータ毎に収益チャートが見れる
・最適化結果に、シャープ・レシオ (Sharp Ratio)やソルチノ・レシオ (Sortino Ratio)も表示される
 
【内容】
・バックテストの利用方法
・最適化の利用方法
 
youtu.be

cTrader/cBot プログラミングの基礎

cTraderもMT4/MT5と同様に自動売買取引機能があります。C#プログラミング言語を用いて、cTraderの取引APIを利用してcBotを作成します。MT4/5のEAでできることはcBotでも大抵できます。

cBotの作成

cTrader のメインメニューからAutomate画面を開き、cBotsタブ上の「New(新規)」ボタンをクリックして、新たに作成された「New cBot」の名前を変更します。
ソースコード・エディタにデフォルトのテンプレート・コードが作成されますので、必要なプログラムを書き加えていきます。
cBotクラス()宣言の前に、タイムゾーンやアクセス権を指定します。MT4時間に合わせるためには調整が必要となります。
OnStart()メソッドは、cBotの初期化のときに呼び出されるメソッドです。
OnTick()メソッドは、Tick毎に動作します。新規Bar毎に動作させたい場合はOnBar()メソッドを使います。
OnStop()メソッドは、cBotが停止したときに呼び出されるメソッドです。

Code

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }

        protected override void OnStart()
        {
            // Put your initialization logic here
        }

        protected override void OnTick()
        {
            // Put your core logic here
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}


成行き注文:ExecuteMarketOrder()

例1 - 注文が成功したとき
成行き注文は、ExecuteMarketOrder()関数を使います。注文が成功したときエントリー価格を出力する方法。

Code

    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            var result = ExecuteMarketOrder(TradeType.Buy, Symbol, 10000);

            if (result.IsSuccessful)
            {
                var position = result.Position;
                Print("Position entry price is {0}", position.EntryPrice);
            }
        }
    }

ログ出力

cBot "Sample_cBot" was started successfully for EURUSD, m1.
Executing Market Order to Buy 10k EURUSD
→ Executing Market Order to Buy 10k EURUSD SUCCEEDED, Position PID156168
Position entry price is 1.34577



例2 - 注文が失敗したとき
ボリューム数を無効にして、注文に失敗した場合エラーメッセージが出て、Stop()関数でその後の取引を停止させる。

Code

    [Robot(TimeZone = TimeZones.UTC)]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            var result = ExecuteMarketOrder(TradeType.Buy, Symbol, -1);

            if (!result.IsSuccessful)
                Stop();
        }
    }

ログ出力

cBot "Sample_cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy -1 EURUSD
→ Executing Market Order to Buy -1 EURUSD FAILED with error "BadVolume"
cBot "Sample_cBot" was stopped for EURUSD, h1.



例3 - 成行き注文のパラメーターを追加
成行き注文のパラメーター変数に、cBotラベル、StopLoss、TakeProfitを追加して、エントリー価格、ストップロスを出力する。

Code

    [Robot(TimeZone = TimeZones.UTC)]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            var result = ExecuteMarketOrder((TradeType.Buy, Symbol, 10000, "order 1", 10, 10);

            if (result.IsSuccessful)
            {
                var position = result.Position;
                Print("Position entry price is {0}", position.EntryPrice);
                Print("Position SL price is {0}", position.StopLoss);
            }
        }
    }

ログ出力

cBot "Sample_cBot" was started successfully for EURUSD, m1.
Executing Market Order to Buy 10k EURUSD (SL: 10, TP: 10)
→ Executing Market Order to Buy 10k EURUSD (SL: 10, TP: 10) SUCCEEDED, Position ID156169
Position entry price is 1.34693
Position SL price is 1.34593


ポジションの変更:ModifyPosition()

例1 - StopLossとTakeProfitの変更
TakeProfitだけ指定した成行き注文に、ModifyPosition()関数を使ってStopLossとTakeProfitの追加変更を行う。StopLossを指定してない場合は"null"を入れた後にTakeProfit(Pips値)を入れる。
ここで注意が必要なのは、ExecuteMarketOrder()関数のSLとTPは"Pips値"、ModifyPosition()関数のSLとTPは"Price値"です、間違えないように。

Code

    [Robot()]
    public class SamplecBbot : Robot
    {
        protected override void OnStart()
        {
            var result = ExecuteMarketOrder(TradeType.Buy, Symbol, 10000, "order 1", null, 10);
            if (result.IsSuccessful)
            {
                var position = result.Position;
                Print("Position SL price is {0}", position.StopLoss);

                var stopLoss = position.EntryPrice - 10*Symbol.PipSize;
                ModifyPosition(position, stopLoss, position.TakeProfit);

                Print("New Position SL price is {0}", position.StopLoss);
            }
        }
    }

ログ出力

cBot "Sample_cBot" was started successfully for EURUSD, m1.
Executing Market Order to Buy 10000 EURUSD (TP: 10)
→ Executing Market Order to Buy 10000 EURUSD (TP: 10) SUCCEEDED, Position PID5229848
Position SL price is null
Modifying position PID5229848 (SL: 1.07716, TP: 1.07916)
→ Modifying position PID5229848 (SL: 1.07716, TP: 1.07916) SUCCEEDED, Position PID5229848
New Position SL price is 1.07716


決済注文:ClosePosition()

例1 - 決済注文
成行き注文後にグロス利益(手数料スワップを含めない)が指定の金額になったらポジションを決済する。

Code

    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, Symbol, 10000, "myLabel");
        }

        protected override void OnTick()
        {
            var position = Positions.Find("myLabel");
            if (position != null && position.GrossProfit > 10)
            {
                ClosePosition(position);
                Stop();
            }   
        }
    }

ログ出力

cBot "Sample_cBot" was started successfully for EURUSD, m1.
Executing Market Order to Buy 10k EURUSD
→ Executing Market Order to Buy 10k EURUSD SUCCEEDED, Position PID156171
Closing position PID156171
→ Closing position PID156171 SUCCEEDED, Position PID156171
cBot "Sample_cBot" was stopped for EURUSD, m1.



例2 - 部分決済
複数の成行き注文が成立したら、次の最新バーでそれぞれのポジションから特定ラベルの指定ボリューム数だけ部分決済する。

Code

    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, Symbol, 20000, "myLabel");
            ExecuteMarketOrder(TradeType.Buy, Symbol, 30000, "myLabel");
        }

        protected override void OnBar()
        {
            var positions = Positions.FindAll("myLabel", Symbol, TradeType.Buy);

            foreach (var position in positions)
            {
                if (position.Volume >= 20000)
                {
                    ClosePosition(position, 15000);
                }
            }
        }
    }

ログ出力

cBot "Sample_cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy 20k EURUSD
→ Executing Market Order to Buy 20k EURUSD SUCCEEDED, Position PID664437
Executing Market Order to Buy 30k EURUSD
→ Executing Market Order to Buy 30k EURUSD SUCCEEDED, Position PID664438
Closing position PID664437 (15k)
→ Closing position PID664437 (15k) SUCCEEDED, Position PID664437
Closing position PID664438 (15k)
→ Closing position PID664438 (15k) SUCCEEDED, Position PID664438


指値注文と逆指値注文:PlaceLimitOrder()/PlaceStopOrder()

例1 - 指値注文と逆指値注文
指値と逆指値の待機注文が設定されたとき、cBotラベルとオーダーIDを表示する。

Code

[Robot()]
public class Sample_cBot : Robot
{
    protected override void OnStart()
    {
        PlaceLimitOrder(TradeType.Buy, Symbol, 10000, Symbol.Bid, "myLimitOrder");
        PlaceLimitOrder(TradeType.Buy, Symbol, 20000, Symbol.Bid-2*Symbol.PipSize, "myLimitOrder");            
        PlaceStopOrder(TradeType.Buy, Symbol, 10000, Symbol.Ask, "myStopOrder");

        foreach (var pendingOrder in PendingOrders)
        {
             Print("Order placed with label {0}, id {1}", pendingOrder.Label, pendingOrder.Id);
        }                                
    }
}

ログ出力

cBot "Sample_cBot" was started successfully for EURUSD, m1.
Placing Limit Order to Buy 10k EURUSD (Price: 1.34211)
→ Placing Limit Order to Buy 10k EURUSD (Price: 1.34211) SUCCEEDED, PendingOrder OID246324
Placing Limit Order to Buy 20k EURUSD (Price: 1.34191)
→ Placing Limit Order to Buy 20k EURUSD (Price: 1.34191) SUCCEEDED, PendingOrder OID246325
Placing Stop Order to Buy 10k EURUSD (Price: 1.34243)
→ Placing Stop Order to Buy 10k EURUSD (Price: 1.34243) SUCCEEDED, PendingOrder OID246326
Order placed with label myLimitOrder, id 246324
Order placed with label myLimitOrder, id 246325



例2 - 待機注文にパラメーター変数を追加する
待機注文にラベル名、SL、TP、期限、コメントを入れて、SL、TPの指定があれば表示する。

Code

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            DateTime midnight = Server.Time.AddDays(1).Date;

            PlaceLimitOrder(TradeType.Buy, Symbol, 10000, Symbol.Bid, "mySample_cBot", 10, null, midnight, "First");

            PlaceStopOrder(TradeType.Buy, Symbol, 10000, Symbol.Ask, "mySample_cBot", 10, 10, null, "Second");

            foreach (var order in PendingOrders)
            {
                var sl = order.StopLoss == null ? "" : "SL: " + order.StopLoss;
                var tp = order.TakeProfit == null ? "" : " TP: " + order.TakeProfit;

                var text = string.Format("{0} {1}", sl, tp);

                if (order.OrderType == PendingOrderType.Limit)
                    Print(order.Comment + " Limit Order " + text);
                else
                    Print(order.Comment + " Stop Order " + text);
            }
        }
    }

ログ出力

cBot "Sample_cBot" was started successfully for EURUSD, m1.
Placing Limit Order to Buy 10k EURUSD (Price: 1.34326, SL: 10, ExpireTime: 22/11/2013 00:00)
→ Placing Limit Order to Buy 10k EURUSD (Price: 1.34326, SL: 10, ExpireTime: 22/11/2013 00:00), SUCCEEDED, PendingOrder OID246369
Placing Stop Order to Buy 10k EURUSD (Price: 1.34359, SL: 10, TP: 10)
→ Placing Stop Order to Buy 10k EURUSD (Price: 1.34359, SL: 10, TP: 10) SUCCEEDED, PendingOrder OID246370
First Limit Order SL: 1.34226
Second Stop Order SL: 1.34259 TP: 1.34459


待機注文の変更:ModifyPendingOrder()

例1 - 待機注文のターゲット価格を変更する
待機注文のターゲット価格を変更、SL、TP、期限はそのままにする。

Code

    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            var price = Symbol.Ask + 10 * Symbol.PipSize;
            DateTime? expiry = Server.Time.AddHours(12);
            PlaceStopOrder(TradeType.Buy, Symbol, 10000, price, "myLabel", 10, 10, expiry);
        }

        protected override void OnBar()
        {
            foreach (var order in PendingOrders)
            {
                if (order.Label == "myLabel")
                {
                    double newPrice = Symbol.Ask + 5 * Symbol.PipSize;
                    ModifyPendingOrder(order, newPrice, order.StopLossPips, order.TakeProfitPips, order.ExpirationTime);
                }
            }
        }
    }

ログ出力

cBot "Sample_cBot" was started successfully for EURUSD, h1.
Placing Stop Order to Buy 10k EURUSD (Price: 1.36161, SL: 10, TP: 10, ExpireTime: 27/11/2013 21:59)
→ Placing Stop Order to Buy 10k EURUSD (Price: 1.36161, SL: 10, TP: 10, ExpireTime: 27/11/2013 21:59) SUCCEEDED, PendingOrder OID1081885
Modifying pending order OID1081885 (Price: 1.36109, SL: 10, TP: 10, ExpireTime: 27/11/2013 21:59)
→ Modifying pending order OID1081885 (Price: 1.36109, SL: 10, TP: 10, ExpireTime: 27/11/2013 21:59) SUCCEEDED, PendingOrder OID1081885


待機注文の消去:CancelPendingOrder()

例1 - 指定ラベル名の待機注文を消去
指定のラベル名を持つ待機注文をすべて消す。

Code

    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnTick()
        {
            foreach (var order in PendingOrders)
            {
                if (order.Label == "myLabel")
                {
                    CancelPendingOrder(order);
                }
            }
        }
    }


ポジションのイベント:PositionOnOpened()/PositionOnClosed()

例1 - ポジションをオープンしたときのイベント予約
ポジションをオープンしたときPositionsにイベント予約して、エントリー価格を表示する。

Code

    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            Positions.Opened += PositionsOnOpened;
            ExecuteMarketOrder(TradeType.Buy, Symbol, 10000, "myLabel", 10, 10);
        }

        private void PositionsOnOpened(PositionOpenedEventArgs args)
        {
            var pos = args.Position;
            Print("Position opened at {0}", pos.EntryPrice);
        }
    }

ログ出力

cBot "Sample_cBot" was started successfully for EURUSD, m1.
Executing Market Order to Buy 10k EURUSD (SL: 10, TP: 10)
→ Executing Market Order to Buy 10k EURUSD (SL: 10, TP: 10) SUCCEEDED, Position PID157201
Position opened at 1.34342



例2 - ポジションをクローズしたときのイベント予約
ポジションがクローズしたときにPositionsにイベント予約して、手数料スワップを含まないGrossProfitを表示する。

Code

    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            Positions.Closed += PositionsOnClosed;
            ExecuteMarketOrder(TradeType.Buy, Symbol, 10000, "myLabel", 10, 10);
        }

        protected override void OnBar()
        {
            var position = Positions.Find("myLabel");
            if (position != null)
                ClosePosition(position);
        }

        private void PositionsOnClosed(PositionClosedEventArgs args)
        {
            var pos = args.Position;
            Print("Position closed with {0} profit", pos.GrossProfit);
        }
    }

ログ出力

cBot "Sample_cBot" was started successfully for EURGBP, m1.
Executing Market Order to Buy 10k EURGBP (SL: 10, TP: 10)
→ Executing Market Order to Buy 10k EURGBP (SL: 10, TP: 10) SUCCEEDED, Position PID50038
Closing position PID50038
→ Closing position PID50038 SUCCEEDED, Position PID50038
Position closed with -0.24 profit


非同期型の取引注文(Asynchronous execution)

 上記で説明してきた取引注文は、すべて同期型の取引注文です。同期型の取引注文は、要求をサーバーに送信し、サーバーの応答を待ってから、後続のステートメントに実行を渡します。

 一方、非同期型の取引注文は、要求がサーバーに送信されると、プログラムはサーバーからの応答を待たずに次のステートメントを実行します。非同期トレード操作に続くステートメントは、これらの要求の結果について何も想定できません。

 たとえば、非同期型の成行き注文をした場合、注文実行の返り値を待たずに実行してしまうため多重注文になる危険性が生じます。

 非同期型の注文を使用する利点は、複数のポジションを一括決済したい場合に、サーバーからの応答を待たずに一括決済してくれますので、決済時間の遅延が無く大きな利点となります。

 非同期型の取引注文については、cTrader公式ページのTrading APIを参照してください。

MetaTrader/cTrader 為替取引の仕組み

ブログ更新をご無沙汰していましたので、FX取引プラットフォーム『cTrader』に焦点をあてて記事を少しづつ書いてみたいと思います。

 

『cTrader』は、イギリスに拠点を持つSpotware社が開発したプラットフォームです。C#ベースで自動売買取引も可能な大変優秀なツールです。国内のFXブローカーではまだ採用されていませんが、日本在住の人が取引できる海外FXブローカー AxioryTradeViewFxProで利用することができます。国内で普及しているMT4/5とほぼ同じ機能を有しています。

 

今回は、MT4/5とcTraderの「為替取引の仕組み」についてまとめてみます。外国為替証拠金取引(FX)といっても、一般の人は、「店頭取引」とか「相対取引」程度しか知らされてなく、インターバンク市場とどのように係わっているのか詳しく書かれた書物は見当たらないと思います。そこに外国為替証拠金取引の落とし穴があるのです。これからFXを始めようと思う人は為替取引の仕組みについても理解しておく必要があります。

 

MT4/5 為替取引の仕組み

MT4/5トレーダーは、まずFXブローカーを経由して取引するることになります。FXブローカーによって為替ディーラーのいるDDブローカーだったり、手数料だけ差引いて次のPrime of Prime (PoP) Aggregatorに注文を引き渡すNDDブローカーだったりします。

 

Prime of Prime (PoP) Aggregatorについて語られることはあまりありませんが、Tier1 プライムブローカー(大手グローバル証券)の資格を有し、為替ブローカーに信用枠を与えて多くの為替ブローカーにサービスを提供している業者です。PoP業者は、為替ブローカーの胴元と考えれば分かり安いと思います。

 

MT4/5の場合、Bridge(Plug-In)を経由してPoP業者に取引情報が全て集約されることになります。そこから、LPやECNに注文を流すこともありますが、PoP業者がマーケットメイカーである場合、注文を吞んだり別の為替業者に注文を流したりすることも可能になります。

f:id:EAMaster:20210616045714j:plain

MT4/5 為替取引の仕組み

 

cTrader 為替取引の仕組み

 仲介業者による複雑なFXの為替取引を避けて、インターバンク市場と直接取引できるDMA方式を提唱してFXプラットフォームを立ち上げたのがイギリスに拠点を持つSpotware社の「cTrader」です。為替ブローカーの胴元であったPoP業者をインターバンク市場まで押し戻して、Spotware社管轄のcServerにすべての取引情報を集約して、LPやECNと直接取引できるようになりました。

 

cTraderもまだ発展途上で、MT4/5プラットフォームと比較して一長一短もあり利用者の好みにもよりますが、外国為替取引の仕組みから考えるとcTraderの方が彼らが提唱する"Traders First"のビジネスモデルに叶っているといえます。

 

【cTraderの特徴】

(1) DMAレベル2板情報:市場と直接取引

(2) cServerがベストマッチ注文:為替ブローカーの胴元がいない!

(3) cBrokerはNDD:為替ブローカーの介入は限定的

(4) FIXベースのインターバンクHFT取引:ヘッジファンドと対等

(5) マーケットメイカーに取引情報が漏れない

 

f:id:EAMaster:20210616045941j:plain

cTrader 為替取引の仕組み

 

EAM2020 配布終了のお知らせ

EA Portfolio-Manager『EAM2020』の配布を終了致します

昨年の暮れあたりから、「EAM2020」の配布を実施して来ましたが、昨今のFX相場の変動は、従来のテクニカル手法を駆使した自動売買取引でも一筋縄で対応が困難となっており、その度に最適化して再配布すればその場は切り抜けられるかもしれませんが、放置して収益があげられる自動売買取引の目的とは異なり、また私自身が多忙であるため十分な対応が難しくなりましたので、「EAM2020」の配布は停止いたします。

 

今後は、新しいロジックの開発や、MT4とは異なる C#ベースのcTraderプラットフォームcAlgoを使ってcBotの開発に取り組みたいと思います。何か新しい情報があれば、このサイトにもアップしていきたいと思いますので今後とも宜しくお願い致します。

 

f:id:EAMaster:20201201233227p:plain

「EAM2020」年間取引推移

 

EAM2020を契約期限まで使いたい人のために

「EAM2020」の設定パラメーターは、ほとんどのテクニカルトレードを網羅して、市販にはない細かいパラメーター設定が可能ですので、最適化すればまだ使える可能性もあります。契約期限まで利用したい人は下記のテクニカルトレードの設定を変えて最適化してみるのも面白いかもしれません。あくまでお試しです。

 

f:id:EAMaster:20201201233506p:plain

「EAM2020」設定パラメーター

 

『七夕バージョン』EAM2020 Profiles アップデート(11)

EAM2020プロファイル (Ver.200707) リリース『七夕バージョン』

■ 今回のアプデ内容

  • EAM設定更新:
  • 「EAM-107」EURUSD (HighLow Pending BO, NY Time)
  • 「EAM-307」GBPUSD(HighLow Pending BO, LDN Time)

「EAM2020」ご利用の方は、「チャート組表示」のプロファイルを今回のプロファイルに指定して再起動するだけ。これまでのアップデートも更新されています。今回も手動で決済する必要はありません。そのまま継続利用できます。

 

f:id:EAMaster:20200704165146p:plain

Portfolio EA Manager 「EAM 2020」

新プロファイル配置

厳選した各種ロジックのEAM12個分をポートフォリオ運用、デフォルト設定でリアルタイムのポジション情報もGUI表示によって大変見やすくなっています。

 

EAM2020 Profiles (Ver.200707)

f:id:EAMaster:20200618155305p:plain

EAM2020 Profiles 12Charts (Ver.200707)

 

新EAM バックテスト結果

EAM-107:EURUSD (HighLow Pending BO,  NY Time)

・HighLow ペンディング・ブレークアウトでNY時間にエントリーします(日計り
・取引時間:15時Start/16時30分Stop/翌日15時Close(サーバー時間)

f:id:EAMaster:20200707154006p:plain

EAM-107-EU  (HighLow Pending BO)

EAM-307:GBPUSD (HighLow Pending BO,  LDN Time)

・HighLow ペンディング・ブレークアウトでLDN時間だけエントリーします(日計り
・取引時間:11時Start/16時Stop/18時Close(サーバー時間)

f:id:EAMaster:20200707154730p:plain

EAM-307-GU  (HighLow Pending BO)

 

新EAM2020 Profiles ダウンロード

このEAMプロファイルをご利用するには、EAM2020専用口座を開設する必要があります。

www.dropbox.com

 ※7/8 修正版と差し替えています。それ以前にDLした人は再度DLして下さい。

 

【EAM_Profiles設定方法】:

  • MT4「ファイル(F)」→「データフォルダを開く(D)」→「Profiles」フォルダを開く →「EAM_Profiles_xxxxxx」をコピー → MT4再起動
  • MT4「ファイル(F)」→「チャートの組表示」→「EAM_Profiles_xxxxx」クリック

    << 別名で保存する場合 >>
  • MT4「ファイル(F)」→「チャートの組表示」→「名前をつけて保存(A)」クリック → 任意の名前で保存
  • MT4「ファイル(F)」→「データフォルダを開く(D)」→「Profiles」フォルダを開く → 保存した「任意の名前」フォルダを右クリック →「プロパティ」を開く →「読取り専用」にチェックを入れる →「OK」→「OK」→ MT4再起動

※提供のProfilesは「読取り専用」になっています
※停止したEAMのポジションがある場合は、手動で決済する必要があります。