トレール機能について

2024/10/02 08:33
321

開発依頼若しくはソースコードをご教授いただければ幸いです。

トレール機能の例えば30PIPS以上含み益がでれば、
トレール機能を開始する。
トレール機能はその後30PIPS含み益が出るごとに損切り30PIPSずつ上昇する。
つまり、60PIPS含み益が出た時の損切は30PIPSという形の?pips上昇すれば、?トレール幅を設定し、段階的に上昇していくトレール機能は作成できないでしょうか?

よろしくお願いいたします。

コメント

GogoJungle
2024/10/08 09:40

こちらの画像のように、階段状にSLを上げていくということですね。(両軸の単位はpipsです。)

LABO_1943_1.png

修正方法を提案いたします。

準備

オプションの「トレーリングストップ(固定幅)」にチェックを付け、「間隔」にお好みの値を入力した状態で、mq4ファイルをダウンロードします。

LABO_1943_2.png

関数の変更

ソースコード内のTrailingStopという関数の定義を探し、次のように書き換えます。

void TrailingStop(double ts_value, int magic)
{
  for(int i = OrdersTotal() - 1; i >= 0; i--) {
    if(!OrderSelect(i, SELECT_BY_POS) || OrderSymbol() != Symbol() || OrderMagicNumber() != magic) continue;

    double sl = 0;
    double profit_pips = 0;
    
    if(OrderType() == OP_BUY) {
      profit_pips = PriceToPips(Bid - OrderOpenPrice());
      sl = OrderOpenPrice() + PipsToPrice(MathFloor(profit_pips / ts_value) * ts_value);
      if(sl > OrderOpenPrice() && sl > OrderStopLoss()) {
        setTPSL(0, sl, OrderTicket());
      }
    } 
    else if(OrderType() == OP_SELL) {
      profit_pips = PriceToPips(OrderOpenPrice() - Ask);
      sl = OrderOpenPrice() - PipsToPrice(MathFloor(profit_pips / ts_value) * ts_value);
      if(sl < OrderOpenPrice() && (sl < OrderStopLoss() || OrderStopLoss() == 0)) {
        setTPSL(0, sl, OrderTicket());
      }
    }
  }
}

以上でございます。
なお、上記のコードあくまでヒントとなっております。
細かい検証は行っておりませんので、修正される場合は十分な検証をお願いいたします。
ご参考になれば幸いです。

YAMA
2024/10/04 04:03

参考にさせていただきます。
ありがとうございます。

YAMA
2024/10/05 02:48

いつもお世話になっております。
追加での質問になり、申し訳ございません。
MQ4及びMQ5でコンパイルしたところ、どちらもコンパイルエラーとなりました。

MQ5で検証を行いたいのですが、MT5では、実装不可なのでしょうか?

添付写真はMT5でのコンパイルエラーの写真になります
![スクリーンショット 2024-10-05 2.18.48.png](スクリーンショット 2024-10-05 2.18.48.png)
![スクリーンショット 2024-10-05 2.28.29.png](スクリーンショット 2024-10-05 2.28.29.png)
何卒よろしくお願いいたします。

GogoJungle
2024/10/07 16:03

大変失礼いたしました。
本サイトの仕組みの関係で、不等号「>」「<」が&gt;,&lt;という文字列に置き換わってしまっておりました。
お手数ですが、こちらの画像を参考に、&gt;を「>」に、&lt;を「<」に、それぞれ置き換えていただけますと幸いです。

LABO_1943_3.png

YAMA
2024/10/08 17:29

追加での質問よろしいでしょうか。
ご教授頂いた、コードを試しましたが、思った通りのSLの動きではありませんでした。。

大変恐縮ですが、もう一度ご教授頂きたいです。

1 エントリー値を起点として、含みpipsが X発生すれば エントリー値+1/2X にSLを移動したいです。
 例)USD/JPY
  100.000を起点として、含みpipsが600 発生すれば 100.000+300 にSL持ってきたいです。
(エントリー値)         (X)   (エントリー値)+(1/2Ⅹ) 
                  900 発生すれば、100.000+600 にSLを階段状に続けていく。
 なお、100.000から300上昇した際は、建値機能を使うつもりです。(一段階目)
 可能でしょうか?

2 また、ストレージテスターのビジュアルモードでは、  
 階段的なトレールを行っていることは、目視できないのでしょうか?

恐縮ですが、ご回答よろしくお願いいたします。

GogoJungle
2024/10/09 09:47

1つ目のご質問につきまして

計算式が

エントリー値+1/2X

の場合、例示していただいたX=900の場合は100.000+450になることと存じますが、100.000+600でお間違いないでしょうか?

1/2Xではありませんが、下記グラフのように「利益が60pipsの際にSLが(エントリー値)+30pips」になるように修正したコードを作成いたしました。

LABO_1943_4.png

void TrailingStop(double ts_value, int magic)
{
  for(int i = OrdersTotal() - 1; i >= 0; i--) {
    if(!OrderSelect(i, SELECT_BY_POS) || OrderSymbol() != Symbol() || OrderMagicNumber() != magic) continue;

    double sl = 0;
    double profit_pips = 0;
    
    if(OrderType() == OP_BUY) {
      profit_pips = PriceToPips(Bid - OrderOpenPrice());
      sl = OrderOpenPrice() + PipsToPrice(MathMax(MathFloor(profit_pips / ts_value) * ts_value - ts_value, 0));
      if(sl > OrderOpenPrice() && sl > OrderStopLoss()) {
        setTPSL(0, sl, OrderTicket());
      }
    } 
    else if(OrderType() == OP_SELL) {
      profit_pips = PriceToPips(OrderOpenPrice() - Ask);
      sl = OrderOpenPrice() - PipsToPrice(MathMax(MathFloor(profit_pips / ts_value) * ts_value - ts_value, 0));
      if(sl < OrderOpenPrice() && (sl < OrderStopLoss() || OrderStopLoss() == 0)) {
        setTPSL(0, sl, OrderTicket());
      }
    }
  }
}

2つ目のご質問につきまして

可能でございます。
ビジュアルモードで実行すると、SLの水平線が、段階的に上がっていく様子が確認できることと存じます。

LABO_1943_5.png

YAMA
2024/11/06 18:19

コードありがとうございました。

教えていただいたコードについて、具体例を用いて詳しく説明いただいてもいいですか??

void TrailingStop(double ts_value, int magic)
{
for(int i = OrdersTotal() - 1; i >= 0; i–) {
if(!OrderSelect(i, SELECT_BY_POS) || OrderSymbol() != Symbol() || OrderMagicNumber() != magic) continue;

double sl = 0;
double profit_pips = 0;

if(OrderType() == OP_BUY) {
  profit_pips = PriceToPips(Bid - OrderOpenPrice());
  sl = OrderOpenPrice() + PipsToPrice(MathMax(MathFloor(profit_pips / ts_value) * ts_value - ts_value, 0));
  if(sl &gt; OrderOpenPrice() && sl &gt; OrderStopLoss()) {
    setTPSL(0, sl, OrderTicket());
  }
} 
else if(OrderType() == OP_SELL) {
  profit_pips = PriceToPips(OrderOpenPrice() - Ask);
  sl = OrderOpenPrice() - PipsToPrice(MathMax(MathFloor(profit_pips / ts_value) * ts_value - ts_value, 0));
  if(sl &lt; OrderOpenPrice() && (sl &lt; OrderStopLoss() || OrderStopLoss() == 0)) {
    setTPSL(0, sl, OrderTicket());
  }
}

}
}

GogoJungle
2024/11/08 09:37

コードにコメントを付けてみました。
ご理解の手助けになれば幸いでございます。

void TrailingStop(double ts_value, int magic) // ts_valueはトレーリングストップ幅。「30pips毎」なら「30」となります。
{
  for(int i = OrdersTotal() - 1; i &gt;= 0; i--) { // すべてのオーダーをについて、最新のものから順に処理します。
    if(!OrderSelect(i, SELECT_BY_POS) || OrderSymbol() != Symbol() || OrderMagicNumber() != magic) continue; // オーダーが存在しない、通貨ペアが異なる、またはマジックナンバーが異なる場合は、これより下の処理をスキップします。

    double sl = 0; // ストップロスの値を格納する変数です。0で初期化しておきます。
    double profit_pips = 0; // 利益をpipsで格納する変数です。0で初期化しておきます。
    
    if(OrderType() == OP_BUY) { // 買い注文の場合の処理です。
      profit_pips = PriceToPips(Bid - OrderOpenPrice()); // 利益をpipsで計算します。買値から現在値を引いた値が利益となります。
      sl = OrderOpenPrice() + PipsToPrice(MathMax(MathFloor(profit_pips / ts_value) * ts_value - ts_value, 0)); // トレーリングストップの値を計算します。MathFloorは小数点以下を切り捨てる関数です。例えば、profit_pipsが「61」でts_valueが「30」の場合、MathFloor(61 / 30) = 2となり、SLは2 * 30 - 30 = 30(pips)となります。切り捨てを行う関数を用いることで、段階的なトレーリングストップが実現できるわけです。
      if(sl &gt; OrderOpenPrice() && sl &gt; OrderStopLoss()) { // トレーリングストップがOpenPriceよりも大きく、かつ、既存のストップロスよりも大きい場合のみ、ストップロスを更新します。
        setTPSL(0, sl, OrderTicket()); // トレーリングストップを更新します。
      }
    } 
    else if(OrderType() == OP_SELL) { // 売り注文の場合の処理です。
      profit_pips = PriceToPips(OrderOpenPrice() - Ask); // 利益をpipsで計算します。売値から現在値を引いた値が利益となります。
      sl = OrderOpenPrice() - PipsToPrice(MathMax(MathFloor(profit_pips / ts_value) * ts_value - ts_value, 0)); // トレーリングストップの値を計算します。買い注文の場合と同様に、切り捨てを行うことで段階的なトレーリングストップが実現できます。符号が逆になることに注意してください。
      if(sl &lt; OrderOpenPrice() && (sl &lt; OrderStopLoss() || OrderStopLoss() == 0)) { // トレーリングストップがOpenPriceよりも小さく、かつ、既存のストップロスよりも小さい場合のみ、ストップロスを更新します。
        setTPSL(0, sl, OrderTicket()); // トレーリングストップを更新します。
      }
    }
  }
}
yusuke
2024/12/15 13:07

大変恐れ入りますが、横から失礼します。

上記のコードは±0pipsの状態から同じ値幅分だけ段階的にストップの位置を引き上げていくもの(もしくは引き下げていくもの)だと思うのですが、例えば30pips以上含み益が出てからトレールを開始し、以後5pips含み益が増える毎に5pipsずつストップを引き上げる(もしくは引き下げる)ということをしたいです。

トレーリングストップ機能のinput変数で数字を入力するのは今のところTrailinStopNormalValueのみですが、もう1つトレール開始の起点のinput変数を追加した場合に上記コードをどのように修正すればいいかご教示頂けると助かります。

GogoJungle
2024/12/17 17:07
含み益が30pipsに満たない場合は何もしない
↓
30pipsに達したら5pipsのSLを設定する
↓
35pipsに達したら10pipsのSLを設定する
↓
40pipsに達したら15pipsのSLを設定する
↓
・
・
・

という条件ですね。
下記を参考に、コードの修正をお試しください。

変数の定義

トレーリングストップを開始する際の含み益を指定するために、新しい変数TrailinStopStartValueを用意します。
TrailinStopNormalValueはこれまで通り、トレイリングストップの間隔(今回の例では5pips)として使用します。

※本来はTrailingStopなのですが、出力されるコードに合わせて"g"のないTrailinStopとしている点にご注意ください。

【修正前】

input bool isTrailingStop = true;
input double TrailinStopNormalValue = 5;

【修正後】

input bool isTrailingStop = true;
input double TrailinStopStartValue = 30;
input double TrailinStopNormalValue = 5;

関数の呼び出し

関数を呼び出す行を修正し、先程追加した変数を渡してあげます。

【修正前】

   if(isTrailingStop == true) TrailingStop(TrailinStopNormalValue, Magic1);

【修正後】

   if(isTrailingStop == true) TrailingStop(TrailinStopStartValue, TrailinStopNormalValue, Magic1);

関数の定義

TrailingStop関数を次のように書き換えます。

【修正後】

void TrailingStop(double ts_start, double ts_value, int magic)
{
  for(int i = OrdersTotal() - 1; i &gt;= 0; i--) {
    if(!OrderSelect(i, SELECT_BY_POS) || OrderSymbol() != Symbol() || OrderMagicNumber() != magic) continue;

    double sl = 0;
    double profit_pips = 0;
    
    if(OrderType() == OP_BUY) {
      profit_pips = PriceToPips(Bid - OrderOpenPrice());
      sl = OrderOpenPrice() + PipsToPrice(MathMax(MathFloor((profit_pips - ts_start) / ts_value + 2.0) * ts_value - ts_value, 0));
      if(sl &gt; OrderOpenPrice() && sl &gt; OrderStopLoss()) {
        setTPSL(0, sl, OrderTicket());
      }
    } 
    else if(OrderType() == OP_SELL) {
      profit_pips = PriceToPips(OrderOpenPrice() - Ask);
      sl = OrderOpenPrice() - PipsToPrice(MathMax(MathFloor((profit_pips - ts_start) / ts_value + 2.0) * ts_value - ts_value, 0));
      if(sl &lt; OrderOpenPrice() && (sl &lt; OrderStopLoss() || OrderStopLoss() == 0)) {
        setTPSL(0, sl, OrderTicket());
      }
    }
  }
}

以上でございます。
ご参考になりましたら幸いでございます。

yusuke
2024/12/18 13:49

ご丁寧にご回答ありがとうございます。
バックテストでも動作を確認できました。活用させて頂きます。

関連トピックス

検索結果がありません。

ノーコードで誰でも簡単EA開発!MQL言語学習にも使える! | GogoJungle

注目トピックス

検索結果がありません。