朝スキャEAを複数ポジション同時に保有できるようカスタマイズ【コピペで使用可能】
これまでの記事では、単純な時間制限と逆張りだけで優位なバックテスト結果を出せることを紹介しました。
本記事からは、前回作成したEAをもとに、さまざまな機能を追加してどのように結果が変化するのかを見ていきましょう。
前回のEAは、1つのポジションしか同時に保有することができない仕様でした。
今回は、複数のポジションを同時に保有できるようにカスタマイズしていきます。
同時保有ポジション数がEAに与える影響
まずは、同時保有ポジション数を増やすメリットとデメリットについて解説します。
<メリット>
大きなメリットは、エントリーのチャンスを逃さず、より利益を拡大できる可能性があることです。
単ポジ型のEAの場合は、ポジションを保有している間、追加でポジションを保有することができません。
そのためポジション保有時に絶好のエントリーチャンスがあっても、見逃してしまうことが起きてしまいます。
また、連続でエントリーを行うと疑似的にナンピンのような形になり、損益分岐点をより近いポイントに引き上げることができるというメリットもあります。
<デメリット>
当然のことですが、ポジションを保有した数だけ、相場が逆行したときに損害が拡大しやすくなります。
最大保有ポジション数を増やせば増やすほど、こつこつと利益を積み上げることもできますが、ドカンと負けた時の損害が大きくなってしまいます。
また、ロット数の管理が難しいというデメリットもあります。
多くの証券会社では、証拠金維持率が一定の値を下回ると、強制ロスカットが行われてしまいます。
ポジションは保有するだけで証拠金維持率もぐんと低下するため、事前に「〇ロットで〇ポジションなら保有することができる」という価格水準を計算しておく必要があります。
仕様
まずは前回作成したEAの仕様をまとめます。
・エントリー
時間が日本時間早朝かつRSIが売られすぎラインを下回ったら、買いエントリー
時間が日本時間早朝かつRSIが買われすぎラインを上回ったら、売りエントリー
・決済
利確価格と損切価格による決済
・その他
著作権を「OANDA」に設定
スリッページ、スプレッドによってエントリーを制限する
ポジションは同時に1つのみ保有するようにする
マジックナンバーとロット数を変更できるようにする
以上です。
今回は、「その他」の「ポジションは同時に1つのみ保有するようにする」という条件を「同時保有ポジション数をパラメータで変更できるようにする」に変更します。
EAを作成する
プログラムは前回の「5.朝スキャのEAを作ってみよう」をもとに作成していくので、前回までの内容は割愛し、今回追加する機能のみ紹介します。
input int MAGICMA = 23498721; // マジックナンバー
input double Lots =0.01; // 1ロット十万通貨単位
input int Slippage = 4; // エントリー見送りスリッページ
input double MaxSpread = 5; // エントリー見送りスプレッド
input double TakeProfit = 10.0; // 利益確定幅(pips)
input double LossCut = 20.0; // 損切確定幅(pips)
input int RSIPeriod=6; // 期間
input ENUM_APPLIED_PRICE RSIAppliedPrice = PRICE_CLOSE; // 適用価格
input int UpLine = 85; // 上の線
input int DownLine = 25; // 下の線
input int TradeTime = 0; // トレードを行う時間
input int MaxPositions = 5; // 最大保有ポジション数
double dSpread;
前回のプログラムに「最大保有ポジション数」というパラメータを追加しています。
このパラメータで指定した値だけ同時にポジションを保有することができます。
OnTick関数
void OnTick()
{
dSpread = (Ask - Bid) / (Point * 10);
//if(CalculateCurrentOrders()==0 && dSpread < MaxSpread) CheckForOpen(); 前回まで
if(CalculateCurrentOrders() < MaxPositions && dSpread < MaxSpread && Volume[0] == 1) CheckForOpen(); //今回
}
OnTick関数です。
前回は「CalculateCurrentOrders()==0」という条件で「保有ポジション数が0の時のみエントリーする」としていましたが、今回は「CalculateCurrentOrders() < MaxPosition」として、パラメータで設定したポジション数までは同時に保有することができるようにします。
また新たな条件として「Volume[0] == 1」を追加しています。
Volume[0]は、現在のローソク足の出来高の数を取得することができます。
「Volume[0] == 1」は「現在のローソク足の出来高が1つめの時」つまり「ローソク足ができた瞬間」という条件を追加しています。
イメージしにくいかもしれないので、「Volume[0] == 1」という条件がある場合とない場合でどのような違いがあるのかを見ていきましょう。
・「Volume[0] == 1」がない場合
ビジュアルモードでバックテストを行った結果は、以下の通りです。
少しわかりにくいですが、同じローソク足で買いポジションを5つも連続で保有してしまっています。
この挙動はよくありません。
エントリー時のスプレッドがもったいないため、これならロット数を上げてポジションを1つだけ保有するほうが断然良いです。
・「Volume[0] == 1」がある場合
「Volume[0] == 1」を追加すると、以下の結果です。
このように、「Volume[0] == 1」を追加することで、各ローソク足の1ティック目でのみエントリーが行われています。
バックテスト
今回作成した最大保有ポジション数5つのEAと、前回作成した単ポジ型のEAのバックテスト結果を比較してみましょう。
条件は以下の通りです。
- 通貨ペア:GBPUSD
- 時間足:5分足
- 期間:2018年1月1日~2023年1月1日の5年間
- スプレッド:15固定
・単ポジ型
・最大保有ポジション数5つ
注目すべき点は「総取引数」と「プロフィットファクター」です。
今回「最大保有ポジション数」を指定したことで、総取引回数を511から987回まで増やすことができました。
また、「最大保有ポジション数」を指定して疑似的にナンピンの働きを追加し、エントリーチャンスを逃さないことで、プロフィットファクターを1.21から1.85まで引き上げることができました。
このように、単ポジ型と複数保有型は一見大きな違いはないように思えますが、複数保有型にすることでさまざまなメリットを得ることができます。
注意点
今回のバックテストではスプレッドを固定で行っております。
日本時間早朝の、相場が緩やかになる時間帯は、スプレッドが広がりやすいという特徴があります。
実運用を行うにはスプレッド制限をかけるなど、十分に注意しましょう。
プログラム全文
#property copyright "Copyright(C) 2023, OANDA"
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
input int MAGICMA = 23498721; // マジックナンバー
input double Lots =0.01; // 1ロット十万通貨単位
input int Slippage = 4; // エントリー見送りスリッページ
input double MaxSpread = 5; // エントリー見送りスプレッド
input double TakeProfit = 10.0; // 利益確定幅(pips)
input double LossCut = 20.0; // 損切確定幅(pips)
input int RSIPeriod=6; // 期間
input ENUM_APPLIED_PRICE RSIAppliedPrice = PRICE_CLOSE; // 適用価格
input int UpLine = 85; // 上の線
input int DownLine = 25; // 下の線
input int TradeTime = 0; // トレードを行う時間
input int MaxPositions = 5; // 最大保有ポジション数
double dSpread;
int OnInit()
{
return(INIT_SUCCEEDED);
}
void OnTick()
{
dSpread = (Ask - Bid) / (Point * 10);
if(CalculateCurrentOrders() < MaxPositions && dSpread < MaxSpread && Volume[0] == 1) CheckForOpen();
}
void CheckForOpen()
{
int res;
double RSI = iRSI(Symbol(), 0, RSIPeriod, RSIAppliedPrice, 1);
if(TradeTime == TimeHour(Time[1]))
{
if(RSI < DownLine)
{
res=OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, Bid - LossCut * Point * 10, Ask + TakeProfit * Point * 10,"", MAGICMA, 0, Red);
}
if(RSI > UpLine)
{
res=OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, Ask + LossCut * Point * 10, Bid - TakeProfit * Point * 10, "", MAGICMA, 0, Blue);
}
}
}
int CalculateCurrentOrders()
{
int positions = 0;
for(int i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
{
positions++;
}
}
return positions;
}
EA(自動売買)を学びたい方へオススメコンテンツ
OANDAではEA(自動売買)を稼働するプラットフォームMT4/MT5の基本的な使い方について、画像や動画付きで詳しく解説しています。MT4/MT5のインストールからEAの設定方法までを詳しく解説しているので、初心者の方でもスムーズにEA運用を始めることが可能です。またOANDAの口座をお持ちであれば、独自開発したオリジナルインジケーターを無料で利用することもできます。EA運用をお考えであれば、ぜひ口座開設をご検討ください。
本ホームページに掲載されている事項は、投資判断の参考となる情報の提供を目的としたものであり、投資の勧誘を目的としたものではありません。投資方針、投資タイミング等は、ご自身の責任において判断してください。本サービスの情報に基づいて行った取引のいかなる損失についても、当社は一切の責を負いかねますのでご了承ください。また、当社は、当該情報の正確性および完全性を保証または約束するものでなく、今後、予告なしに内容を変更または廃止する場合があります。なお、当該情報の欠落・誤謬等につきましてもその責を負いかねますのでご了承ください。