cAlgo Tips & Sample

【cAlgo】cBotからの注文処理

cBotからの注文

前回が決済の話だったので、今回はエントリー注文の話でも。

 

cAlgoでのエントリー注文メソッドおさらい

cTrader(cAlgo)におけるエントリー注文の種類はExecuteMarketOrder、ExecuteMarketRangeOrder、PlaceStopOrder、PlaceStopOrder、PlaceStopLimitOrderの5種類です。

厳密にはそれぞれの非同期版で末尾にAsyncがついたものもありますが、注文内容自体は全く同じです。当記事での詳しい説明は割愛しますが、同時に複数注文するときだけはAsyncを使ってま

すでにリファレンスで説明してる通り。基本のxecuteMarketOrderはこちら。非同期版Asyncの説明もここにあります。

cAlgoの発注メソッド(2) ~ExecuteMarketOrder~

基本の発注メソッド-ExecuteMarketOrder 前回の記事では発注メソッドがいっぱいあるとかあおっておいてなんですが、cAlgoでの発注はぶっちゃけこれ一つでだいたいどうにかなります。 Ex ...

続きを見る

その他4種類はこっち。

cAlgoの発注メソッド(3) ~その他の注文~

まずはExecuteMarketOrder ExecuteMarketOrderメソッドの使い方はわかってる前提で話は進みますので、よくわからんという方は先にこちらへ。→cAlgoの発注メソッド(2) ...

続きを見る

ストップリミットオーダーって何???って方はここ参照。

cAlgoの発注メソッド(番外編) ~StopLimitOrder(ストップリミット注文)って何?~

待機注文3つの違い 待機注文にはLimitOrder,StopOrder,StopLimitOrderの3種類があるという話でした。指値注文のLimitOrder、逆指値注文のStopOrderはとも ...

続きを見る

一通りあげてみたものの、実はajinoriはExecuteMarketOrderしか使ってません。

ここではどんな風に使ってるかと、なんで他の注文を使ってないのかを説明したいと思います。

 

普段の注文

注文条件を満たしたらExecuteMarketOrder、いわゆる成り行き注文のメソッドを呼ぶだけ。なんですが、シンプルなcBotであればまず最初に本体クラス内にこんな感じのメソッドを作っておくことが多いです。

private bool EntryOrder(TradeType tradeType, string comment="") {
    // --- ラベルはcBotのクラス名をそのまま使う。
    var label = ToString();

    // --- エントリーボリュームとSLとTPは別メソッドで計算。固定値ならパラメータの値そのまま入れる
    var volume = CalcVolume();
    var stopLossPips = CalcSlPips(tradeType);
    var takeProfitPips = CalcTpPips(tradeType);

    // --- volumeを発注可能な数値にして、SLTPの小数点桁数も揃える
    volume = Symbol.NormalizeVolumeInUnits(volume);
    var decimals = (int)(Symbol.Digits + Math.Log10(Symbol.PipSize));
    stopLossPips = Math.Round(stopLossPips, decimals);
    takeProfitPips = Math.Round(takeProfitPips, decimals);

    // --- 発注処理
    var res = ExecuteMarketOrder(tradeType, SymbolName, volume, label, stopLossPips, takeProfitPips, comment);

    // --- エラーが出たらログに出力
    if (!res.IsSuccessful) {
        Print(res.Error.ToString());
    }

    // --- 成功したかどうかだけ返す
    return res.IsSuccessful;
}
private double CalcSlPips(TradeType tradeType) {
    // --- ここにストップロス計算処理
}
private double CalcTpPips(TradeType tradeType) {
    // --- ここにテイクプロフィット計算処理
}
private double CalcVolume() {
    // --- ここにボリューム計算処理
}

cBotの内容によって部分部分変更してその都度作ってるのですが、基本はこんな感じです。

ほとんどのcBotでSymbolNameやLabel部分は固定ですし、VolumeやStopLoss、TakeProfitの算出方法もだいたい決まってると思います。

上記では別メソッドにしてますが、簡単な処理ならEntryOrder内に書いてしまいますし、実際、Volumeなんかは固定でパラメータ値をそのまま渡しちゃうことの方が多いです。

コメントは使わないことも多いですが、一応引数で渡せるようにしておきます。cBotによってその都度変わる項目があれば引数に加えておいてもいいと思います。

返り値は成功したかどうか返して、成功した時と失敗した時で呼び出し元で処理の振り分けが可能なようにしておきてます、が、あまり使ったことありません。

cBot作るときって、作りながらロジック書き換えたりとか、注文の仕方変えたりとかいろいろやるんですよね。それでそのたびにいちいちExecuteMarketOrderを呼び出すのが意外に面倒でして。それで最初にメソッド化しておいてます。

あとはロジック部分で、発注したいとこでEntryOrderを呼び出すだけ。

 

注文失敗時の再注文はしません

上記コードを見ると決済注文時と異なり、注文失敗時のリトライがないことに気づくと思います。

この辺はひとそれぞれかもしれませんが、ajinoriは基本的に注文に失敗したらご縁がなかったと思ってあきらめることにしています。理由としては以下の2つ。

 

異常事態時はエントリーしたくない

そもそも注文失敗は稀です。そこにはなにかしらの異常事態が発生してる可能性も低くはないと考えるべきでしょう。

そんなときになにも無理に新規エントリーすることはないのです。チャンスを逃さないことよりリスクを避けることを優先します。

 

重複エントリーの恐れがある

こっちが本命ですが、どうやらエラーが返ってきてるくせに「実は注文入ってましたー」ということがあるようなのです。

おそらく、注文サーバーが重たくてタイムアウトで一旦TechnicalErrorが返る → そのあとに遅れて約定、となるのでしょうが、cBot側ではエラーを頼りに注文失敗を判断するため、注文失敗してるくせにポジションは持ってるというあり得ないことが起きてしまうのです。

ここでもし無限ループとかで再注文送ってたらと思うと・・・想像するだけで恐ろしいですよね。

 

 

なんで他の注文は使わないのか

あくまで個人的な考えですので参考程度に。

 

PlaceLimitOrder

理由:暴落急騰時の事故を防ぎたいから

指値注文のことですが、cBotでは指値注文は使いません。

指値注文は指定価格に到達した瞬間に約定します。例えば買いの指値注文では一方的に下落する相場でも、当然指定した価格を通過した時点で買いポジションを持ってしまうのです。

・・・でそのまま落ちてストップロスにかかると。これがどうしてもいやなんです。

あくまで落ちてきたときに買いたいのは、そこまで落ちた後に上がることを見込んでるからです。であれば、「指定価格に到達した直後」ではなくて「指定価格を下から上に抜けた直後」に買った方がいいと思いませんか?

もちろんこの場合は指定価格より少し不利な価格で約定することにはなりますが、これだけで暴落相場の事故を防げると思ったら安いもんです。

裁量トレードの場合は、常にチャートに張り付いてるわけにもいかないので指値注文を使うこともあるかもしれませんが、cBotであればプログラムに見張っておいてもらえばいいだけです。

「価格が落ちてきたら買いたい」という場合はPlaceLimitOrderは使わずに、OnTickで見張って指定価格を「下から上に」抜けた時にExecuteMarketOrderを呼び出すようにしています。

 

PlaceStopOrder

理由:あえて使わなくてもいいから

逆指値注文ですが、これは前もってターゲット価格が決まってるならむしろ使った方がいいとは思ってます。

ただ、自分が作るcBotの場合、前もって価格をはっきり決めることがそんなにないため、基本的にOnTickでその都度条件判定してExecuteMarketOrderを呼び出せばいいかな、と考えて使ってません。

そもそも逆指値注文は「価格到達時に注文を出す」だけのものなので、cTrader (cBot) 側でやるかサーバー側でやるかの違いしかありません。もちろんPlaceStopOrderの方がサーバーに注文を任せられるのでスピードがわずかに速いというメリットはありますけどね。

あと、サーバーに注文送っておけば、cBotがトラブルで止まってたとしても約定するというメリットが・・・いや、cBot止まってたら決済ロジック動かないから、これはデメリットかな。

必要が出てきたら使うかもしれませんが、今のところは別にいいか、という感じです。

 

ExecuteMarketRangeOrder

理由:面倒だから

これはわかりやすく言うとスリッページが指定できるExecuteMarketOrderです。どうしても指定価格で約定させたいという方はExecuteMarketOrderよりもこっちの方がいいのかもしれません。

でも私は使いません。なにが面倒なのかというと、ExecuteMarketRangeOrderは約定価格と許容スリッページを指定して注文を送る必要があるところです。

「そんなもんプロパティのBID (ASK) 渡して、スリッページは0付近で指定しておけばいいじゃん」と思われるかもしれませんが、これだと一瞬タイミングが遅れただけで注文が通らなくなります。

瞬間的なスキャルピングをやるのならともかく、デイ~スイングトレードの場合、ほんの一瞬の値動きで約定しないほうが問題です。

また、ロット数が大きくなると一部注文が通らなくなるという問題もあります。cTraderのトレード画面右パネルのVWAP DoMを見るとわかりますが、注文ボリュームによって約定できる価格は異なるのです。

これらを考慮するとなるといちいち指定するのはなかなか面倒でして、別にそこまでしなくてもいいかな、と思ってます。

(いや、別にそんな大きな発注すること今のところはないんですけどね・・・将来的に大きな発注するようになった時のことも考えておきたいし・・・)

 

PlaceStopLimitOrder

理由:上に同じ

逆指値注文のスリッページ指定版です。まぁPlaceStopOrderもExecuteMarketRangeOrderも使わないので・・・

 

 

やり方はひとそれぞれ

上記はあくまでajinoriのエントリー注文に対する考え方です。全然違う方法をとる方もいるでしょうし、別にどれが正解とかはありません。

自分なりのベストな注文方法で素敵なcBotライフを!

 

-cAlgo Tips & Sample

© 2021 cTrader's Life Powered by AFFINGER5