HYROLEAN

hyrGlobal.mq4

Mar 17th, 2026 (edited)
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.01 KB | Money | 0 0
  1. // hyrGlobal.mq4
  2. //   by 2025-2026 (c)hyrolean
  3. //---------------------------------------------------------------------------
  4. // Local:: <DataFolder>\MQL4\Libraries\User\hyrGlobal.mq4
  5. // URL:: https://pastebin.com/hk9XfDiv
  6. //---------------------------------------------------------------------------
  7. #property copyright "2025-2026, (c)hyrolean"
  8. #property link      "https://pastebin.com/hk9XfDiv"
  9. #property library
  10. //---------------------------------------------------------------------------
  11. #include <stdlib.mqh>
  12. #include <User/hyrDefs.mqh>    // https://pastebin.com/iHZKAWqC
  13. #include <User/hyrTmpl.mqh>    // https://pastebin.com/LG1vurny
  14. #include <User/hyrStatus.mqh>  // https://pastebin.com/D9JP5Ujq
  15.  
  16. static string ENTRY_NAME = "hyrEA"; // エントリー名
  17.  
  18. static int MaxAllowedSlippage=10;  // 最大許容スリッページ(points)
  19. static int MaxAllowedSpread=50;    // 最大許容スプレッド(points)
  20.  
  21. static int  ORDER_RETRY = 10 ;            // 注文の最大許容リトライ回数
  22. static int  ORDER_RETRY_SLEEP = 100 ;     // 注文のリトライ時待機時間
  23. static uint ORDER_RETRY_DURATION = 1000 ; // 注文のリトライ最大許容有効時間
  24.  
  25. static color ColorLongArrow=clrBlue; // 買い矢印の色
  26. static color ColorShortArrow=clrRed; // 売り矢印の色
  27.  
  28. //---------------------------------------------------------------------------
  29. //グローバル変数の設定
  30. void GlobalSettings(
  31.   string entryName,
  32.   int maxSlippage,
  33.   int maxSpread,
  34.   int orderRetry,
  35.   int orderRetrySleep,
  36.   uint orderRetryDuration ) export
  37. {
  38.   ENTRY_NAME = entryName ;
  39.   MaxAllowedSlippage = maxSlippage ;
  40.   MaxAllowedSpread = maxSpread ;
  41.   ORDER_RETRY = orderRetry ;
  42.   ORDER_RETRY_SLEEP = orderRetrySleep ;
  43.   ORDER_RETRY_DURATION = orderRetryDuration ;
  44. }
  45. //---------------------------------------------------------------------------
  46. //注文の色設定
  47. void OrderColorSetting(
  48.   color colLongArrow,
  49.   color colShortArrow  )
  50. {
  51.   ColorLongArrow = colLongArrow ;
  52.   ColorShortArrow = colShortArrow ;
  53. }
  54. //---------------------------------------------------------------------------
  55. //エラーログ出力
  56. void PrintLastError(string sender)
  57. {
  58.   int lastError = GetLastError() ;
  59.   if(sender!="") {
  60.     printf(ENTRY_NAME+"(%s): error(%d): %s",
  61.       sender,lastError,ErrorDescription(lastError));
  62.   }else {
  63.     printf(ENTRY_NAME+"error(%d): %s",
  64.       lastError,ErrorDescription(lastError));
  65.   }
  66. }
  67. //---------------------------------------------------------------------------
  68. //メッセージ出力
  69. void PrintMessage(string message, string sender)
  70. {
  71.   if(sender!="")
  72.     printf(ENTRY_NAME+"(%s): %s",sender,message);
  73.   else
  74.     printf(ENTRY_NAME+": %s",message);
  75. }
  76. //---------------------------------------------------------------------------
  77. //vとcompの距離が1Pointのサイズに収まっているかどうか
  78. bool InnerPoint(double v, double comp)
  79. {
  80.   return comp-Point/2.0 < v && v < comp+Point/2.0 ;
  81. }
  82. //---------------------------------------------------------------------------
  83. //基軸時間を返す
  84. datetime BaseTime(ENUM_TIMEBASE TimeBase)
  85. {
  86.   switch(TimeBase) {
  87.     case TIMEBASE_GMT:               // Greenwich Mean Time (GMT)
  88.       return TimeGMT();
  89.     case TIMEBASE_LOCAL:             // Local Time
  90.       return TimeLocal();
  91.     case TIMEBASE_SERVER:            // Server Time
  92.       return TimeCurrent();
  93.   }
  94.   return 0;
  95. }
  96. //---------------------------------------------------------------------------
  97. //マーケットで扱えるようにロットサイズを補正して返す
  98. double AdjustMarketLots(double lots)
  99. {
  100.   double minLots = MarketInfo(Symbol(),MODE_MINLOT);
  101.   double stepLots = MarketInfo(Symbol(),MODE_LOTSTEP);
  102.   double maxLots = MarketInfo(Symbol(),MODE_MAXLOT);
  103.   double roundLots = MathRound( MathMax(lots,stepLots) / stepLots ) ;
  104.   return MathMin(MathMax(roundLots*stepLots,minLots),maxLots) ;
  105. }
  106. //---------------------------------------------------------------------------
  107. //すでに注文済みかどうか
  108. FLAG AlreadyOrdered(FLAG orderFlag, MAGIC magic)
  109. {
  110.   FLAG flag = 0 ;
  111.   for(int i=OrdersTotal()-1 ; i>=0 ; i--) {
  112.     if( OrderSelect(i, SELECT_BY_POS) ) {
  113.       MAGIC orderMagic = OrderMagicNumber() ;
  114.       if( OrderSymbol() == Symbol() && (magic<0||magic==orderMagic) ){
  115.         OP orderType = OrderType() ;
  116.         if( orderType == OP_BUY && (orderFlag&FLAG_BUY)!=0 ){
  117.           flag |= FLAG_BUY  ; if(flag==orderFlag) break;
  118.         }else if( orderType == OP_SELL && (orderFlag&FLAG_SELL)!=0 ){
  119.           flag |= FLAG_SELL ; if(flag==orderFlag) break;
  120.         }
  121.       }
  122.     }
  123.   }
  124.   return flag;
  125. }
  126. //---------------------------------------------------------------------------
  127. //注文の発注
  128. TICKET MakeOrder(OP entryType, double lots, double sl, double tp, string detector,
  129.   MAGIC magic, double entryPrice, datetime expiration)
  130. {
  131.   string entryName = ENTRY_NAME+"("+detector+")" ;
  132.  
  133.   uint start = GetTickCount();
  134.   for(int retry=0; retry<ORDER_RETRY; retry++) {
  135.  
  136.     if( MaxAllowedSpread<0 || (entryType!=OP_BUY&&entryType!=OP_SELL) ||
  137.         MarketInfo(NULL,MODE_SPREAD) <= MaxAllowedSpread ) {
  138.  
  139.       color orderColor = clrNONE;
  140.       double price=entryPrice ;
  141.       switch(entryType) {
  142.       case OP_BUY: case OP_BUYSTOP: case OP_BUYLIMIT:
  143.         if(price==0.0) price = Ask ;
  144.         orderColor = ColorLongArrow ;
  145.         break;
  146.       case OP_SELL: case OP_SELLSTOP: case OP_SELLLIMIT:
  147.         if(price==0.0) price = Bid ;
  148.         orderColor = ColorShortArrow ;
  149.         break;
  150.       }
  151.  
  152.       TICKET ticket=MakeOrderSub(
  153.         entryType,price,lots,sl,tp,entryName,
  154.           magic,expiration,orderColor);
  155.       if(ticket>=0)
  156.         return ticket ;
  157.     }
  158.  
  159.     if(GetTickCount()-start>=ORDER_RETRY_DURATION)
  160.       break; // タイムオーバー
  161.  
  162.     Sleep(ORDER_RETRY_SLEEP);
  163.   }
  164.  
  165.   PrintMessage("entry failed.","MakeOrder");
  166.   return -1;
  167. }
  168. //---------------------------------------------------------------------------
  169. //注文発注サブルーチン
  170. TICKET MakeOrderSub(OP entryType, double entryPrice, double lots, double sl, double tp,
  171.   string comment, MAGIC magicNumber, datetime expiration, color orderColor)
  172. {
  173.    TICKET res = OrderSend(
  174.                       NULL,
  175.                       entryType,
  176.                       lots,
  177.                       entryPrice,
  178.                       MaxAllowedSlippage,
  179.                       sl,
  180.                       tp,
  181.                       comment,
  182.                       magicNumber,
  183.                       expiration,
  184.                       orderColor
  185.                    );
  186.    if(res<0)
  187.      PrintLastError("MakeOrderSub");
  188.    return res;
  189. }
  190. //---------------------------------------------------------------------------
  191. //発注済オーダーのStoplossとTakeprofitの変更
  192. bool ModifyOrderSlTp(TICKET ticket, double sl, double tp)
  193. {
  194.   if(OrderSelect(ticket,SELECT_BY_TICKET)) {
  195.     color orderColor = clrNONE;
  196.     switch(OrderType()) {
  197.     case OP_BUY: case OP_BUYSTOP: case OP_BUYLIMIT:
  198.       orderColor = ColorLongArrow ;
  199.       break;
  200.     case OP_SELL: case OP_SELLSTOP: case OP_SELLLIMIT:
  201.       orderColor = ColorShortArrow ;
  202.       break;
  203.     }
  204.     return
  205.       OrderModify(
  206.         ticket,OrderOpenPrice(),sl,tp,OrderExpiration(),orderColor) ;
  207.   }
  208.   PrintLastError("ModifyOrderSlTp");
  209.   return false ;
  210. }
  211. //---------------------------------------------------------------------------
  212. //発注済予約注文の取消
  213. bool WithdrawOrder(TICKET ticket, color orderColor)
  214. {
  215.   bool res = OrderDelete(ticket, orderColor);
  216.   if(!res) PrintLastError("WithdrawOrder");
  217.   return res ;
  218. }
  219. //---------------------------------------------------------------------------
  220. //注文の決済
  221. bool CheckoutOrder(OP orderType, TICKET orderTicket, double orderLots)
  222. {
  223.   uint startTick = GetTickCount();
  224.   for(int retry=0; retry<ORDER_RETRY; retry++) {
  225.     double checkoutPrice = 0.0 ;
  226.     color orderColor = clrNONE ;
  227.     switch(orderType) {
  228.     case OP_BUY:
  229.       checkoutPrice = Bid ;
  230.       orderColor = ColorLongArrow ;
  231.       break;
  232.     case OP_SELL:
  233.       checkoutPrice = Ask ;
  234.       orderColor = ColorShortArrow ;
  235.       break;
  236.     }
  237.     if(OrderClose(orderTicket, orderLots, checkoutPrice, MaxAllowedSlippage, orderColor))
  238.       return true;
  239.     if(GetTickCount()-startTick>=ORDER_RETRY_DURATION)
  240.       break; // タイムオーバー
  241.     Sleep(ORDER_RETRY_SLEEP);
  242.   }
  243.   PrintLastError("CheckoutOrder");
  244.   return false ;
  245. }
  246. //---------------------------------------------------------------------------
  247.  
  248.   struct OBJECT_CHECKOUT {
  249.     TICKET Ticket;
  250.     double Profit;
  251.     OBJECT_CHECKOUT() {
  252.       Ticket = -1 ;
  253.       Profit = 0.0 ;
  254.     }
  255.     OBJECT_CHECKOUT(const OBJECT_CHECKOUT &lhs) {
  256.       Ticket = lhs.Ticket ;
  257.       Profit = lhs.Profit ;
  258.     }
  259.     OBJECT_CHECKOUT(TICKET Ticket_, double Profit_) {
  260.       Ticket = Ticket_ ;
  261.       Profit = Profit_ ;
  262.     }
  263.     bool operator <(const OBJECT_CHECKOUT &rhs) const {
  264.       return Profit < rhs.Profit ;
  265.     }
  266.   };
  267.  
  268. //注文の全決済
  269. bool CheckoutOrderAll(FLAG orderFlag, MAGIC magic, double lotsDenom)
  270. {
  271.   int i;
  272.   bool result = true ;
  273.   CArrayObj *array = new CArrayObj();
  274.   for(i = 0 ; i < OrdersTotal() ; i++){
  275.     if(OrderSelect(i, SELECT_BY_POS)) {
  276.       MAGIC orderMagic = OrderMagicNumber();
  277.       OP orderType = OrderType() ;
  278.       if( (orderType==OP_BUY&&(orderFlag&FLAG_BUY)!=0) ||
  279.           (orderType==OP_SELL&&(orderFlag&FLAG_SELL)!=0) ) {
  280.         if( OrderSymbol() == Symbol() && (magic<0||magic==orderMagic) ){
  281.           AddToArray(array,OBJECT_CHECKOUT(OrderTicket(),OrderProfit()));
  282.         }
  283.       }
  284.     }
  285.   }
  286.   array.Sort(ARRAY_SORT_DESCEND); // 利益が多い順に並べ替える
  287.   for(i=0;i<array.Total();i++) {
  288.     CSortable<OBJECT_CHECKOUT> *node = (CSortable<OBJECT_CHECKOUT>*)array.At(i);
  289.     if(OrderSelect(node.v.Ticket, SELECT_BY_TICKET)) {
  290.       if(!CheckoutOrder(OrderType(),OrderTicket(),AdjustMarketLots(OrderLots()/lotsDenom))) {
  291.         result = false ; break;
  292.       }
  293.     }
  294.   }
  295.   delete array ;
  296.   return result ;
  297. }
  298. //---------------------------------------------------------------------------
  299. //時間動作制御(戻り値: true=アクティブ時間, false=オフタイム)
  300. bool ControlTimeAction(
  301.   datetime TimeTick, datetime TimeStart, datetime TimeEnd,
  302.   datetime &NextStartTime, MAGIC magic, ENUM_TIMEACT TimeAction)
  303. {
  304.   MqlDateTime mqlTick, mqlStart, mqlEnd ;
  305.   TimeToStruct(TimeTick, mqlTick);
  306.   TimeToStruct(TimeStart, mqlStart);
  307.   TimeToStruct(TimeEnd, mqlEnd);
  308.  
  309.   // 活動時間帯のチェック
  310.   int ct = mqlTick.hour*60 + mqlTick.min ;
  311.   int st = mqlStart.hour*60 + mqlStart.min ;
  312.   int et = mqlEnd.hour*60 + mqlEnd.min ;
  313.   if(et<=st) {
  314.     if(st<=ct) et=24*60;
  315.     if(ct<=et) st=0;
  316.   }
  317.   bool activeTime = st <= ct && ct <= et ;
  318.  
  319.   bool isActivated = NextStartTime<TimeTick ;
  320.  
  321.   // 現在活動時間帯
  322.   if(activeTime) {
  323.     if(!isActivated)
  324.       NextStartTime = TimeTick ; // 現在時間を開始時間切り上げて完了
  325.     return true ;
  326.   }
  327.  
  328.   // 活動時間を次の時間にセットする
  329.   MqlDateTime mqlNextStart = mqlTick ;
  330.   mqlNextStart.hour = mqlStart.hour ;
  331.   mqlNextStart.min = mqlStart.min ;
  332.   mqlNextStart.sec = 0 ;
  333.   datetime timNextStart = StructToTime(mqlNextStart) ;
  334.   while(timNextStart<TimeTick)  timNextStart += 24*60*60 ;
  335.   NextStartTime = timNextStart ;
  336.  
  337.   // 次の開始までの秒数
  338.   datetime timOff = NextStartTime - TimeTick ;
  339.  
  340.   FLAG orderFlag = AlreadyOrdered(FLAG_SELL|FLAG_BUY, magic);
  341.  
  342.   STATUS status_long, status_short;
  343.   double total=0.0;
  344.  
  345.   switch(TimeAction) {
  346.     case TIMEACT_NONE:
  347.       // None
  348.       break;
  349.     case TIMEACT_FORCE_CLOSE_ALL:
  350.       // Force Close All positions
  351.       if(orderFlag!=0)
  352.         CheckoutOrderAll(orderFlag, magic, 1.0);
  353.       break;
  354.     case TIMEACT_FORCE_CLOSE_LONG:
  355.       // Force Close Long positions
  356.       if((orderFlag&FLAG_BUY)!=0)
  357.         CheckoutOrderAll(FLAG_BUY, magic, 1.0);
  358.       break;
  359.     case TIMEACT_FORCE_CLOSE_SHORT:
  360.       // Force Close Short positions
  361.       if((orderFlag&FLAG_SELL)!=0)
  362.         CheckoutOrderAll(FLAG_SELL, magic, 1.0);
  363.       break;
  364.     case TIMEACT_SOFT_CLOSE_ALL:
  365.       // Close All positions if profits are Positive
  366.       if(orderFlag!=0) {
  367.         CheckStatus(OP_BUY,magic,&status_long);
  368.         CheckStatus(OP_SELL,magic,&status_short);
  369.         total = status_long.GrossProfit+status_short.GrossProfit ;
  370.         if(total>0) {
  371.           CheckoutOrderAll(orderFlag, magic, 1.0);
  372.         }
  373.       }
  374.       break;
  375.     case TIMEACT_SOFT_CLOSE_LONG:
  376.       // Close Long positions if profits are Positive
  377.       if((orderFlag&FLAG_BUY)!=0) {
  378.         CheckStatus(OP_BUY,magic,&status_long);
  379.         total=status_long.GrossProfit;
  380.         if(total>0) {
  381.           CheckoutOrderAll(FLAG_BUY, magic, 1.0);
  382.         }
  383.       }
  384.       break;
  385.     case TIMEACT_SOFT_CLOSE_SHORT:
  386.       // Close Short positions if profits are Positive
  387.       if((orderFlag&FLAG_SELL)!=0) {
  388.         CheckStatus(OP_SELL,magic,&status_short);
  389.         total=status_short.GrossProfit;
  390.         if(total>0) {
  391.           CheckoutOrderAll(FLAG_SELL, magic, 1.0);
  392.         }
  393.       }
  394.       break;
  395.   }
  396.  
  397.   return false ;
  398. }
  399. //---------------------------------------------------------------------------
  400. //000,000,000表示
  401. string DoubleToAmount(double inputdata, int dig)
  402. {
  403.   string textOrg = DoubleToStr(inputdata,dig);
  404.   int lnOrg = StringLen(textOrg) ;
  405.   if(!lnOrg) return "" ;
  406.   int periodPos = StringFind(textOrg,".");
  407.   string textRes="";
  408.   int beg=0, lnHead = periodPos>=0 ? periodPos : lnOrg ;
  409.   StringReserve(textRes,lnHead+(lnHead+2)/3+1);
  410.   if(textOrg[0]=='-') { textRes="-"; beg++ ; } // マイナス損益
  411.   int lnRem = lnHead-beg ;
  412.   int first = lnRem%3;
  413.   if(!first&&lnRem>=3) first=3 ;
  414.   if(first>0) {
  415.     textRes+=StringSubstr(textOrg,beg,first);
  416.     for(int i=first;i<lnRem;i+=3) // 三桁区切り
  417.       textRes+=","+StringSubstr(textOrg,beg+i,3);
  418.   }
  419.   if(periodPos>=0)
  420.     return textRes+StringSubstr(textOrg,periodPos);
  421.   return textRes;
  422. }
  423. //---------------------------------------------------------------------------
  424.  
Tags: Mt4
Advertisement
Add Comment
Please, Sign In to add comment