初のcBot作成と個人的に躓いた点
前回記事の続きです。
cTraderで自動売買を行うために、cAlgoを使って自動売買用のcBot作成にチャレンジ。ということで、まずは自作EAの一つであるSunflowerをcBotに移植してみました。
なおcBot作成に当たってはemijaさんの記事が非常に参考になりました。
C#を触ったことがなく、ネームスペース?クラス?メソッド?何それおいしいの?レベルの素人プログラマーである私にとって、数少ない日本語のcBot解説はとても助かりました。
そもそもcBotに関する日本語の情報はほとんどなく、参考書なんて当然ありませんし、APIリファレンスもわかりにくいというか不親切というか検索しにくいというか。
SpotwareさんはホントにcTrader普及させるつもりあるんですかね?
一度覚えてしまえばMQL4のプログラミングとそんなに変わらないですし、むしろMQL4よりプログラムは洗練されている感じもするのですが、いかんせん取っつきにくいというのが普及の足枷になっているような気もします。
また、cAlgoはデバッグ機能がないというのがプログラマー泣かせな、残念な仕様。
正確に言えばVisual Studioを使ってデバッグできるようですが、そこで記述に間違いがあるということがわかるだけで、ではどのように修正したらいいかということがわかりません。
私の使い方が悪かっただけかもしれませんが…
結局、cAlgo上でBuildしてみて間違いがあればそこでコンパイルが止まる(カーソルの位置でわかる)ので、変数の型なのか関数の書き方なのか間違いの原因をリファレンスと見比べながら地道に潰していきました。
そこらへん、コンパイル時にエラーの内容がちゃんと記載してくれるMetaEditorは素人にも優しいですね(というかそれが普通な気もしますが)。
ちなみに、私がcBotを書いていて地味~に躓いたところを何点か。
取引時間の指定
MT4であればMT4ターミナルの時刻を元に取引時間を計算する場合が多いかと思いますが、ではcTraderの基準となる時間は何時なのか…?
初歩的な質問ですが、説明がないのでわからず。
ただ、MT4とは異なりターミナルでは表示時刻を自分の好きなように変えられるのですが、そこを見るにUTC+0 (Server Time)となっているので基本的にはUTC+0を基準に考えるのがプログラム的には確実なのかもしれません。
cBotにおいては「このプログラムはどこに合わせて現在時刻を認識するのか」というのをはじめに指定する必要がありますが、私の場合はサンプル通りに
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
としてこのcBotの時刻計算はUTC+0で行ってねということを初めに記述して、別途指定するGMTオフセットを加味して取引時間の制限を加えるようにしました。
わかってしまえばどうということはないですが、初めてとなるとこういう基本的なところから悩んでしまうものです。
ロット数の記述
MetaTraderでは1ロット=100,000通貨という形でロット数を指定しますが、cBotのプログラム内では、”100,000通貨”の方の通貨数の形でポジションサイズを指定します。
ただ、サンプルプログラムを見るとMetaTraderに合わせているのか、パラメータ入力の部分ではロット数で入力、それを関数を使って通貨数に変換するという方法になっています。
説明がわかりにくいかもしれませんが、私が書いたサンプルだと以下のような感じです。
// ロット数計算 long LotsOptimized = 1000; // 単利 if (MoneyManagement == false) LotsOptimized = Symbol.QuantityToVolume(Lots); else // 複利 LotsOptimized = Symbol.QuantityToVolume(Leverage * Account.Balance / 100000); LotsOptimized = Symbol.NormalizeVolume(LotsOptimized, RoundingMode.ToNearest);
単利の部分を見ていただくとわかるかと思いますが、LotsはMetaTraderと同じようにロット数で指定して、それをQuantityToVolumeという関数で通貨数に変換しているのですね。
サンプルでそうなっているのでそれに準拠しましたが、そもそもということを考えれば最初から通貨数を入力パラメータとする方がわかりやすいような気もします。
下の複利の方では、指定したレバレッジと口座残高からロットを自動算出するようにしています。
ここで気を付けないといけないのが最後の行の部分になりますが、通常の業者では取引通貨単位が最低1000通貨なので、例えば1200通貨という数を指定することはできませんし、プログラムでそう書くとエラーで上手く取引しません(それでもBuildが通ってしまうのが厄介なのですが)。
したがって、最後の行ではポジションサイズをNormalizeVolumeという関数を使って1000通貨単位となるように四捨五入しています。
バックテストしてみて、複利にすると1ポジション取ったところで止まってしまってこのエラーを特定するのに苦労しました…
注文価格の指定
Sunflowerにはブレイクイーブン、トレーリングストップ機能をつけておりますが、最初に行ったバックテストだとどうも働いておらず。
コンパイルはできているのになんでかなーと思っていたのですが、そういえばMQL4でも同じようなことがありました。
そう、ロット数の話と同じですが、Modifyする価格を計算・指定する時にはレートと桁数を合わせるために四捨五入をする必要があるのですね!
double TrailStop = 1.0; // トレール値 = ~~~ (プログラム省略) TrailStop = Math.Round(double トレール値, Symbol.Digits); ModifyPosition(position, TrailStop, position.TakeProfit);
MQL4のNormalizeDoubleとは異なり、どう書いたらいいのかを見つけるのになかなか苦労しましたが、ともあれこれでトレーリングストップも上手く機能するようになりました。
他にも何かあったような気がしますが今さら記事を書いているので忘れてしまいました笑
こうやって書いているとcAlgoダメじゃんというようにも見えますけど、時間足確定時にだけ動作させたいときはOnTick()ではなくOnBar()を使えばいいとか、Market Execution方式でもスリッページ制御できるとか、MQL4より便利な点もあるんですよね。
結局、何事も慣れということなのかもしれません。
さて、それではバックテスト結果はどうなのか!というところですが、プログラムを交えながら記事を書いていたらそこそこ長くなってしまったので、そちらはまた次の記事でご紹介します。
別記事にして記事数稼ごうとしてるだろとか、そんなつもりは毛頭ありますけれど(笑)、興味のある方は少々お待ちください~
コメント
この記事へのトラックバックはありません。
この記事へのコメントはありません。