FX自動売買システム開発

自作EAでナンピン買いを行う方法【MT4でFX自動売買】

 

↓そもそも「MT4って何?」という方はこちら。
メタトレーダー(MT4)の使い方!入手方法も解説

↓サンプルEAの動かし方や評価、改編方法は以下
MT4で自作するFX自動売買システム(EA)とは?作り方を徹底解説!

 

 

1.【質問】自動売買でナンピンをするにはどうすれば?

 

質問者

保有ポジションを分割する「ナンピン」を実装したいと考えています。
できれば後のポジションほどロット数が大きくなるようにしたいです。
恐らくポジション情報の取得が必要だと思いますがどうでしょうか。

 

2.【回答】開発工程をいくつかのステップで考える

 

Hazu

先に取ったポジションの情報が必要という予想は合っています。
ですが、希望のロジックを実現するには少々工夫が必要になります。
具体的には以下のように機能を分割して考える必要があります。

 

手順

①  保有ポジション価格を取得し現在値と比較するロジックを作成

②  保有ポジション数をカウントしロット数に反映するロジックを作成

③  ①,②を組み合わせてナンピン買いロジックを作成

 

ナンピンとは?

保有ポジションに対し相場が逆行した際に買い増しで平均単価を下げる手法です。
例えば108円でドル円の買いポジを取った後、107円まで逆行したとします。
同じ数のポジションを新たにとれば平均は107.5円です。

 

HAZU
狙いが正しければ有効ですが、間違っていれば損失を広げる諸刃の剣です。
初心者の退場理由の多くがナンピンによる「コツコツドカン」です。

 

保有ポジションの情報をOrderSelect()で取得

OrderSelect(,,);

①インデックス番号を指定。先に取ったポジションから1,2,3と増えていきます。

②タイプを指定。①でチケット番号をしたい場合はここで指定。

③取得したい情報を指定。今回はポジション価格、売買方向を取得。

 

必要なロジックを公開

 

① 保有ポジションから価格を取得し現在値と比較するロジック

 

HAZU

こちらで公開しているコードの該当部分を以下に差し替えてください。
マーカの部分が主な変更点です。

 

 command
//------------------------------------------------------------------------------------
// 3. position : ポジション管理
//------------------------------------------------------------------------------------
void position(){
//ポジション数取得
int res;
int tpoji = 0;
int pojilim = 4;
int torder = OrdersTotal();
//ポジション数カウント
for(int i = torder-1; i >= 0; i--){
res = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol()==rcur&&((OrderType()==0&&result==1)||(OrderType()==1&&result==-1)))
tpoji += 1;
}
//ポジション構築
if(tpoji<pojilim&&result!=0&&goflg)
ordersend();
}
//------------------------------------------------------------------------------------
// 4. ordersend : ポジション構築
//------------------------------------------------------------------------------------
void ordersend(){
int res = 0;
double BID = MarketInfo(rcur,MODE_BID);
double ASK = MarketInfo(rcur,MODE_ASK);
double PIP = MarketInfo(rcur,MODE_SPREAD);
double lots = 10;
double HI = 0;
double LOW = 0;
bool noflg = true;
//選択通貨ポジション数取得
int torder = OrdersTotal();
for(int i = torder-1; i >= 0; i--){
res = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol()==rcur&&((OrderType()==0&&result==1)||(OrderType()==1&&result==-1)))
if(OrderType()==1&&result==-1){
if(OrderOpenPrice()>=HI||HI==0)
HI=OrderOpenPrice();
}
if(OrderType()==0&&result==1){
if(OrderOpenPrice()<=LOW||LOW==0)
LOW=OrderOpenPrice();
}
}
if(result==-1&&HI!=0){
if(HI+0.05>=ASK)
noflg = false;
}
if(result==1&&LOW!=0){
if(LOW-0.05<=BID)
noflg = false;
}
//売り指示
if(result==-1&&PIP<=100&&noflg){
res = OrderSend(rcur,OP_SELL,0.01*lots,BID,100,ASK+0.2,ASK-0.4,"Short",MAGICMA,0,clrRed);
Sleep(3000);
}
//買い指示
else if(result==1&&PIP<=100&&noflg){
res = OrderSend(rcur,OP_BUY,0.01*lots,ASK,100,BID-0.2,BID+0.4,"Long",MAGICMA,0,clrRed);
Sleep(3000);
}
}

 

保有ポジションのエントリー価格を取得して現在値と比較します。
サンプルコードは 5pips 逆行するごとに売買命令をするよう設定しています。
今回はポジションを4つに分けて取るようにしています。

 

② ポジション数をカウントしロット数に反映するロジック

 

HAZU

こちらで公開しているコードの該当部分を以下に差し替えてください。
マーカの部分が主な変更点です。

 

 command
//------------------------------------------------------------------------------------
// 3. position : ポジション管理
//------------------------------------------------------------------------------------
void position(){
//ポジション数取得
int res;
int tpoji = 0;
int pojilim = 4;
int torder = OrdersTotal();
//ポジション数カウント
for(int i = torder-1; i >= 0; i--){
res = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol()==rcur&&((OrderType()==0&&result==1)||(OrderType()==1&&result==-1)))
tpoji += 1;
}
//ポジション構築
if(tpoji<pojilim&&result!=0&&goflg)
ordersend();
}
//------------------------------------------------------------------------------------
// 4. ordersend : ポジション構築
//------------------------------------------------------------------------------------
void ordersend(){
int res = 0;
double BID = MarketInfo(rcur,MODE_BID);
double ASK = MarketInfo(rcur,MODE_ASK);
double PIP = MarketInfo(rcur,MODE_SPREAD);
double lots;
int tpoji = 0;
int torder = OrdersTotal();
for(int i = torder-1; i == 0; i--){
if(OrderSymbol()==rcur&&((OrderType()==0&&result==1)||(OrderType()==1&&result==-1)))
tpoji += 1;
}
lots = MathFloor(5*(1+tpoji));
//売り指示
if(result==-1&&PIP<=100){
res = OrderSend(rcur,OP_SELL,0.01*lots,BID,100,ASK+0.2,ASK-0.4,"Short",MAGICMA,0,clrRed);
Sleep(3000);
}
//買い指示
else if(result==1&&PIP<=100){
res = OrderSend(rcur,OP_BUY,0.01*lots,ASK,100,BID-0.2,BID+0.4,"Long",MAGICMA,0,clrRed);
Sleep(3000);
}
}

 

保有ポジションが1つ増えるごとにロット数を 2倍、3倍と増やしていきます。

 

③ ①と②を組み合わせることで実現できるロジック

具体的には以下のようなロジックを作ることが可能です。

・打診買いの際にはロット数を低めにしておく

・まずはポジションを大きくとって、あとで平均単価を合わせる

 

実際に実装した画面が以下になります。

 

HAZU
1ペア目から5pips刻みで、ポジションが増えています。
売買のタイミングやスプレッドで多少ずれますが、許容範囲かと思います。

 

3.EA開発に詰まったら

EA開発に限らず、物事に詰まったら外部の知識を頼るのが賢い選択です。
以下ではトレードとプログラミングに役立つ参考書籍やサービスを紹介します。

 

①書籍でトレードの勉強

基本ブログ内で完結するよう心がけていますが、以下の本があると理解が深まります。
シリーズものですがとりあえず1冊読んでみると良いかと思います。

■FXメタトレーダー入門 AMAZON 楽天

 

②無料のプログラミングスクールを活用

ソースコードの理解に苦しむようであれば初級レベルのプログラミングを学びましょう。
最初の基礎ベースを身に着けるならTechAcademyがおすすめです。
TechAcademyは1週間の無料体験があるので、それで十分学べるかと思います。

>>Techacademyの無料体験はこちら

 

4.まとめ

複雑なロジックはいくつかの機能に分けて考えましょう。
実現したいロジックがあった場合、まずは必要な機能を書き出します。
コピペでEAを作る場合もソースコードを探すのが容易になります。
また、それをサブ関数化することで後の開発に使いまわすことが可能です。

 

その他のロジックについて知りたい方は以下の記事を参照下さい。

>>参考:『FX自動売買システム(EA)の自作に困った際のヒント集』

 

以上、参考になれば幸いです。

 

  • この記事を書いた人

HAZU

静岡の一部上場企業で働く兼業投資家、投資を初めて6年が経ちました。30代のセミリタイアを目指して20代からコツコツと資産形成中。趣味はキャンプとプログラミング。ブログでは主に【FXの始め方から自動化】までを扱っています。

-FX自動売買システム開発

© 2021 HAZUの資産形成ラボ Powered by AFFINGER5