ナンピンマーチンEAのロジックにおいて、ナンピン幅やマーチン倍率の設定も重要ですが、含み益が生じた時にどのタイミングで利確するか(どれくらいまで利益を伸ばすか)という点もポイントです。
利確幅を小さくすればするほど、利確タイミングは早くなりポジションを抱えすぎるリスクから解放されますが、1回あたりの利益額が小さくなるため、利益をコツコツ貯めていく度合いが高まります。
逆に、利確幅を大きくすれば、1回あたりの利益額は大きくなりますが、利確しづらくなってポジションを抱えすぎるリスクが高まります。
この記事では、ナンピンマーチンEAの利確幅を設定する方法についてご紹介します。
EAのベースモデル
ここでは、以下の記事で作成したEAを「ベースモデル」と呼んで、機能追加を行なっていきます。
最も単純なナンピンマーチンEAをゼロから作成する記事になっていますので、まだご覧になっていない方は是非一度ご確認ください。
Inputの設定
ベースモデルでは、以下のインプット項目を設定していました。
input double first_lot = 0.01;//初期ロット
input double nanpin_range = 200;//ナンピン幅
input double profit_target = 143;//利益目標
input int magic_number = 10001; //マジックナンバー
static int ticket_number;//チケットナンバー
double slippage = 10;//スリッページ
ここにさらに、利確パターン用のインプット項目を追加します。
input int close_type = 1;//利確パターン(1:ポジション比例、2:lot比例、3:常に固定)
利確パターン(close_type)
クローズ判定をどのようにするかという設定を使い分けるための変数を設定しておきます。
ここでは、
- ポジション比例
- lot比例
- 常に固定
の3パターンを選択出来るように設定しました。
ループ処理
事前に必要は追加処理が終わり、ここからループ処理の中の機能追加に入ります。
void OnTick()
void OnTick()
{
これ以降は、void OnTick()の中に追加記載していく内容になります。
変数の定義
ベースモデルでは、以下の変数を定義していました。
int cnt;
int current_buy_position;//最新のbuyポジション
int current_sell_position;//最新のsellポジション
int buy_position;//buyポジション数
int sell_position;//sellポジション数
double buy_profit;//buyポジションの含み損益
double sell_profit;//sellポジションの含み損益
ここに、以下の2つの定義を追加します。
double buy_lot;//buy_lot数合計
double sell_lot;//sell_lot数合計
buy_lot、sell_lot
buy_lotは、保有しているbuyポジションのlot数合計を記録しておく変数です。例えば、buyポジションを3つ持っている状況であれば、1〜3つ目のbuyポジションのlot数合計を意味します。sell_lotも同様です。
ポジションの確認
ポジションを確認する処理の中で、lot数合計の確認も行うようにします。
機能追加前
ベースモデルでは、以下の記載でした。
buy_position=0;//buyポジション数の初期化
sell_position=0;//sellポジション数の初期化
current_buy_position=-1;//最新buyポジションの初期化
current_sell_position=-1;//最新sellポジションの初期化
for(cnt=0;cnt<OrdersTotal();cnt++)//ポジションの確認
{
if(OrderSelect(cnt,SELECT_BY_POS)==false)continue;
if(OrderMagicNumber()!=magic_number)continue;
if(OrderType()==OP_BUY)
{
current_buy_position=cnt;
buy_position+=1;
buy_profit=buy_profit+OrderProfit();
};//buyポジションの確認
if(OrderType()==OP_SELL)
{
current_sell_position=cnt;
sell_position+=1;
sell_profit=sell_profit+OrderProfit();
};//sellポジションの確認
}
機能追加後
これを、以下のように変更します。(「←今回追加」という行が、追加箇所です。)
buy_position=0;//buyポジション数の初期化
sell_position=0;//sellポジション数の初期化
current_buy_position=-1;//最新buyポジションの初期化
current_sell_position=-1;//最新sellポジションの初期化
buy_lot=0;//buyポジションのlot数合計の初期化 ←今回追加
sell_lot=0;//sellポジションのlot数合計の初期化 ←今回追加
for(cnt=0;cnt<OrdersTotal();cnt++)//ポジションの確認
{
if(OrderSelect(cnt,SELECT_BY_POS)==false)continue;
if(OrderMagicNumber()!=magic_number)continue;
if(OrderType()==OP_BUY)
{
current_buy_position=cnt;
buy_position+=1;
buy_profit=buy_profit+OrderProfit();
buy_lot=buy_lot+OrderLots(); //←今回追加
};//buyポジションの確認
if(OrderType()==OP_SELL)
{
current_sell_position=cnt;
sell_position+=1;
sell_profit=sell_profit+OrderProfit();
sell_lot=sell_lot+OrderLots(); //←今回追加
};//sellポジションの確認
}
追加箇所の中身を簡単に解説しておくと、全てのポジションを順番に確認していき、
buyポジションだったら、buy_lotに最新のbuyポジションのlot数を加える。
sellポジションだったら、sell_lotに最新のsellポジションのlot数を加える。
というような処理を行なっています。こうして、それぞれのポジションのlot数合計が記録できます。
ポジションクローズ注文
そして、ポジションクローズ注文における機能追加です。
機能追加前
ベースモデルでは、以下のような記載でした。
if(buy_position>0&&buy_profit>profit_target*buy_position)
{
buyClose(Green);//すべてbuyポジションを決済
}
if(sell_position>0&&sell_profit>profit_target*sell_position)
{
sellClose(Yellow);//すべてsellポジションを決済
}
ポジションクローズ条件
ポジション比例
ベースモデルにおける以下の記載部分がクローズ条件に当たります。
if(buy_position>0&&buy_profit>profit_target*buy_position)
この条件は、以下の2つを同時に満たした場合です。
- buyポジションを1つ以上持っている
- 含み益合計が、利益目標×buyポジション数を上回っている
具体的には、例えばbuyポジション数が3だった場合、利益目標(profit_target)を143円と設定していれば、143円の3倍である429円をbuyポジションの含み益合計が上回った場合にクローズ注文を行います。
lot比例
利確パターンを、ポジション数ではなくlot比例に変えてみます。
if(buy_position>0&&buy_profit>profit_target*buy_lot/first_lot)
この条件は、以下の2つを同時に満たした場合です。
- buyポジションを1つ以上持っている
- 含み益合計が、利益目標×buyポジションのlot数合計÷初期lot数を上回っている
具体的には、例えばbuyポジションが0.01lot、0.02lot、0.03lotの3つ(合計0.06lot)だった場合、利益目標(profit_target)を143円と設定していれば、143円の6倍である858円をbuyポジションの含み益合計が上回った場合にクローズ注文を行います。ポジション数比例よりも利益を追求するタイプの利確パターンです。
常に固定
もちろん、利確目標を常に固定というようなパターンも可能です。
if(buy_position>0&&buy_profit>profit_target)
この条件は、以下の2つを同時に満たした場合です。
- buyポジションを1つ以上持っている
- 含み益合計が、利益目標を上回っている
具体的には、例えばbuyポジション3つ持っていても、5つ持っていても、利益目標(profit_target)を143円と設定していれば、buyポジションの含み益合計が143円を上回った場合にクローズ注文を行います。どれだけポジションを積み重ねていても、常に一定の利益を目指すという保守的な手法になります。その分、利益は伸びません。
機能追加後
追加後は、close_typeの条件を加えて、以下のようになります。
if(buy_position>0&&buy_profit>profit_target*buy_position&&close_type==1) //ポジション比例
{
buyClose(Red);//すべてbuyポジションを決済
}
if(buy_position>0&&buy_profit>profit_target*buy_lot/first_lot&&close_type==2) //lot比例
{
buyClose(Red);//すべてbuyポジションを決済
}
if(buy_position>0&&buy_profit>profit_target&&close_type==3) //常に固定
{
buyClose(Red);//すべてbuyポジションを決済
}
if(sell_position>0&&sell_profit>profit_target*sell_position&&close_type==1) //ポジション比例
{
sellClose(Blue);//すべてsellポジションを決済
}
if(sell_position>0&&sell_profit>profit_target*sell_lot/first_lot&&close_type==2) //lot比例
{
sellClose(Blue);//すべてsellポジションを決済
}
if(sell_position>0&&sell_profit>profit_target&&close_type==3) //常に固定
{
sellClose(Blue);//すべてsellポジションを決済
}
まとめ
以上で、利確パターンの変更機能追加は完了です。
EAの動かし方、パラメーター設定等
実際に動かす方法、パラメーター設定等は以下の記事を参考にしてください。
その他のEA作成解説記事
取引時間制限、強制クローズ機能を追加
ココモ法の導入、マーチン倍率の変更など
Pythonで作るFX自動売買ツール(bot)
PythonでFX自動売買ツール(bot)を作成する方法もご紹介しています。