どうも潤奈です( ゚Д゚)
今回はトレーリングストップの動作をさせる為のオリジナル関数を紹介します。
オリジナル関数って?という方はこちらのEA講座でオリジナル関数の説明をしていますので覗いてみて下さい( ゚Д゚)
コード全文
トレーリングストップで使用している変数は以下の4つです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//パラメーター設定 input int MagicNumber=20230215; //注文元を識別する番号 input double TrailingPips=10; //トレーリング幅(pips) //グローバル変数 double Pips; //pointからpipsに変換する値格納 double StopL; //ストップレベル値格納 //+-------------------------------------------------------------------------------------------------------------------------------------------------------------+ int OnInit() { Pips=AdjustPoint(_Symbol); StopL=MarketInfo(_Symbol,MODE_STOPLEVEL)*_Point; return(INIT_SUCCEEDED); } |
トレーリングストップのコードは以下の通りです。
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 TrailingStop(){ double TSP; bool res=true; for(int i=OrdersTotal()-1;i>=0;i--){ if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))continue; if(OrderMagicNumber()!=MagicNumber)continue; if(OrderSymbol()!=_Symbol)continue; if(OrderType()==OP_BUY){ TSP=Bid-TrailingPips*Pips; if(OrderOpenPrice()<TSP && OrderStopLoss()+_Point*0.5<TSP && StopL<Bid-TSP){ res=OrderModify(OrderTicket(),OrderOpenPrice(),TSP,0,0,clrYellow); } }else if(OrderType()==OP_SELL){ TSP=Ask+TrailingPips*Pips; if((OrderOpenPrice()>TSP && OrderStopLoss()-_Point*0.5>TSP && StopL<TSP-Ask) || (OrderStopLoss()==0 && StopL<TSP-Ask)){ res=OrderModify(OrderTicket(),OrderOpenPrice(),TSP,0,0,clrYellow); } } if(!res)Print("OrderModify ErrorCode: "+(string)GetLastError()); } } |
コード説明
使用する変数の用意
まず以下2つはEAのパラメーター設定の時に設定をして下さい。
1 2 3 |
//パラメーター設定 input int MagicNumber=20230215; //注文元を識別する番号 input double TrailingPips=10; //トレーリング幅(pips) |
次にグローバル変数として宣言します。グローバル変数とは関数の外で宣言している変数の事を言い、プログラム全体で使用できるようになります。
1 2 3 |
//グローバル変数 double Pips; //pointからpipsに変換する値格納 double StopL; //ストップレベル値格納 |
このままでは値が入っていないので、OnInit()関数内で必要な値を入れておきます。
1 2 3 4 5 6 7 |
int OnInit() { Pips=AdjustPoint(_Symbol); StopL=MarketInfo(_Symbol,MODE_STOPLEVEL)*_Point; return(INIT_SUCCEEDED); } |
AdjustPoint()関数は冒頭の「オリジナル関数とは?」の記事に記述があるのでそちらを参照してください。
StopL変数に入れている数値は、各FX業者や通貨ペアによって決められている「指値や逆指値注文を行う際に、最低限現在の価格から離れていなければいけない価格差」のことです。
これはストップロス値を変更する際に、現在価格に近すぎるとエラーが連発するのを防ぐために使用します。
トレーリングストップ本文の説明
1 2 3 4 |
//トレーリングストップ void TrailingStop(){ } |
まずvoid型のTrailingStop関数を宣言します。
1 2 |
double TSP; bool res=true; |
次にトレーリングストップ値を入れるTSP変数をdouble型で宣言し、注文変更を指示するOrderModify()関数の戻り値を入れるres変数をtrue(真)で宣言します。
1 2 3 4 5 |
for(int i=OrdersTotal()-1;i>=0;i--){ //ここに次のコードを記述 } |
for文で現在保持している総ポジション数をループ処理で、該当するポジションを探します。
1 2 3 |
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))continue; if(OrderMagicNumber()!=MagicNumber)continue; if(OrderSymbol()!=_Symbol)continue; |
for文の中にこのコードを記述します。上から、if文で確認して問題があれば下の処理をスキップして次のループ処理へ進みます(continue)。
1行目は、正しくポジションを取得出来なかったら→次のポジションへ
2行目は、対象のマジックナンバーでなければ→次のポジションへ
3行目は、対象の通貨ペアでなければ→次のポジションへ
この3つの条件をクリアして、取得出来たポジションで、対象のマジックナンバーで、対象の通貨ペアのポジションのみ下のコードへ進めます。
1 2 3 4 5 6 7 8 9 10 |
if(OrderType()==OP_BUY){ //買いのトレーリングストップ }else if(OrderType()==OP_SELL){ //売りのトレーリングストップ } |
if文とelse if文で買いか売りのポジションか判断してトレーリングストップの計算を行います。
1 2 |
//買いのトレーリングストップ TSP=Bid-TrailingPips*Pips; |
売値からトレーリングストップ値を引いた価格をTSP変数に入れます。
1 2 3 4 5 |
if(OrderOpenPrice()<TSP && OrderStopLoss()+_Point*0.5<TSP && StopL<Bid-TSP){ //注文変更指示 } |
3つの条件をif文で確認します。
①OrderOpenPrice()<TSP:エントリー価格よりトレーリングストップ値が上にあるか
②OrderStopLoss()+_Point*0.5<TSP:現在のストップロス値よりトレーリングストップ値が更新されたか
③StopL<Bid-TSP:トレーリングストップ値がストップレベル値より売値から離れているか
1 2 |
//注文変更指示 res=OrderModify(OrderTicket(),OrderOpenPrice(),TSP,0,0,clrYellow); |
OrderModify()関数には戻り値は処理が成功した場合はtrueで、失敗した場合はfalseを返します。
次は売りの説明です。
1 2 |
//売りのストーリングストップ TSP=Ask+TrailingPips*Pips; |
買値からトレーリングストップ値を足した価格をTSP変数に入れます。
1 2 3 4 5 6 |
if((OrderOpenPrice()>TSP && OrderStopLoss()-_Point*0.5>TSP && StopL<TSP-Ask) || (OrderStopLoss()==0 && StopL<TSP-Ask)){ //注文変更指示 } |
売りの方は3つの条件ともしくは、2つの条件をif文で確認します。
①OrderOpenPrice()>TSP:エントリー価格よりトレーリングストップ値が下にあるか
②OrderStopLoss()-_Point*0.5>TSP:現在のストップロス値よりトレーリングストップ値が更新されたか
③StopL<TSP-Ask:トレーリングストップ値がストップレベル値より買値から離れているか
もしくは、
④OrderStopLoss()==0:ストップロス値を0に設定している
⑤StopL<TSP-Ask:これは③と同じ条件です
何故買いと条件が違うのかというと、条件②でOrderStopLoss()が0だと、TSP値より大きくなる事がないので、ストップロス値が0の時に注文変更が出来る条件を追加しています。
1 2 |
//注文変更指示 res=OrderModify(OrderTicket(),OrderOpenPrice(),TSP,0,0,clrYellow); |
OrderModify()関数には戻り値は処理が成功した場合はtrueで、失敗した場合はfalseを返します。
1 |
if(!res)Print("OrderModify ErrorCode: "+(string)GetLastError()); |
res変数がfalseの場合は、失敗したという事なのでif文でGetLastError()でエラーコードを取得してPrint関数でプリントさせます。
まとめ
いかがでしたでしょうか。
恐らく一番スタンダードなトレーリングストップのコードになります。
エラー回避の為にちょっと複雑になっていますが、必要なものだと思います。
あ、使う時はメインロジックのどこかにTrailingStop(); と記述して使用して下さい。
では、少しでも参考になれば( ゚Д゚)
コメント