ゴトー日を運用を始めたくてEAを作ってみました。
わりと簡単に作れました😀
初心者むけです。
Table of Contents
ゴゴジャンで自作EAの販売に挑戦中
この記事のロジックそのまま、オリジナル機能もりもりで魔改造してEA販売しています。
EA作れるようになったら色々出来て楽しいね😁
ゴゴジャンというEAのプラットフォームをつかってます。
みんなもゆくゆくはEAの販売・配布に挑戦してみてくださいね!
MT5で自動売買EA(エキスパートアドバイザー)を自作する
毎度ですが先にゴールを決めてから作りはじめます。
今回のゴールは、「ドル円ゴトー日EAを完成」です。
MT5のEAの作り方は、
日本時間の2時にドル円をロング、9時55分に決済。
日本時間の9時55分にドル円をショート、15時に決済。
・エントリー
・決済
の2個のルールが必要です。
ネットでググるとほとんど情報がでてくるので、きっと作れます。
自動化させるロジックを確認
先にTradingViewでロジックを確認します。
ロングエントリールールは2時00分~9時54分に滞在、決済ルールは9時55分に到達。
ショートエントリールールは9時55分~14時59分に滞在、決済ルールは15時00分に到達。
Gotobi Teriyaki by hosono_p on TradingView.com
コードは以下のリンクから確認できます。
ブログの存続のため、TradingViewの有料アカウントを申し込むときは以下の紹介リンクから申し込みをお願いします。
MT5のインストール
ゆくゆくは仮想通貨の自動売買もしたいのでMT5はFXGTの口座を利用します。
FXGTのMT5デモ口座の申請方法
お疲れ様でした。これでMT5の準備完了です。次はプログラミング用のエディタを表示させます。
MT5のプログラミングエディタ(メタエディタ)を起動
MQL5のプログラムのコードはここに書いていきます。
エキスパートアドバイザーの新規作成
新規でEAを作ります。
テンプレコードの説明
いちおうテンプレの説明しておきます。飛ばしてもOKです。※MAゴールデンクロスの転用です。
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 |
//+------------------------------------------------------------------+ //| gotobi.mq5 | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ |
上から8行目まではEAの説明文など
1 2 3 4 5 6 7 8 |
//+------------------------------------------------------------------+ //| gotobi.mq5 | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" |
最後の property strict で日本語化されます。
他はEAの説明文に転載されます。
// ダブルスラッシュから始まるのはコメントアウトです。
int OnInit()はEA起動時に呼ばれる機能です。
1 2 3 4 5 6 7 8 9 10 |
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- return(INIT_SUCCEEDED); } |
int OnDeinit()はEA削除時に呼ばれる機能です。
1 2 3 4 5 6 7 8 |
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } |
void OnTick()は値動きがあった時に呼ばれる機能です。
1 2 3 4 5 6 7 8 9 |
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ |
テンプレには3つの機能がデフォルト搭載されている
・EAを開いたとき
・EAを終了させたとき
・値動き時
今回は値動き時のときだけプログラムのコードを実行させるので値動きだけでOK
OnTick関数は値動きがあったら呼ばれる機能です。
例えばBTCUSDの最小単位0.01が動けば実行されます。
20000.00→20000.01
ちなみにMT4では最小単位をPointと呼びます。
void 何も返さない
実行したときに呼び出し元に何も返さない。
対義としては何かを返す関数。
voidの他に、何かを返す関数はint,double,boolが使われる。
何も返さない場合は void を関数の先頭につける。
OnTickはMT4が実行させているので返却しなくてもいい。
TimeLocal()でPCの現在の日本時間を取得する
MT5はパソコンの時間とズレて表示されているのでMT5の時刻を参照してゴトー日を計算するとズレます。
市販のEAは、夏時間冬時間を計算してEAに組み込むのですが、今回は簡単に作りたいので、Windowsの現在時刻を取得して時間判別に使います。
使う関数は、
TimeLocal()
です。
TimeLocal()の動作を確認します。
Print()
Print()でエキスパートのログに出力させることができます。
値動き毎にPrint(TimeLocal()); でパソコンの現在の時間がdatetime型の形でプリントアウトされています。
datetime型とは?
datetimeは日付です。またはintの属性をもっています。
なので、int(整数型)にすると1970年1月1日からの経過時間秒で表示させることもできます。
int timeに代入してみると、
TimeLocal()の結果を int time 変数に代入しています。
1970年1月1日からの経過秒
5のつく日、10のつく日を計算する
現在の時間から日付を取得して5のつく日10のつく日を計算します。
「MQL ゴトー日」でネット検索すると参考コードがでてきますので参考にしてTimeLocal()版に書き換えていきます。
1 2 3 |
bool is_gotobi() { return false; } |
まずは関数を作成します。
現在のパソコンの時間を変数に保存します。
datetime pc_time = TimeLocal();
日付を取得するTimeDay()関数を使います。今日の日付を int day に代入します
int day = TimeDay(pc_time);
余りを計算するMathMod()関数を使います。日付÷5の余りの数をdouble amari に代入します
double amari = MathMod(day,5);
amariの数が0の場合は5の倍数の日付、つまりゴトー日です。
1 2 3 |
if(amari==0) { return true; } |
is_gotobi()関数の動作確認します。
1 2 3 |
void OnTick() { Print(is_gotobi()); } |
土日が5のつく日、10のつく日の場合は金曜日に繰り下げられるのでその計算を組み込みます。
曜日を計算するTimeDayOfWeek()で今日の曜日をint youbi に代入します
int youbi = TimeDayOfWeek(pc_time);
金曜日かつamariが3(3のつく日)かamariが4(4のつく日)ならゴトー日です。
1 2 3 4 5 6 |
if(youbi==FRIDAY && amari==3) { return true; } if(youbi==FRIDAY && amari==4) { return true; } |
ゴトー日の判別関数が完成
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 |
bool is_gotobi() { datetime pc_time = TimeLocal(); int day = TimeDay(pc_time); double amari = MathMod(day,5); if(amari==0) { return true; } int youbi = TimeDayOfWeek(pc_time); if(youbi==FRIDAY && amari==3) { return true; } if(youbi==FRIDAY && amari==4) { return true; } return false; } int TimeDay(datetime date) { MqlDateTime tm; TimeToStruct(date,tm); return(tm.day); } int TimeDayOfWeek(datetime date) { MqlDateTime tm; TimeToStruct(date,tm); return(tm.day_of_week); } |
次は現在の時間を計算する
ゴトー日の2時から9時54分まではBUY判定
日付を計算するのと似たような関数なので説明は割愛します。
時間を判定する関数追加
分を判定する関数を追加
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 |
bool is_buy_time() { datetime pc_time = TimeLocal(); int hour = TimeHour(pc_time); int minute = TimeMinute(pc_time); for(int i=2; i < 9; i++) { if(hour == i) { return true; } } if(hour==9 && minute <= 54) { return true; } return false; } int TimeHour(datetime date) { MqlDateTime tm; TimeToStruct(date,tm); return(tm.hour); } int TimeMinute(datetime date) { MqlDateTime tm; TimeToStruct(date,tm); return(tm.min); } |
ゴトー日の9時55分から14時59分まではSELL判定
日付を計算するのと似たような関数なので説明は割愛します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
bool is_sell_time() { datetime pc_time = TimeLocal(); int hour = TimeHour(pc_time); int minute = TimeMinute(pc_time); if(hour == 9 && 55 <= minute) { return true; } for(int i=10; i < 15; i++) { if(hour == i) { return true; } } return false; } |
月曜日から金曜日までを判定
TradingViewで先に作ったら間違って土曜日の2時からロングされちゃったので、MT4でもしっかりと平日判定をいれます。
平日ならtrue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
bool is_weekday() { datetime pc_time = TimeLocal(); int youbi = TimeDayOfWeek(pc_time); if(youbi==MONDAY) { return true; } if(youbi==TUESDAY) { return true; } if(youbi==WEDNESDAY) { return true; } if(youbi==THURSDAY) { return true; } if(youbi==FRIDAY) { return true; } return false; } |
BUY条件トリガーでロングエントリーさせる
BUY条件は、
1.ゴトー日
2.2時から9時54分に滞在
3.平日
なので、プログラミングコードで翻訳すると、
if(is_gotobi() && is_buy_time() && is_weekday()){}
になります。
ポジション数が0の場合という条件をつける
ロングポジションを持っている条件を加えないと無限ループで買い続けてしまうのでポジション数が0の場合だけエントリーします。
「ポジション数 mql」でネット検索すると参考コードが見つかります。
ロングポジション数の取得関数を作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
int buy_posi_count() { int count =0; for(int i=PositionsTotal()-1; i>=0; i--) { if("" != PositionGetSymbol(i)) { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { if(Symbol()==PositionGetString(POSITION_SYMBOL)) { count++; } } } } return count ; } |
条件式は
buy_posi_count() == 0
です。
MagicNumber(マジックナンバー)をつけてEAでのポジションを識別させる
EAのポジションとほかでエントリーしたポジションを判別できるようにマジックナンバーをつけます。
定数(変数)でmagic_numberを宣言しておきます。
関数の外側を外部スコープと呼びます。
関数に属していないのをグローバルスコープと呼びます。
int magic_number = 510;
は関数に属していない、グローバルスコープの変数です。
グローバルスコープにおいてあると処理で変更をしない限りデータは変更されません。
保存しておきたい数字はグローバルスコープへ置くと保存されます。
また、関数に属している変数のことをローカルスコープの変数と呼びます。
ローカルスコープの変数はOnTickが実行されるとデータはリセットされます。
ポジション数の取得関数をMagicNumberを追加して修正
ポジション取得に識別するマジックナンバーを加えます。
変更前
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
int buy_posi_count() { int count =0; for(int i=PositionsTotal()-1; i>=0; i--) { if("" != PositionGetSymbol(i)) { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { if(Symbol()==PositionGetString(POSITION_SYMBOL)) { count++; } } } } return count ; } |
変更後
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
int buy_posi_count() { int count =0; for(int i=PositionsTotal()-1; i>=0; i--) { if("" != PositionGetSymbol(i)) { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { if(Symbol()==PositionGetString(POSITION_SYMBOL)) { if(PositionGetInteger(POSITION_MAGIC)==magic_number) { count++; } } } } } return count ; } |
注文が残っている場合は”何もしない”をする
MT5では
- 注文
- 約定
- ポジション
という流れでポジションを取得します。注文が残っている状態では新規で注文をしないように注文数を確認する機能をつくります。
- 総オーダー数を確認
- 総オーダーに現在のチャートの通貨ペアが含まれるか確認
- 総オーダーに現在のEAに設定しているマジックナンバーが含まれるか確認
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
int order_count() { int count =0; for(int i=OrdersTotal()-1; i>=0; i--) { if("" != OrderGetString(ORDER_SYMBOL)) { if(Symbol()==OrderGetString(ORDER_SYMBOL)) { if(OrderGetInteger(ORDER_MAGIC)==magic_number) { count++; } } } } return count ; } |
値動きごとに注文が残っている場合を確認し、注文が残っている場合は何もしないをします。
OnTick()の直下に以下のコマンドを貼り付けときます。return;でOnTick()が終了します。(注文が残っている状態で再度新規注文させないようにする)
1 |
if(order_count() > 0 ){return;} |
MT5は成行注文→約定→ポジション保有状態(注文失敗でも注文が残る)
MT4は成行注文→約定すればポジション保有状態(注文失敗で注文が無効になる)
MT5は注文から約定までの間の情報を取得可能になりました。
だから注文の価格取得をして約定の価格取得をするとスリッページを取得できたりする。
まあぶっちゃけこの仕様めんどくさいです。
MT5は約定の履歴、注文の履歴とバラバラで管理されるため開発者を混乱させる一因になっている。
いつものセット置いとくよ
MT4からMT5に移行するときの”いつものやつ”をコピペでどこかに置いときます。
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 |
#include <Trade\SymbolInfo.mqh> CSymbolInfo iSymbol; double Bid,Ask,High,Low,Spread; void InitSymbol() { iSymbol.Name(Symbol()); } void SetSymbol() { iSymbol.RefreshRates(); Bid = iSymbol.Bid(); Ask = iSymbol.Ask(); High = iHigh(NULL,PERIOD_CURRENT,0); Low = iLow(NULL,PERIOD_CURRENT,0); Spread = iSymbol.Spread(); } #include <Trade\Trade.mqh> CTrade iTrade; void InitTrade() { iTrade.SetDeviationInPoints(10); iTrade.SetTypeFillingBySymbol(Symbol()); } void SetTrade(ulong magic_num) { iTrade.SetExpertMagicNumber(magic_num); } int OnInit() { InitSymbol(); InitTrade(); SetTrade(magic_number); return(INIT_SUCCEEDED); } |
BUY条件達成かつポジション数が0ならエントリー
1.ゴトー日
2.2時から9時54分に滞在
3.平日
4.ロングポジション数が0
1 2 3 |
if(is_gotobi() && is_buy_time() && is_weekday() && buy_posi_count()==0) { iTrade.Buy(0.1,NULL,0,0,0,"買い"); } |
スプレッド拡大していたら損をするので対策する
スプが広がる可能性もあるのでスプレッド拡大防止のためのコードを追加します。
スプレッドはAsk-Bidで計算できます。
1.ゴトー日
2.2時から9時54分に滞在
3.平日
4.ロングポジション数が0
5.スプレッドが0.25以内
1 2 3 4 5 |
if(is_gotobi() && is_buy_time() && is_weekday() && buy_posi_count()==0) { if((Ask - Bid) < 0.25) { iTrade.Buy(0.1,NULL,0,0,0,"買い"); } } |
以上でエントリーのプログラミングは完成です。
次は決済つくります。
決済ルールを計算する
決済は時間外のときです。
1 |
is_buy_time() |
is_buy_timeで判定しているので、
is_buy_time() == false
なら決済になります。
is_buy_time() == falseは
!is_buy_time()とも表現できるので、
1 |
!is_buy_time() |
あとはポジション数が0ではないなら決済します。
1 |
buy_posi_count()!=0 |
決済判定式
1 |
if(!is_buy_time() && buy_posi_count()!=0){} |
決済関数をつくる
決済させるには
ポジションを識別→決済
させる必要があるので、決済の関数をべつでつくります。
使いやすいように引数追加してBUY決済とSELL決済ができるようにしておきます。
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 |
void position_close(string side) { if(side=="buy_close") { for(int i=PositionsTotal()-1; i>=0; i--) { if("" != PositionGetSymbol(i)) { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { if(Symbol()==PositionGetString(POSITION_SYMBOL)) { if(PositionGetInteger(POSITION_MAGIC)==magic_number) { iTrade.PositionClose(PositionGetTicket(i)); } } } } } } if(side=="sell_close") { for(int i=PositionsTotal()-1; i>=0; i--) { if("" != PositionGetSymbol(i)) { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) { if(Symbol()==PositionGetString(POSITION_SYMBOL)) { if(PositionGetInteger(POSITION_MAGIC)==magic_number) { iTrade.PositionClose(PositionGetTicket(i)); } } } } } } } |
引き渡すデータを引数と呼びます。
(string side) が引数です。
今回は引数を1個渡しています。
引数は呼ぶときに呼び出し元で記述します。
position_close(“buy_close”); ならBUYポジションを決済します。
position_close(“sell_close”); ならSELLポジションを決済します。
条件で決済させる
時間外かつロングポジションを持っているなら決済します。
1.時間外
2.EAのポジション数が0ではない
3.スプレッドが0.25以内
1 2 3 4 5 |
if(!is_buy_time() && buy_posi_count()!=0) { if((Ask - Bid) < 0.25) { position_close("buy_close"); } } |
これで決済も完成です。
OnTick()にSetSymbol();を追加する
MT5にBidやAskというのが使えなくなってしまったので、自分で用意する必要があります。
最初は戸惑うと思いますが、MT4にあった関数や機能がMT5では存在しない場合があります。
なので互換性を持たせるために、少し工夫をする必要があります。
EAが完成!
コード全文
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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
int magic_number = 510; void OnTick() { if(order_count() > 0 ){return;} SetSymbol(); if(is_gotobi() && is_buy_time() && is_weekday() && buy_posi_count()==0) { if((Ask - Bid) < 0.25) { iTrade.Buy(0.1,NULL,0,0,0,"買い"); } } if(!is_buy_time() && buy_posi_count()!=0) { if((Ask - Bid) < 0.25) { position_close("buy_close"); } } if(is_gotobi() && is_sell_time() && is_weekday() && sell_posi_count()==0) { if((Ask - Bid) < 0.25) { iTrade.Sell(0.1,NULL,0,0,0,"売り"); } } if(!is_sell_time() && sell_posi_count()!=0) { if((Ask - Bid) < 0.25) { position_close("sell_close"); } } } bool is_gotobi() { datetime pc_time = TimeLocal(); int day = TimeDay(pc_time); double amari = MathMod(day,5); if(amari==0) { return true; } int youbi = TimeDayOfWeek(pc_time); if(youbi==FRIDAY && amari==3) { return true; } if(youbi==FRIDAY && amari==4) { return true; } return false; } bool is_buy_time() { datetime pc_time = TimeLocal(); int hour = TimeHour(pc_time); int minute = TimeMinute(pc_time); for(int i=2; i < 9; i++) { if(hour == i) { return true; } } if(hour==9 && minute <= 54) { return true; } return false; } bool is_sell_time() { datetime pc_time = TimeLocal(); int hour = TimeHour(pc_time); int minute = TimeMinute(pc_time); if(hour == 9 && 55 <= minute) { return true; } for(int i=10; i < 15; i++) { if(hour == i) { return true; } } return false; } bool is_weekday() { datetime pc_time = TimeLocal(); int youbi = TimeDayOfWeek(pc_time); if(youbi==MONDAY) { return true; } if(youbi==TUESDAY) { return true; } if(youbi==WEDNESDAY) { return true; } if(youbi==THURSDAY) { return true; } if(youbi==FRIDAY) { return true; } return false; } int TimeDay(datetime date) { MqlDateTime tm; TimeToStruct(date,tm); return(tm.day); } int TimeHour(datetime date) { MqlDateTime tm; TimeToStruct(date,tm); return(tm.hour); } int TimeMinute(datetime date) { MqlDateTime tm; TimeToStruct(date,tm); return(tm.min); } int TimeDayOfWeek(datetime date) { MqlDateTime tm; TimeToStruct(date,tm); return(tm.day_of_week); } int buy_posi_count() { int count =0; for(int i=PositionsTotal()-1; i>=0; i--) { if("" != PositionGetSymbol(i)) { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { if(Symbol()==PositionGetString(POSITION_SYMBOL)) { if(PositionGetInteger(POSITION_MAGIC)==magic_number) { count++; } } } } } return count ; } int sell_posi_count() { int count =0; for(int i=PositionsTotal()-1; i>=0; i--) { if("" != PositionGetSymbol(i)) { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) { if(Symbol()==PositionGetString(POSITION_SYMBOL)) { if(PositionGetInteger(POSITION_MAGIC)==magic_number) { count++; } } } } } return count ; } int order_count() { int count =0; for(int i=OrdersTotal()-1; i>=0; i--) { if("" != OrderGetString(ORDER_SYMBOL)) { if(Symbol()==OrderGetString(ORDER_SYMBOL)) { if(OrderGetInteger(ORDER_MAGIC)==magic_number) { count++; } } } } return count ; } void position_close(string side) { if(side=="buy_close") { for(int i=PositionsTotal()-1; i>=0; i--) { if("" != PositionGetSymbol(i)) { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { if(Symbol()==PositionGetString(POSITION_SYMBOL)) { if(PositionGetInteger(POSITION_MAGIC)==magic_number) { iTrade.PositionClose(PositionGetTicket(i)); } } } } } } if(side=="sell_close") { for(int i=PositionsTotal()-1; i>=0; i--) { if("" != PositionGetSymbol(i)) { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) { if(Symbol()==PositionGetString(POSITION_SYMBOL)) { if(PositionGetInteger(POSITION_MAGIC)==magic_number) { iTrade.PositionClose(PositionGetTicket(i)); } } } } } } } #include <Trade\SymbolInfo.mqh> CSymbolInfo iSymbol; double Bid,Ask,High,Low,Spread; void InitSymbol() { iSymbol.Name(Symbol()); } void SetSymbol() { iSymbol.RefreshRates(); Bid = iSymbol.Bid(); Ask = iSymbol.Ask(); High = iHigh(NULL,PERIOD_CURRENT,0); Low = iLow(NULL,PERIOD_CURRENT,0); Spread = iSymbol.Spread(); } #include <Trade\Trade.mqh> CTrade iTrade; void InitTrade() { iTrade.SetDeviationInPoints(10); iTrade.SetTypeFillingBySymbol(Symbol()); } void SetTrade(ulong magic_num) { iTrade.SetExpertMagicNumber(magic_num); } int OnInit() { InitSymbol(); InitTrade(); SetTrade(magic_number); return(INIT_SUCCEEDED); } |
あとは
この表示がでる。
これで完成です。
バックテストは出来ない
Windowsの時刻をつかうので、バックテストは出来ないです。
代わりにTradingViewでのバックテストをのせておきます。
ロングエントリールールは2時00分~9時54分に滞在、決済ルールは9時55分に到達。
ショートエントリールールは9時55分~14時59分に滞在、決済ルールは15時00分に到達。
Gotobi Teriyaki by hosono_p on TradingView.com
コードは以下のリンクから確認できます。
ブログの存続のため、TradingViewの有料アカウントを申し込むときは以下の紹介リンクから申し込みをお願いします。
実際に稼働させる
これでおわりです。
MT5のEAが完成!
お疲れ様でした。
全部がおわりです。
ゴトー日のEAは勝てるEAだと思っているので実運用しています。
内容でわからないことはコメントに書き込みしてください。
まとめとおさらい
エントリーと決済ルールが必要。
・無料
・デモ口座が使える
・UIが綺麗
・新しい
・MT5の操作に癖があるので慣れるまでちょっとめんどくさい
・MT4よりもプログラミング難易度が高い
このブログは広告で運営費を捻出しています。
なので広告収入がないとそのうち消滅します。
なので紹介リンクから口座開設の協力をお願いいたします。
ゆくゆくは仮想通貨の自動売買もしたいのでMT5はFXGTの口座を利用します。
あとAmazonで何か買い物をしてください。
ワンピースおもしろい!
ほしい。
いま読んでます。
ゴトー日のアノマリー解説本。
BybitがGoogleのIPアドレス規制をしているためです。国内のVPSなら使…
自分のbotで使ってるAPIキーを使用しているんですが、 You have br…
pybit 最新版にコードを変更しました。コードとrequirements.tx…
お返事ありがとうございます。はい。pybit==2.3.0になっております。
コードはあっていると思います。rewuirements.txtは「pybit==…