朝スキャEAに複利機能を実装するカスタマイズ【コピペで使用可能】
前回の記事では、単純な時間制限と逆張りのロジックに対して、ナンピンを実装することでどのような影響が出るのかを試しました。
今回の記事では、複利機能を実装することで、バックテストの結果がどのように変化するのかを確認していきましょう。
複利機能とは、トレードで得た収益を元本にプラスして、再びトレードを行う投資手法のことです。
複利機能のメリットとデメリット
まずは複利機能のメリットとデメリットについて紹介します。
<メリット>
複利機能の一番のメリットは、指数関数的に資金を伸ばせる点です。
資金が増加するにつれてロット数も増加するため、時間が経つほどより大きな収益を期待できます。
その他のメリットとして、証拠金に合わせてロット数が自動で計算されるので、自身でロット数を管理する必要がないというメリットがあります。
<デメリット>
複利機能のデメリットは、リスクが変わらないという点です。
固定ロットでのトレードの場合、資金が増えるにつれ破綻するリスクが減少します。
しかし、複利機能を使用すると、証拠金に合わせてロット数も上がるので、常に一定のリスクが伴います。
仕様
前回作成したEAの仕様をまとめます。
エントリー
時間が日本時間早朝かつRSIが売られすぎラインを下回ったら、買いエントリー
時間が日本時間早朝かつRSIが買われすぎラインを上回ったら、売りエントリー
決済
利確価格と損切り価格による決済
その他
著作権を「OANDA」に設定
スリッページ、スプレッドによってエントリーを制限する
ポジションは同時に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 UseMM = true; //複利(ON/OFF)
input double MMRisk = 2.0; //複利リスクパーセント
前回のパラメータに「複利(ON/OFF)」と「複利リスクパーセント」というパラメータを追加します。
「複利(ON/OFF)」はその名の通り、複利機能を使用するかどうかを設定する項目です。
「複利リスクパーセント」について、ロット数の計算は「余剰証拠金の〇リスクパーセントの金額でエントリーできるギリギリのロット数」でエントリーをするようにします。
例えば余剰証拠金が100万円、パラメータの「複利リスクパーセント」が2パーセントの時は、2万円でエントリーできるロット数が自動でセットされます(最大レバレッジも考慮されます)。
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, UseMM ? GetMMLots() : Lots, Ask, Slippage, Bid - LossCut * Point * 10, Ask + TakeProfit * Point * 10,"", MAGICMA, 0, Red);
}
if(RSI > UpLine)
{
res=OrderSend(Symbol(), OP_SELL, UseMM ? GetMMLots() : Lots, Bid, Slippage, Ask + LossCut * Point * 10, Bid - TakeProfit * Point * 10, "", MAGICMA, 0, Blue);
}
}
}
OrderSend関数のロット数を指定する第3引数のみを変更しています。
意味としては「複利機能を利用する場合はGetMMLots関数の値を、複利機能を利用しない場合はパラメータのロット数をセットする」ようにしています。
GetMMLots関数は、複利機能によってロット数を計算する関数で、この後に解説します。
GetMMLots関数
double GetMMLots(){
double MMLot;
double MinLots = MarketInfo(Symbol(), MODE_MINLOT); //①
double MaxLots = MarketInfo(Symbol(), MODE_MAXLOT); //②
double MMargin;
MMargin = AccountFreeMargin() * MMRisk * 0.01; //③
MMLot = MathFloor(MMargin / MarketInfo(Symbol(), MODE_MARGINREQUIRED) / MinLots) * MinLots; //④
if(MMLot == 0)MMLot = MinLots; //⑤
if(MMLot > MaxLots)MMLot = MaxLots; //⑥
return MMLot; //⑦
}
- ① 変数MinLotsに、現在利用している証券会社がエントリー可能な最小ロット数を格納します。
- ② 変数MaxLotsに、現在利用している証券会社がエントリー可能な最大ロット数を格納します。
- ③ 変数MMMatginに、余剰証拠金にリスクパーセントをかけた値を格納します。
AccountFreeMargin関数は、現在の余剰証拠金を取得できる関数です。 - ④ MarketInfo(Symbol(), MODE_MARGINREQUIRED)関数は、1ロットあたりの余剰証拠金を取得できる関数です。
この値を利用して③で計算した値をもとにロット数を計算し、変数MMLotに格納します。 - ⑤ 計算した値MMLotが0になった場合、エントリー可能な最小ロット数がセットされます。
- ⑥ 計算した値MMLotがMaxLotsよりも大きい場合、MMLotにMaxLotsがセットされます。
- ⑦ 最後に計算したMMLotをreturnで返します。
バックテスト
今回作成したマーチンゲールのEAと、前回作成した単ポジ型のEAのバックテスト結果を比較してみましょう。
条件は以下の通りです。
- 通貨ペア:GBPUSD
- 時間足:5分足
- 期間:2018年1月1日~2023年1月1日の5年間
- スプレッド:15固定
単ポジ型
複利機能のEA
画面下部のグラフを見ると、緑色のヒストグラムが表示されています。
こちらはその時のエントリーのロット数を表しています。
時間が経つにつれてロット数が上昇していることが分かります。
最大ドローダウンを見ると、0.20%から21.33%に上昇しいていることが分かります。
これは資金が増えるとともにロット数も増やして、最大ドローダウンが大きくなっていることが原因です。
特筆すべき点はやはり純益でしょう。
ロジックは同じなのに純益が85,411円から1億円とすさまじい差が開いています(そもそも初期証拠金が1000万円あることも影響していますが)。
また、余剰証拠金は証券会社の最大レバレッジにも大きく影響を受け、ご利用の証券会社によってエントリーロット数は大きく変わってきます。
注意点
今回のバックテストは、スプレッドを固定で行っています。
日本時間早朝の相場が緩やかになる時間帯は、スプレッドが広がりやすいという特徴があります。
実運用を行うにはスプレッド制限をかけるなど、十分に注意しましょう。
また、マーチンゲールは自己資金を一瞬で失ってしまうリスクがあるので注意が必要です。
プログラム全文
#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 UseMM = true; //複利(ON/OFF)
input double MMRisk = 2.0; //複利リスクパーセント
double dSpread;
int OnInit()
{
return(INIT_SUCCEEDED);
}
void OnTick()
{
dSpread = (Ask - Bid) / (Point * 10);
if(CalculateCurrentOrders()==0 && dSpread < MaxSpread) 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, UseMM ? GetMMLots() : Lots, Ask, Slippage, Bid - LossCut * Point * 10, Ask + TakeProfit * Point * 10,"", MAGICMA, 0, Red);
}
if(RSI > UpLine)
{
res=OrderSend(Symbol(), OP_SELL, UseMM ? GetMMLots() : 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;
}
double GetMMLots(){
double MMLot;
double MinLots = MarketInfo(Symbol(), MODE_MINLOT);
double MaxLots = MarketInfo(Symbol(), MODE_MAXLOT);
double MMargin;
MMargin = AccountFreeMargin() * MMRisk * 0.01;
MMLot = MathFloor(MMargin / MarketInfo(Symbol(), MODE_MARGINREQUIRED) / MinLots) * MinLots;
if(MMLot == 0)MMLot = MinLots;
if(MMLot > MaxLots)MMLot = MaxLots;
return MMLot;
}
EA(自動売買)を学びたい方へオススメコンテンツ
OANDAではEA(自動売買)を稼働するプラットフォームMT4/MT5の基本的な使い方について、画像や動画付きで詳しく解説しています。MT4/MT5のインストールからEAの設定方法までを詳しく解説しているので、初心者の方でもスムーズにEA運用を始めることが可能です。またOANDAの口座をお持ちであれば、独自開発したオリジナルインジケーターを無料で利用することもできます。EA運用をお考えであれば、ぜひ口座開設をご検討ください。
本ホームページに掲載されている事項は、投資判断の参考となる情報の提供を目的としたものであり、投資の勧誘を目的としたものではありません。投資方針、投資タイミング等は、ご自身の責任において判断してください。本サービスの情報に基づいて行った取引のいかなる損失についても、当社は一切の責を負いかねますのでご了承ください。また、当社は、当該情報の正確性および完全性を保証または約束するものでなく、今後、予告なしに内容を変更または廃止する場合があります。なお、当該情報の欠落・誤謬等につきましてもその責を負いかねますのでご了承ください。