レンジブレイクアウトを作る。
初心者むけに解説しています。
ロジックは以下の記事を読んでみてください!
Table of Contents
MT4で自動売買EA(エキスパートアドバイザー)を自作する
毎度ですが先にゴールを決めてから作りはじめます。
今回のゴールは、「レンジブレイクアウトEA」をつくります。
MT4のEAの作り方は、
後述します。
・エントリー
・決済
の2個のルールが必要です。
ネットでググるとほとんど情報がでてくるので、きっと作れます。
自動化させるロジックを確認
先にTradingViewでロジックを確認します。
エントリールール
- A ローソク足40本
- B 移動平均線期間N
- C 「終値」と「移動平均線」クロスを期間内に4回以上
- D チャネルブレイクアウト期間40 順張り
決済ルール
- A 期間40 最高値 ー 最安値
- B A ÷ 2
- C Bの値幅でトレーリングストップ
レンジブレイクアウト by hosono_p on TradingView.com
ブログの存続のため、TradingViewの有料アカウントを申し込むときは以下の紹介リンクから申し込みをお願いします。
MT4のインストール
仮想通貨の自動売買をしたいのでMT4はエクスネスのデモ口座を利用します。
エクスネスのMT4デモ口座の申請方法
お疲れ様でした。これでMT4の準備完了です。次はプログラミング用のエディタを表示させます。
MT4のプログラミングエディタ(メタエディタ)を起動
MQLのプログラムのコードはここに書いていきます。
エキスパートアドバイザーの新規作成
新規で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 36 |
//+------------------------------------------------------------------+ //| MAゴールデンクロス.mq4 | //| Copyright 2022, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2022, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ |
上から9行目まではEAの説明文など
1 2 3 4 5 6 7 8 9 |
//+------------------------------------------------------------------+ //| MAゴールデンクロス.mq4 | //| Copyright 2022, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2022, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict |
最後の 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が実行させているので返却しなくてもいい。
レンジを判定する機能をつくる
初心者向けに関数の説明からするので知ってる人は次項まで飛ばしてください。
空っぽの関数をつくっておきます。
呼び出したら、内容に応じてデータを返却します。
これだけの説明だと意味不明なので
まあ、使ってみますか。
関数の動作確認します。
1 2 3 4 5 6 7 8 |
#property strict void OnTick() { Print(is_range()); } bool is_range(){ return false; } |
この状態でコンパイルを押すと、
ツールボックスに詳細が表示される。
Print()
Print()でエキスパートのログに出力させることができます。
関数の返却されたデータを表示させています。
今は、
だけなのでfalseが表示されています。
一般的にほぼ馴染みがないfalseはプログラムしてるとたびたび遭遇します。
〇か×かで
〇 は true;
× は false;
true(トゥルー) 又は false(フォルス) を真偽値(しんぎち)と呼びます。
真偽値はBoolean型、bool型、ブール型と呼ばれる。
一般的にほぼ馴染みがない「型(がた)」はプログラムしてるとたびたび遭遇します。
文字は文字列型、数字は数字型、真偽値はブール型とデータよって型が決まります。
例)
”1” → 文字列型の1(文字列は””、’’で囲む)
1 → 整数型の1
true → ブール型のtrue
型で使える機能が違います。
・整数型の例)
例えば整数型の1と整数型の2を足すと、算数になる
1 + 2
= 3
・文字列型の例)
例えば文字列型の”1”と文字列型の”2”を足すと、文字の連結になる
“1 “+ “2”
= “12”
”1” → 文字列型の1(文字列は””、’’で囲む)
1 → 整数型の1
true → ブール型のtrue
関数は、
型、スペース、カッコ、波カッコの順番で書きます。
bool is_range(){}
型:bool
スペース:
カッコ:()
波カッコ:{}
カッコ()には引き渡すデータを書きます。(今回は引き渡しのデータなしなので空白)
波カッコ{}の中には、処理と返却値を書きます。
bool is_range(){return false;}
現在の関数の返却値はfalseです。
OnTick関数は値動きがあったらOnTick内部の処理が実行されます。
例えばBTCUSDの最小単位0.01が動けば実行されます。
20000.00→20000.01
呼び出してPrint()で表示させています。
なので、以下のプログラムは
値動き毎に、is_range()の中身をエキスパートのメッセージに出力しています。
void OnTick() { Print(is_range()); }
なので、今は値動き毎にfalseが表示されています。
void OnTick() { Print(is_range()); }
セミコロン;を付け忘れるとerrorが表示される。
セミコロン;をつけるタイミングはステップ(1行)ごとです。
初心者はセミコロン;をつける、つけないはわからないと思います。慣れるしかないです。
レンジ状態を判断する機能をつくる
これで1個前(i + 1)のローソク足の状態を定義した。
次は現在足の定義
条件分岐でカウントアップさせます。
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_range() { int count=0; for(int i = 1; i <= 40; i++) { //移動平均線 <= 終値 bool up = iMA(NULL,0,20,0,0,0,i+1) <= iClose(NULL,0,i+1); //移動平均線 >= 終値 bool down = iMA(NULL,0,20,0,0,0,i+1) >= iClose(NULL,0,i+1); //現在足 移動平均線 <= 終値 bool current_up = iMA(NULL,0,20,0,0,0,i) <= iClose(NULL,0,i); //現在足 移動平均線 >= 終値 bool current_down = iMA(NULL,0,20,0,0,0,i) >= iClose(NULL,0,i); //もしもup状態でcurrent_downならクロス if(up && current_down) { count++; } //もしもdown状態でcurrent_upならクロス if(down && current_up) { count++; } } if(4 <= count) { return true; } return false; } |
レンジの判定が完成。
次は高値安値のチャネル
高値安値のチャネル価格を調べる機能をつくる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
double get_highest_price() { int index=iHighest(NULL,0,MODE_HIGH,40,1); double highest_price = iHigh(NULL,0,index); return highest_price; } double get_lowest_price() { int index=iLowest(NULL,0,MODE_LOW,40,1); double lowest_price = iLow(NULL,0,index); return lowest_price; } |
ポジション数、指値注文数を調べる機能をつくる
ポジション数が0の時にのみトレードを行いたいのでポジション数を調べる機能をつくります。
ググったらでてきます。
- すべてのオーダーを確認
- オーダータイプ(ロングorショートorロング指値注文orショート指値注文)
- オーダーシンボル(通貨ペア)
- マジックナンバー(EA識別番号)
上記すべてを満たすポジションが存在するならcountの数字をプラス1する。
マジックナンバーはあとでエントリー時に付与するのですが、「036」に指定します。777のマジックナンバーなら、このEAでのエントリーになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
int position_count(int side) { int count = 0; for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderType() == side) { if(OrderSymbol()==Symbol()) { if(OrderMagicNumber()==036) { count++; } } } } } return count; } } |
カッコの中は引数です。
引き渡すデータを引数と呼びます。
(int side)が引数です。
今回は引数を1個渡しています。
引数は呼ぶときに呼び出し元で記述します。
関数仕様の例)
posi_count(0); ならBUYポジションをカウントします。
posi_count(1); ならSELLポジションをカウントします。
countは初期値0の整数です。
int count = 0;
整数型は++をつけるとカウントアップします。
これをインクリメントと呼びます。
ちなみに–をつけるとカウントダウンします。これはデクリメントと呼びます。
オーダーキャンセルの機能をつくる
ググればでます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
void order_all_cancel() { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderType() == 4 || OrderType() == 5) { if(OrderSymbol()==Symbol()) { if(OrderMagicNumber()==036) { bool res=OrderDelete(OrderTicket()); } } } } } } |
ポジションエントリーの関数をつくる
ググったらでてきます。
1 2 3 4 5 |
void position_entry(int side,double price) { double qty = 0.1; bool res= OrderSend(NULL,side,qty,price,0,0,0,NULL,036,0,clrGreen); } |
注文数量です。
ポジション決済の関数をつくる
ググったらでる。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void position_close(int side) { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderType() == side) { if(OrderSymbol()==Symbol()) { if(OrderMagicNumber()==777) { bool res= OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0, clrBlue); } } } } } } |
ローソク足が切り替わった時のみ処理をする機能をつくる
OnTick()関数の中に記述。
1 2 3 4 5 |
//ローソク足が切り替わる時のみ動作する static datetime prev_time; if(prev_time != iTime(NULL,0,0)) { prev_time = iTime(NULL,0,0); |
条件を満たしたらエントリーする機能をつくる
細かい関数はつくりおわったのでOnTick()を書き換えていきます。
- is_range()がtrue
- 買いポジション数が0
- 売りポジション数が0
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 |
void OnTick() { //ローソク足が切り替わる時のみ動作する static datetime prev_time; if(prev_time != iTime(NULL,0,0)) { prev_time = iTime(NULL,0,0); //エントリー //注文数が0かつ、ポジション保有が0の場合 if(is_range() && position_count(OP_BUY) == 0 && position_count(OP_SELL) == 0 && position_count(OP_BUYSTOP) == 0 && position_count(OP_SELLSTOP) == 0) { position_entry(OP_BUYSTOP,get_highest_price() + _Point); position_entry(OP_SELLSTOP,get_lowest_price() - _Point); } //エントリー //注文数が1以上かつ、ポジション保有が0の場合 if(is_range() && position_count(OP_BUY) == 0 && position_count(OP_SELL) == 0 && (position_count(OP_BUYSTOP) != 0 || position_count(OP_SELLSTOP) != 0)) { order_all_cancel(); position_entry(OP_BUYSTOP,get_highest_price() + _Point); position_entry(OP_SELLSTOP,get_lowest_price() - _Point); } } } |
MQLには定数と呼ばれる,
あらかじめ用意されている変数があります。
ポジションのストップを変更する機能をつくる
ググればでる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
void position_modify(int side,double price) { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderType() == side) { if(OrderSymbol()==Symbol()) { if(OrderMagicNumber()==036) { bool res=OrderModify(OrderTicket(),OrderOpenPrice(),price,0,0,clrYellow); } } } } } } |
トレーリングストップ機能をつくる
ロングポジションのストップ変更
- 条件A ストップロスが設定されていない。
- 条件B ストップロス + トレーリングストップ値幅 < 現在価格
ショートポジションのストップ変更
- 条件A ストップロスが設定されていない。
- 条件B ストップロス ー トレーリングストップ値幅 > 現在価格
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 |
void trailing_stop(double nehaba) { double trailing_stop_price=0; bool A; bool B; //ポジションを調べる for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { { if(OrderSymbol()==Symbol()) { if(OrderMagicNumber()==036) { //ロングポジション if(OrderType()==OP_BUY) { trailing_stop_price = iClose(NULL,0,0) - nehaba; //A ストップが0に設定されている A = OrderStopLoss() == 0; //B ストップ+ストップ値幅 < 現在価格 B = (OrderStopLoss() + nehaba) < iClose(NULL,0,0) - _Point; //もしも A or B なら if(A || B) { position_modify(OP_BUY,trailing_stop_price);//ポジションのストップ変更 } } //ショートポジション if(OrderType()==OP_SELL) { trailing_stop_price = iClose(NULL,0,0) + nehaba; //A ストップが0に設定されている A = OrderStopLoss() == 0; //B ストップ ー ストップ値幅 > 現在価格 B = (OrderStopLoss() - nehaba) > iClose(NULL,0,0) + _Point; //もしも A or B なら if(A || B) { position_modify(OP_SELL,trailing_stop_price);//ポジションのストップ変更 } } } } } } } } |
トレーリングストップの値幅の計算する機能をつくる
(最高値 - 最安値) ÷ 2
1 2 3 4 5 6 7 |
double calc_trail_offset() { double nehaba; nehaba = (get_highest_price() - get_lowest_price()) / 2; nehaba = NormalizeDouble(nehaba,Digits());//小数点丸めた return nehaba; } |
条件を満たしたらトレーリングストップを注文する機能をつくる
以下の条件でトレーリングストップの値幅計算する
- ポジション保有0
以下の条件トレーリングストップの注文される
- ポジション保有状態
チャートからEAを削除した時に指値を削除する
関数オンデイニットを使います。
1 2 3 |
void OnDeinit(const int reason){ order_all_cancel(); } |
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 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
#property strict void OnDeinit(const int reason){ order_all_cancel(); } void OnTick() { //ローソク足が切り替わる時のみ動作する static datetime prev_time; if(prev_time != iTime(NULL,0,0)) { prev_time = iTime(NULL,0,0); //エントリー //注文数が0かつ、ポジション保有が0の場合 if(is_range() && position_count(OP_BUY) == 0 && position_count(OP_SELL) == 0 && position_count(OP_BUYSTOP) == 0 && position_count(OP_SELLSTOP) == 0) { position_entry(OP_BUYSTOP,get_highest_price() + _Point); position_entry(OP_SELLSTOP,get_lowest_price() - _Point); } //エントリー //注文数が1以上かつ、ポジション保有が0の場合 if(is_range() && position_count(OP_BUY) == 0 && position_count(OP_SELL) == 0 && (position_count(OP_BUYSTOP) != 0 || position_count(OP_SELLSTOP) != 0)) { order_all_cancel(); position_entry(OP_BUYSTOP,get_highest_price() + _Point); position_entry(OP_SELLSTOP,get_lowest_price() - _Point); } } //ポジション数が0の時のみ、トレーリングストップの値幅計算 static double nehaba = 0; if(position_count(OP_BUY) == 0 && position_count(OP_SELL) == 0) { nehaba = calc_trail_offset(); } //トレーリングストップ決済とポジション保有状態ならエントリーオーダーキャンセルする if(position_count(OP_BUY) > 0 || position_count(OP_SELL) > 0) { trailing_stop(nehaba); order_all_cancel(); } //レンジではないならオーダーキャンセル if(is_range()== false){order_all_cancel();} } //+------------------------------------------------------------------+ //| レンジ判定 //+------------------------------------------------------------------+ bool is_range() { int count=0; for(int i = 1; i <= 40; i++) { //移動平均線 <= 終値 bool up = iMA(NULL,0,20,0,0,0,i+1) <= iClose(NULL,0,i+1); //移動平均線 >= 終値 bool down = iMA(NULL,0,20,0,0,0,i+1) >= iClose(NULL,0,i+1); //現在足 移動平均線 <= 終値 bool current_up = iMA(NULL,0,20,0,0,0,i) <= iClose(NULL,0,i); //現在足 移動平均線 >= 終値 bool current_down = iMA(NULL,0,20,0,0,0,i) >= iClose(NULL,0,i); //もしもup状態でcurrent_downならクロス if(up && current_down) { count++; } //もしもdown状態でcurrent_upならクロス if(down && current_up) { count++; } } if(4 <= count) { return true; } return false; } //+------------------------------------------------------------------+ //|最高値取得 //+------------------------------------------------------------------+ double get_highest_price() { int index=iHighest(NULL,0,MODE_HIGH,40,1); double highest_price = iHigh(NULL,0,index); return highest_price; } //+------------------------------------------------------------------+ //|最安値取得 //+------------------------------------------------------------------+ double get_lowest_price() { int index=iLowest(NULL,0,MODE_LOW,40,1); double lowest_price = iLow(NULL,0,index); return lowest_price; } //+------------------------------------------------------------------+ //|ポジション数カウント //+------------------------------------------------------------------+ int position_count(int side) { int count = 0; for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderType() == side) { if(OrderSymbol()==Symbol()) { if(OrderMagicNumber()==036) { count++; } } } } } return count; } //+------------------------------------------------------------------+ //|ポジションエントリー //+------------------------------------------------------------------+ void position_entry(int side,double price) { double qty = 0.1; bool res= OrderSend(NULL,side,qty,price,0,0,0,NULL,036,0,clrGreen); } //+------------------------------------------------------------------+ //|ポジション決済 //+------------------------------------------------------------------+ void position_close(int side) { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderType() == side) { if(OrderSymbol()==Symbol()) { if(OrderMagicNumber()==036) { bool res= OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0, clrBlue); } } } } } } //+------------------------------------------------------------------+ //|ポジションのストップ変更 //+------------------------------------------------------------------+ void position_modify(int side,double price) { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderType() == side) { if(OrderSymbol()==Symbol()) { if(OrderMagicNumber()==036) { bool res=OrderModify(OrderTicket(),OrderOpenPrice(),price,0,0,clrYellow); } } } } } } //+------------------------------------------------------------------+ //|注文のキャンセル //+------------------------------------------------------------------+ void order_all_cancel() { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderType() == 4 || OrderType() == 5) { if(OrderSymbol()==Symbol()) { if(OrderMagicNumber()==036) { bool res=OrderDelete(OrderTicket()); } } } } } } //+------------------------------------------------------------------+ //|トレーリングストップ注文 //+------------------------------------------------------------------+ void trailing_stop(double nehaba) { double trailing_stop_price=0; bool A; bool B; //ポジションを調べる for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { { if(OrderSymbol()==Symbol()) { if(OrderMagicNumber()==036) { //ロングポジション if(OrderType()==OP_BUY) { trailing_stop_price = iClose(NULL,0,0) - nehaba; //A ストップが0に設定されている A = OrderStopLoss() == 0; //B ストップ+ストップ値幅 < 現在価格 B = (OrderStopLoss() + nehaba) < iClose(NULL,0,0) - _Point; //もしも A or B なら if(A || B) { position_modify(OP_BUY,trailing_stop_price);//ポジションのストップ変更 } } //ショートポジション if(OrderType()==OP_SELL) { trailing_stop_price = iClose(NULL,0,0) + nehaba; //A ストップが0に設定されている A = OrderStopLoss() == 0; //B ストップ ー ストップ値幅 > 現在価格 B = (OrderStopLoss() - nehaba) > iClose(NULL,0,0) + _Point; //もしも A or B なら if(A || B) { position_modify(OP_SELL,trailing_stop_price);//ポジションのストップ変更 } } } } } } } } //+------------------------------------------------------------------+ //|トレーリングストップの値幅計算 //+------------------------------------------------------------------+ double calc_trail_offset() { double nehaba; nehaba = (get_highest_price() - get_lowest_price()) / 2; nehaba = NormalizeDouble(nehaba,Digits());//小数点丸めた return nehaba; } //+------------------------------------------------------------------+ |
あとは
この表示がでる。
これで完成です。
バックテスト
指値のバックテスト面白いねw
指値とトレーリングストップでめちゃくちゃ重たい🤢
いつもの5倍ぐらい時間かかるんだが。
初心者向けなので、あえてわかりやすさを優先してコーディングしているので、ポジション保有状態あたりを修正すると速くなるかもしれません。
あと全ティックにから始値のみに変更するとバックテスト早くなる。
実際に稼働させる
これでおわりです。
MT4のEAが完成!
お疲れ様でした。
全部がおわりです。
ハー。つよい。
ポートフォリオにいれるんごw
まとめとおさらい
エントリーと決済ルールが必要。
・無料
・デモ口座が使える
・情報が豊富にある
・MT4の操作に癖があるので慣れるまでちょっとめんどくさい
このブログはアフィリエイトで運営費を捻出しています。
なのでアフィリエイト収入がないとそのうちブログが消滅します。
Exnessの口座を持ってない方はこちらのリンクから申し込みをしてもらえると管理人にアフィリエイト収入が入ります。
以下のリンクからAmazonで何かしらを購入してもらえると管理人にアフィリエイト収入が入ります。
稼いだ方はお祝いどうぞ
パソコン
MQLの本が出来たみたいですよ😀
MQL勉強にいいです
BybitがGoogleのIPアドレス規制をしているためです。国内のVPSなら使…
自分のbotで使ってるAPIキーを使用しているんですが、 You have br…
pybit 最新版にコードを変更しました。コードとrequirements.tx…
お返事ありがとうございます。はい。pybit==2.3.0になっております。
コードはあっていると思います。rewuirements.txtは「pybit==…