見出し画像

プレゼント企画

いつもnote、Twitter応援ありがとうやで😊
昨日言ってた「今のポジションがミリったらプレゼント企画する」ってのやりますか‼️
まぁ今日も10万から100万勝ったしねwww
第1回はMT5のビットコイン用EAのソースコード
第2回はMacBook Air
そして今回、第3回目は・・・

MT4用EA[ムササビ様3]や‼️

エントリーロジックは指定した本数の平均足が連続したら順張りでエントリー。
ここは初代ムササビ様と一緒やね😊
日足チャートに設定1本なら陽線が出たらチャートが切り替わるタイミングでロングや‼️

決済ロジックはSLとTPを設定出来るようにしてあるのは前作と一緒だけど、トレーリングストップと追撃ロジックを追加してみた🌟

スイングで1番萎えるのは皆んなどんな時???
含み益を大きく取ったのに建値に戻った時とかヤレヤレって感じやない?www
まぁこれはトレーリングストップでもある程度は解消出来るけど、根本的な解決にはなってないとワイは思う。

1番考え方の変えどころは利確の部分やとワイは思う🤔
プラス域にストップロスが置けたら、トレーリングストップが機能しててもその時点で利確扱いで良くね?
そうすれば長いトレンドが発生してたら、次々に利益を確保したポジション積んでいけるっちゅう寸法や😊がはは
まぁピラミッディングを上手にするって感じかな?
どや?面白そうやろ??
これを今回は特別にワイのアカウントをフォロー&この記事をリツイートしてくれた人に全員プレゼントや🎁
ほんまは上手い事煽り散らかして有料販売したら100万くらいは売れる自信あるんだけど出血大サービスやで?



//+------------------------------------------------------------------+
#property strict
#include <stdlib.mqh>
#property description ""

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+ 変更可能箇所はここから
//bool DebugMode = true; //(動作確認用)デバッグ用にインジケーター値等を操作履歴に出力する機能。オンはtrue。オフにする場合はfalse。
bool     FlagAccountNo = false;            //口座縛りを使うか?
int      AllowableAccountNo = 072;   //口座縛りの口座番号。
//
//+------------------------------------------------------------------+ 変更可能箇所はここまで
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
enum enumlotMode {
  fixed = 0,  //固定ロット
  varuable = 1,  //変動ロット
};

// 入力パラメータ宣言
extern string a00001 = "==================";             //※基本の設定※
extern string Memo             = "エントリー時にスプレッドが開いていると収束時にエントリーします。"; //注意事項
extern string COMMENT          = "";                      //オーダーコメント
extern int    Magic0           = 20220725;                //基準マジックナンバー ※内部処理で末尾に何ポジ目かを追加する。
extern int    MaxSpread        = 100;                     //最大スプレッド[point]
extern int    Slippage         = 005;                     //許容スリッページ[point]
int Magic;
//
extern string a00101 = "==================";             //※ロジックの設定※
extern double TPPips           = 100.0;                  //TP[pips]
extern double SLPips           = 100.0;                  //SL[pips]
extern int    HACountReq       = 01;                     //平均足何本が連続したらエントリーするか?
//
extern string a00201 = "==================";             //※ロットの設定※
double StartLots;
extern enumlotMode LotMode     = fixed;                  //ロットモード
extern double StartLotsFixed   = 0.10;                   //固定ロットの場合のロット数
extern double LotVarBC         = 10 * 10000;             //変動ロットの場合の基準有効証拠金
extern double LotVarLot        = 0.10;                   //変動ロットの場合の基準ロット数
//double LotMult          = 1.00;   //マーチン倍率
//
extern string a00301 = "==================";             //※トレールの設定※
extern bool   TrailSwitch      = false;                  //トレールを使うか?
extern double TrailBootPips    = 50.0;                   //トレール開始含み益[pips]
extern double TrailWidthPips   = 30.0;                   //トレール幅[pips]
double TrailBootPrice, TrailWidthPrice;
//
extern string a00401 = "==================";             //※積み増しの設定※
extern int    MaxPosi          = 05;                     //最大ポジ数
extern double NanpinProfitPips = 50.0;                   //保有ポジがこの含み益[pips]以上で積み増し可能。
double NanpinProfitPrice;
//
string Sufex = "";
double TPPrice;          //初期ポジション利確[Price]
double SLPrice;         //追加エントリー幅[Price]
int    DigitsLot;          //ロットの桁数
int    digits;             //価格桁数
double PipsPrice;          //Pipsの価格
int    orderInterval = 300;            //エントリーと決済を複数回試行する場合の間隔ミリ秒の価格
int    orderCloseModTryCountMax = 05;  //決済試行回数の上限
int    orderSendTryCountMax = 1;       //エントリー試行回数の上限
bool   First = true, ReInit = false;

//基本パラ
string EAname = "";        //EA名前。
int    buys = 0, sells = 0;
int    posi;               //ポジ数
bool   ret;
int    i, ii, icount, res;
double entrylot, entrylotMAX, entrylotMIN, entryPrice;
datetime LastOrderErrL = 1, LastOrderErrS = 1, LastErrTime, LastCalTime, LastArertTime;
string DebugText = "";
//ロジックパラ
bool EnFlag = false;

//ポジションパラ
//int CountM = 0; //マーチンカウント
int LastTradeHistryCount = 0, LastTradePoolCount;
string EnTimeHMStr;
double MinProfitPrice;
//インジパラ
int    HACount;
double HAOpen[100], HAClose[100];
int    HAColor = 0;
string HAStr = "", HAStr2 = "";
datetime HALastCalTime;

//+------------------------------------------------------------------+
int OnInit() {
//異常入力値の処理
  {
     if(HACountReq <= 0) HACountReq = 1;
     //string aText = "";
     //if(aText != "") {
     //   MessageBox(aText, "エラー", MB_ICONEXCLAMATION);
     //   return(INIT_FAILED);
     //}
  }
//初期値設定
  {
     EnFlag = false;
     LastTradeHistryCount = OrdersHistoryTotal();
     LastTradePoolCount   = OrdersTotal();
     LastCalTime = 0;
  }
//通貨ペア情報の取得。通貨ペアの数だけforループ
  DebugText = "";
  digits            = Digits();
  if(StringSubstr(_Symbol, 0, 6) == "XAUUSD" || StringSubstr(_Symbol, 0, 6) == "GOLD") PipsPrice         = 0.10;          //ゴールド特例。少数3桁価格の対策。
  else                                                                                 PipsPrice         = 10 * Point();  //通常の通貨ペアは1Pips=10ポイント
  TPPrice        =      NormalizeDouble(PipsPrice * TPPips,         digits);
  SLPrice        =      NormalizeDouble(PipsPrice * SLPips,        digits);
  TrailBootPrice    =      NormalizeDouble(PipsPrice * TrailBootPips,        digits);
  TrailWidthPrice   =      NormalizeDouble(PipsPrice * TrailWidthPips,        digits);
  NanpinProfitPrice =      NormalizeDouble(PipsPrice * NanpinProfitPips,        digits);
  DebugText = "";
//ロットステップからロット桁数の設定
  entrylotMAX = MarketInfo(_Symbol, MODE_MAXLOT);
  entrylotMIN = MarketInfo(_Symbol, MODE_MINLOT);
  double LotStepLog     = MarketInfo(_Symbol, MODE_LOTSTEP);
  DigitsLot = (int)(-MathLog10(LotStepLog));
  if(-MathLog10(LotStepLog) - DigitsLot > 0) DigitsLot++;
//if(DebugMode) DebugText += StringFormat("(%s, %s, %s, %d),", DoubleToString(entrylotMAX, DigitsLot),
//                                           DoubleToString(entrylotMIN, DigitsLot), DoubleToString( LotStepLog, DigitsLot), DigitsLot);
//if(DebugMode) printf("Lot情報取得(Max,Min,Step,DigitLot)=%s", DebugText);
//ロット設定
  entrylot = StartLots;
  entrylot = fmin(entrylotMAX, fmax(entrylot, entrylotMIN));     //上限下限設定
  entrylot = NormalizeDouble( entrylot, DigitsLot);              //桁数設定
//初期化不良の場合に再イニット
  if(PipsPrice == 0 || entrylotMAX == 0 || entrylotMIN == 0 || DigitsLot == 0) ReInit = true;
  CalculateCOrders();
  CalLot();
  Comment(StringFormat("[Lot=%s], 起動日時:%s, 平均足連続本数:%d", DtS2(entrylot), (string)TimeCurrent(), HACountReq));
  First = true;
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
  Comment("");
}
//+------------------------------------------------------------------+
bool AllowableCheck() {
  string text = "";
//縛りとかトレード禁止の警告。足1本毎に警告。
  if( IsTradeAllowed() == false ) text += "自動売買禁止設定になっています。";
  if(FlagAccountNo) if(AllowableAccountNo != AccountNumber()) text += "口座縛り。";
  if(text == "") {
     return(false);
  } else {
     if(LastErrTime != Time[0]) {
        printf(text);
        MessageBox(text, "エラー", MB_ICONEXCLAMATION);
        LastErrTime = Time[0];
     }
     return(true);
  }
}
//+------------------------------------------------------------------+
void OnTick() {
//縛りとかトレード禁止の警告。
  if( AllowableCheck() ) return;
//初期化不良の場合に再イニット
  if(ReInit) {
     OnInit();
     return;
  }
//保有済みのポジション情報の取得。初回起動時と決済済みポジション数か保有中ポジ数が増減した時。
  if(First || LastTradeHistryCount != OrdersHistoryTotal() || LastTradePoolCount != OrdersTotal()) {
     CalculateCOrders();
  }
////決済の処理。
  if(posi > 0) {
     if(TrailSwitch) {
        orderTrailAll();
     }
  }
//エントリーの処理。
  if(posi < MaxPosi) {
     if(!EnFlag) {
        if(Time[1] <= LastCalTime && LastCalTime < Time[0] && Time[0] <= TimeCurrent()) {
           HAstart(HAOpen, HAClose, PERIOD_CURRENT, HALastCalTime);
           int Flag = 0;
           HAStr = "";
           HAStr2 = "";
           for(i = 1; i <= HACountReq; i++) {
              if(HAClose[i] > HAOpen[i]) {
                 Flag++;
                 HAStr += "Up,";
                 HAStr2 += StringFormat("(%s, %s),", DtS(HAClose[i]), DtS(HAOpen[i]));
              } else if(HAClose[i] < HAOpen[i]) {
                 Flag--;
                 HAStr += "Dn,";
                 HAStr2 += StringFormat("(%s, %s),", DtS(HAClose[i]), DtS(HAOpen[i]));
              } else {
                 HAStr += "None,";
                 HAStr2 += StringFormat("(%s, %s),", DtS(HAClose[i]), DtS(HAOpen[i]));
              }
           }
           if(Flag == +HACountReq) {
              EnFlag = true;
              HAColor = +1;
           } else if(Flag == -HACountReq) {
              EnFlag = true;
              HAColor = -1;
           }
           CalLot();
           string aFlagStr = (!EnFlag) ? "None" : ((HAColor == +1) ? "Up" :  "Down");
           string aText = StringFormat("[Lot=%s], エントリー判定日時:%s[Flag=%s] 平均足陰陽(%s), 平均足価格(%s)", DtS2(entrylot), (string)TimeCurrent(), aFlagStr, HAStr, HAStr2);
           if(posi > 0) {
              CalculateCOrders();
              bool aFlagNanpin = MinProfitPrice > NanpinProfitPrice;
              if(!aFlagNanpin) EnFlag = 0;
              aText += StringFormat(", (ポジ数%d, 最小含み損益%s, 基準含み損益%s, 積み増し判定%s)", posi, DtS(MinProfitPrice), DtS(NanpinProfitPrice), (string)(aFlagNanpin));
           }
           Comment(aText);
        }
     }
     if(EnFlag) {
        int  EnDir = HAColor;
        //printf("%d => %d, (%d, %d)", tc, EnDir, (int)MarketInfo(NULL, MODE_SPREAD), MaxSpread);
        if(EnDir == +1 && sells == 0) {
           if(MarketInfo(NULL, MODE_SPREAD) > MaxSpread) printf("Lエントリー条件成立したが、Spread=%d > 設定値%d [point]なのでエントリー見送り。", (int)MarketInfo(_Symbol, MODE_SPREAD), MaxSpread);
           else {
              res = orderSend(OP_BUY);
              if(res > 0) {
                 EnFlag = false;
                 printf("%s", ChartGetString(0, CHART_COMMENT));
              }
           }
        } else if(EnDir == -1 && buys == 0) {
           if(MarketInfo(NULL, MODE_SPREAD) > MaxSpread) printf("Sエントリー条件成立したが、Spread=%d > 設定値%d [point]なのでエントリー見送り。", (int)MarketInfo(_Symbol, MODE_SPREAD), MaxSpread);
           else {
              res = orderSend(OP_SELL);
              if(res > 0) {
                 EnFlag = false;
                 printf("%s", ChartGetString(0, CHART_COMMENT));
              }
           }
        }
     }
  }
//引き継ぎ変数の保存。
  LastTradeHistryCount = OrdersHistoryTotal();
  LastTradePoolCount   = OrdersTotal();
  LastCalTime = TimeCurrent();
  First = false;
}
//+------------------------------------------------------------------+
string DtS2(double aP) {
  return DoubleToString(aP, 2);
}
//+------------------------------------------------------------------+
string DtS(double aP) {
  return DoubleToString(aP, _Digits);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void orderCloseAll(int aMode) {
//指定タイプ全決済。
  for( icount = OrdersTotal() - 1; icount >= 0 ; icount--) {
     if( OrderSelect( icount, SELECT_BY_POS, MODE_TRADES ) == false ) continue;
     if( !Is_Magic(OrderMagicNumber()) )            continue;
     if( OrderSymbol() != _Symbol)                continue;
     if(aMode >= 0 && aMode != OrderType())       continue;
     orderClose(OrderTicket());
  }
//ポジ数の再取得。
  CalculateCOrders();
}
//+------------------------------------------------------------------+
bool orderClose(int aTicket) {
  res = OrderSelect( aTicket, SELECT_BY_TICKET, MODE_TRADES );
  double aClosePrice = 0;
  for(int  order_resend_num = 1 ; order_resend_num <= orderCloseModTryCountMax; order_resend_num++) {
     aClosePrice = (OrderType() == OP_BUY) ? SymbolInfoDouble(OrderSymbol(), SYMBOL_BID) : SymbolInfoDouble(OrderSymbol(), SYMBOL_ASK);
     res = OrderTicket();
     ret = OrderClose(OrderTicket(), OrderLots(), aClosePrice, Slippage, clrWhite);
     if(ret == false) {
        Sleep(orderInterval * order_resend_num);
        int errorcode = GetLastError();
        string aType = OrderType() == OP_BUY ? "Buy" : "Sell";
        printf("%d回目:決済(%s)拒否。エラーコード:%d 、詳細:%s", order_resend_num, aType, errorcode, ErrorDescription(errorcode));
        if(errorcode != ERR_TOO_MANY_REQUESTS && errorcode != ERR_OFF_QUOTES && errorcode != ERR_REQUOTE && errorcode != ERR_SERVER_BUSY && errorcode != ERR_TOO_FREQUENT_REQUESTS && errorcode != ERR_TRADE_TIMEOUT) {
           //要求の頻度が多すぎる場合、ブローカーがレートを提示していなかったり、売買の成立を拒否した場合、「Bid」や「Ask」を指定したが、それらに格納されている価格が古すぎたり、「Bid」と「Ask」が混在している場合、
           //取引サーバがビジー状態の場合、要求が頻繁すぎる場合、トレードに関する操作が完了するまでに時間切れとなった場合
           //こんな時は再注文を行わない。
           break;
        }
     } else {
        //オーダー成功時はブレイク
        break;
     }
  }
  return(ret);
}
//+------------------------------------------------------------------+
void CalLot() {
  if(LotMode == fixed) {
     StartLots = StartLotsFixed;
  } else {
     double aAE = AccountEquity();
     StartLots = LotVarLot * (aAE / LotVarBC);
  }
  entrylot = StartLots;
//entrylot = StartLots * MathPow(LotMult, CountM);
  entrylot = fmin(entrylotMAX, fmax(entrylot, entrylotMIN));  //上限下限設定
  entrylot = NormalizeDouble( entrylot, DigitsLot);           //桁数設定
}
//+------------------------------------------------------------------+
int orderSend(int Type) {
//ロット計算
  CalLot();
  Magic   = Magic0 * 100 + (1 + ((Type == OP_BUY) ? buys : sells));
//異常時対応。
  if(JudgeMarzinShortage()) return(-1);                          //証拠金不足判定
  if(Type == OP_BUY  && LastOrderErrL == iTime(_Symbol, PERIOD_M1, 0)) return(-1); //エラー後の時間制限の場合の判定
  if(Type == OP_SELL && LastOrderErrS == iTime(_Symbol, PERIOD_M1, 0)) return(-1); //エラー後の時間制限の場合の判定
//オーダー
  for(int order_resend_num = 1 ; order_resend_num <= orderSendTryCountMax; order_resend_num++) {
     RefreshRates();
     entryPrice   = (Type == OP_BUY) ? Ask : Bid;
     color aColor = (Type == OP_BUY) ? clrBlue : clrRed;
     res = OrderSend(_Symbol, Type, entrylot, entryPrice, Slippage, 0, 0, COMMENT, Magic, 0, aColor);
     if(res < 0) {
        //オーダーエラーの処理
        Sleep(orderInterval * order_resend_num);  //ミリ秒待機
        int errorcode = GetLastError();
        printf("%d回目:新規注文(%s %s)拒否。エラーコード:%d 、詳細:%s",
               order_resend_num, _Symbol, EnumToString((ENUM_ORDER_TYPE)Type), errorcode, ErrorDescription(errorcode));
        if(errorcode != ERR_TOO_MANY_REQUESTS && errorcode != ERR_OFF_QUOTES && errorcode != ERR_REQUOTE && errorcode != ERR_SERVER_BUSY && errorcode != ERR_TOO_FREQUENT_REQUESTS && errorcode != ERR_TRADE_TIMEOUT) {
           //要求の頻度が多すぎる場合、ブローカーがレートを提示していなかったり、売買の成立を拒否した場合、「Bid」や「Ask」を指定したが、それらに格納されている価格が古すぎたり、「Bid」と「Ask」が混在している場合、
           //取引サーバがビジー状態の場合、要求が頻繁すぎる場合、トレードに関する操作が完了するまでに時間切れとなった場合
           //こんな時は再注文を行わない。
           break;
        }
     } else {
        //オーダー成功の処理
        //TPの設定。
        if( OrderSelect( res, SELECT_BY_TICKET, MODE_TRADES ) )  orderModify(res);
        else                                                     printf("TPSL設定失敗");
        //ポジ数の再取得。
        CalculateCOrders();
        break;
     }
  }
//オーダーエラーで終了の場合は、1分足切替まで同じ方向のエントリー制限。
  if(res < 0) {
     if(Type == OP_BUY ) {
        LastOrderErrL = iTime(_Symbol, PERIOD_M1, 0);
        printf("注文エラー(%s - BUY) 次回トライ時刻%s",  _Symbol, (string)(iTime(_Symbol, PERIOD_M1, 0) + 60) );
     }
     if(Type == OP_SELL) {
        LastOrderErrS = iTime(_Symbol, PERIOD_M1, 0);
        printf("注文エラー(%s - SELL) 次回トライ時刻%s", _Symbol, (string)(iTime(_Symbol, PERIOD_M1, 0) + 60) );
     }
  }
  return(res);
}
//+------------------------------------------------------------------+
bool JudgeMarzinShortage() {
//必要証拠金不足の確認
  double aAE  = AccountFreeMargin();
  double aAM1 = MarketInfo(_Symbol, MODE_MARGINREQUIRED); //1Lot保有するのに必要証拠金
  if(aAE < aAM1 * entrylot) {
     string text = "";
     if(aAM1 != 0) text = StringFormat("資金不足のためエントリー処理(%s) 算出ロット%fLot, 証拠金%f, 最大ロット%f",                  _Symbol, entrylot, aAE, aAE / aAM1);
     else          text = StringFormat("資金不足のためエントリー処理(%s) 算出ロット%fLot, 証拠金%f, 必要証拠金を算出できませんでした。", _Symbol, entrylot, aAE);
     MessageBox(text, "エラー", MB_ICONEXCLAMATION);
     printf("%s", text);
     return(true);
  } else {
     return(false);
  }
}
//+------------------------------------------------------------------+
bool orderModify(int aTicket) {
//TPSLの設定
  double takeprofit = TPPrice;
  double stoploss   = SLPrice;
  if(takeprofit == 0 && stoploss == 0) return(false);
  bool modify_ret = false;
  double aSL = 0, aTP = 0;
  for(int  order_resend_num = 1 ; order_resend_num <= orderCloseModTryCountMax; order_resend_num++) {
     RefreshRates();
     if( OrderType() == OP_BUY ) {
        if(takeprofit != 0) aTP = OrderOpenPrice() + takeprofit;
        if(stoploss   != 0) aSL = OrderOpenPrice() - stoploss;
        if(NormalizeDouble(aTP - OrderTakeProfit(), digits) == 0 && NormalizeDouble(aSL - OrderStopLoss(), digits) == 0) return(false);
        modify_ret = OrderModify(OrderTicket(), OrderOpenPrice(), aSL, aTP, OrderExpiration(), clrBlue);
     } else if( OrderType() == OP_SELL ) {
        if(takeprofit != 0) aTP = OrderOpenPrice() - takeprofit;
        if(stoploss   != 0) aSL = OrderOpenPrice() + stoploss;
        if(NormalizeDouble(aTP - OrderTakeProfit(), digits) == 0 && NormalizeDouble(aSL - OrderStopLoss(), digits) == 0) return(false);
        modify_ret = OrderModify(OrderTicket(), OrderOpenPrice(), aSL, aTP, OrderExpiration(), clrRed);
     } else {
        break;
     }
     if(modify_ret == false) {
        Sleep(orderInterval * order_resend_num);
        int errorcode = GetLastError();
        printf("Ticket[%d]=%d, %d回目:指値逆指値設定注文変更拒否。エラーコード:%d 、詳細:%s (Bid=%f Open=%f, TP=%f, SL=%f)",
               icount, OrderTicket(), order_resend_num, errorcode, ErrorDescription(errorcode),
               Bid, OrderOpenPrice(), aTP, aSL);
        if(errorcode != ERR_TOO_MANY_REQUESTS && errorcode != ERR_OFF_QUOTES && errorcode != ERR_REQUOTE && errorcode != ERR_SERVER_BUSY && errorcode != ERR_TOO_FREQUENT_REQUESTS && errorcode != ERR_TRADE_TIMEOUT) {
           break;
        }
     } else {
        break;
     }
  }
  return(modify_ret);
}
//+------------------------------------------------------------------+
void orderTrailAll() {
  double aProfitPrice = 0, aSL = 0, aSLNew = 0;
  for( icount = OrdersTotal() - 1; icount >= 0 ; icount--) {
     if( OrderSelect( icount, SELECT_BY_POS, MODE_TRADES ) == false ) continue;
     if( !Is_Magic(OrderMagicNumber()) || OrderSymbol() != _Symbol)      continue;
     if(     OrderType() == OP_BUY)  {
        aSLNew       =  ((Bid - TrailWidthPrice) - OrderOpenPrice());
        aSL          =  (OrderStopLoss() - OrderOpenPrice());
        if(NormalizeDouble(aSL - aSLNew, Digits) >= -0 * Point()) continue; //設定したい値以上のSLが入っていればスキップ。
        //if((Bid - OrderOpenPrice()) >= TrailBootPrice) printf("%s, %s, %s",DtS(aSLNew),DtS(aSL), DtS(Bid - OrderOpenPrice()));
        if((Bid - OrderOpenPrice()) >= TrailBootPrice) orderModifyTrail(OrderTicket(), EMPTY_VALUE, OrderOpenPrice() + aSLNew);
     } else if(OrderType() == OP_SELL) {
        aSLNew       = -((Ask + TrailWidthPrice) - OrderOpenPrice());
        aSL          = -(OrderStopLoss() - OrderOpenPrice());
        if(NormalizeDouble(aSL - aSLNew, Digits) >= -0 * Point()) continue; //設定したい値以上のSLが入っていればスキップ。
        //if((OrderOpenPrice() - Ask) >= TrailBootPrice) printf("%s, %s, %s",DtS(aSLNew),DtS(aSL),DtS(OrderOpenPrice() - Ask));
        if((OrderOpenPrice() - Ask) >= TrailBootPrice) orderModifyTrail(OrderTicket(), EMPTY_VALUE, OrderOpenPrice() - aSLNew);
     }
  }
}
//+------------------------------------------------------------------+
bool orderModifyTrail(int aTicket, double aTPPrice, double aSLPrice) {
//printf("Mod注文[Ticket%d], En%f, TP%f, SL%f", aTicket, entryPrice, aTPPrice, aSLPrice);
//TPSLの設定
  bool modify_ret = false;
  double aSL = OrderStopLoss(), aTP = OrderTakeProfit();
  for(int  order_resend_num = 1 ; order_resend_num <= orderCloseModTryCountMax; order_resend_num++) {
     RefreshRates();
     if( OrderType() == OP_BUY || OrderType() == OP_BUYLIMIT || OrderType() == OP_BUYSTOP ) {
        if(aTPPrice != EMPTY_VALUE) aTP = aTPPrice;
        if(aSLPrice != EMPTY_VALUE) aSL = aSLPrice;
        //注文に変更がない場合はスキップ
        if(NormalizeDouble(aTP - OrderTakeProfit(), Digits) == 0 && NormalizeDouble(aSL - OrderStopLoss(), Digits) == 0) return(false);
        modify_ret = OrderModify(OrderTicket(), OrderOpenPrice(), aSL, aTP, OrderExpiration(), clrBlue);
     } else if( OrderType() == OP_SELL || OrderType() == OP_SELLLIMIT || OrderType() == OP_SELLSTOP  ) {
        if(aTPPrice != EMPTY_VALUE) aTP = aTPPrice;
        if(aSLPrice != EMPTY_VALUE) aSL = aSLPrice;
        //注文に変更がない場合はスキップ
        if(NormalizeDouble(aTP - OrderTakeProfit(), Digits) == 0 && NormalizeDouble(aSL - OrderStopLoss(), Digits) == 0) return(false);
        modify_ret = OrderModify(OrderTicket(), OrderOpenPrice(), aSL, aTP, OrderExpiration(), clrRed);
     } else {
        break;
     }
     if(modify_ret == false) {
        Sleep(orderInterval * order_resend_num);
        int errorcode = GetLastError();
        printf("Ticket=%d, %d/%d回目:指値逆指値設定注文変更拒否。エラーコード:%d 、詳細:%s (Bid=%f Open=%f, TP=%f, SL=%f, Entry=%f)",
               OrderTicket(), order_resend_num, orderCloseModTryCountMax, errorcode, ErrorDescription(errorcode),
               Bid, OrderOpenPrice(), aTP, aSL, OrderOpenPrice());
        if(errorcode != ERR_TOO_MANY_REQUESTS && errorcode != ERR_OFF_QUOTES && errorcode != ERR_REQUOTE && errorcode != ERR_SERVER_BUSY && errorcode != ERR_TOO_FREQUENT_REQUESTS && errorcode != ERR_TRADE_TIMEOUT) {
           break;
        }
     } else {
        break;
     }
  }
  return(modify_ret);
}
//+------------------------------------------------------------------+
void CalculateCOrders() {
//ポジ情報取得
//この処理が呼び出されるタイミングは初回起動時/エントリー成功時/決済済みポジ数増減時のみ。低頻度だから負荷は気にしない。
  buys = 0;
  sells = 0;
  MinProfitPrice = TPPrice;
//保有ポジ数を取得。
  for ( icount = 0 ; icount < OrdersTotal() ; icount++) {
     if( OrderSelect(icount, SELECT_BY_POS, MODE_TRADES) == false) break;   // 注文選択に失敗したらループ処理終了
     if( OrderSymbol() == _Symbol && Is_Magic(OrderMagicNumber())) {
        if(OrderType() == OP_BUY) {
           buys++;
           MinProfitPrice = fmin(MinProfitPrice, (Bid - OrderOpenPrice()));
        }
        if(OrderType() == OP_SELL) {
           sells++;
           MinProfitPrice = fmin(MinProfitPrice, (OrderOpenPrice() - Ask));
        }
     }
  }
  posi = buys + sells;
////マーチンカウントの確認
//   datetime aTimeNPlus = 0;                //最新の利確ポジ探索用
//   for ( icount = 0 ; icount < OrdersHistoryTotal() ; icount++) {
//      if( OrderSelect(icount, SELECT_BY_POS, MODE_HISTORY) == false) break;
//      if( OrderSymbol() == _Symbol && Is_Magic(OrderMagicNumber()))
//         if(OrderProfit() + OrderSwap() + OrderCommission() >= 0)
//            if(aTimeNPlus < OrderCloseTime())
//               aTimeNPlus = OrderCloseTime();
//   }
////コピー元のヒストリーから、当連敗回数を取得。カウント開始日時はコピー元EAの最新利確以降。
//   datetime aTime = aTimeNPlus;
//   int aCount = 0;
//   for ( icount = 0 ; icount < OrdersHistoryTotal() ; icount++) {
//      if( OrderSelect(icount, SELECT_BY_POS, MODE_HISTORY) == false) break;   // 注文選択に失敗したらループ処理終了
//      if( OrderSymbol() == _Symbol && Is_Magic(OrderMagicNumber())) {
//         if(aTime < OrderCloseTime()) aCount++;
//      }
//   }
//   CountM = aCount;
//printf("◆カウントリセット日時%s, その後の敗数 = %d", (string)aTimeNPlus, aCount);
}
//+------------------------------------------------------------------+
bool Is_Magic(int aMagic) {
  bool aRet = (StringFind((string)aMagic, (string)Magic0) == 0);
  return aRet;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void HAstart(double &aBufOpen[], double &aBufClose[], ENUM_TIMEFRAMES aTF, datetime &aLastCalTime) {
  int pos = iBarShift(NULL, aTF, aLastCalTime, false);
//if(pos == iBars(NULL, aTF) - 1) {
//バッファのインデックス異常対策
  if(pos >= ArraySize(aBufOpen) - 1) {
     //printf("%d / %d, (%s)", pos, ArraySize(aBufOpen), (string)aLastCalTime);
     ArrayResize(aBufOpen, pos + 100);
     ArrayResize(aBufClose, pos + 100);
     pos = ArraySize(aBufOpen) - 2;
     aBufOpen[pos]  = iClose(NULL, aTF, pos);
     aBufClose[pos] = iClose(NULL, aTF, pos);
     pos--;
  }
//バッファのスライド
  if(!First && pos > 0) {
     BufShift(aBufOpen,  pos);
     BufShift(aBufClose, pos);
  }
//printf("pos=%d(%s)", pos, (string)iTime(NULL, aTF, pos));
  int limit = pos;
//if(pos > 0) printf("%d/%d/%d", pos, limit, ArraySize(aBufOpen));
//バッファの計算
  while(pos >= 0) {
     aBufOpen[pos]  = (aBufOpen[pos + 1] + aBufClose[pos + 1]) / 2;
     aBufClose[pos] = (iOpen(NULL, aTF, pos) + iClose(NULL, aTF, pos) + iHigh(NULL, aTF, pos) + iLow(NULL, aTF, pos)) / 4;
     pos--;
  }
//if(limit > 0) for(int ai = fmin(limit, 10); ai >= 1; ai--)
//      printf("[%d][%d(%s)](%s, %s)(%s, %s)", (int)aTF, ai, (string)iTime(NULL, aTF, ai),
//             DoubleToString(aBufOpen[ai], 4), DoubleToString(aBufClose[ai], 4), DoubleToString(iOpen(NULL, aTF, ai), 3), DoubleToString(iClose(NULL, aTF, ai), 3));
  HAColor = (aBufClose[1] >= aBufOpen[1]) ? +1 : -1;
  HAStr = (HAColor == +1) ? "Up" : (HAColor == -1) ? "Down" : "None";
  aLastCalTime = iTime(NULL, aTF, 0);
}
//+------------------------------------------------------------------+
void BufShift(double & aBuf[], int aShift) {
  int aSize = ArraySize(aBuf);
  for(int ai = aSize - 1; ai > 0; ai--) aBuf[ai] = aBuf[ai - 1];
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+

いいなと思ったら応援しよう!