HYROLEAN

claude-test_3ma_user.mq5

Mar 17th, 2026 (edited)
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 31.91 KB | Money | 0 0
  1. //+------------------------------------------------------------------+
  2. //| claude-test_3ma_user.mq5 - Claude による移植テスト                  |
  3. //|  (殆ど自動だが、ビルドエラーが出る部分や表示がおかしくなる部分等は、 |
  4. //|   MT4との違いをGemini等に尋ねながら別途修正する必要がある模様…) |
  5. //|                                                                  |
  6. //| MT4版 test_3ma_user.mq4 の MT5移植版                             |
  7. //| 元コード: https://pastebin.com/6jvBeEfi                          |
  8. //|                                                                  |
  9. //| MT4→MT5 主な変更点 by Claude :                                  |
  10. //|  1. iMA() → CHyrIQueueMA クラスに置き換え                       |
  11. //|  2. OrderSend() → MT5スタイル (MqlTradeRequest) に変更          |
  12. //|  3. OrderSelect/OrdersTotal → PositionSelect 系に変更           |
  13. //|  4. Bid/Ask → SymbolInfoDouble() に変更                         |
  14. //|  5. ObjectSet() → ObjectSetInteger/Double/String に統一         |
  15. //|  6. stdlib.mqh → 不要なので削除、ErrorDescription→独自実装     |
  16. //|  7. OP_BUY/OP_SELL → ORDER_TYPE_BUY/ORDER_TYPE_SELL に変更      |
  17. //+------------------------------------------------------------------+
  18. #property copyright "2024-2026, (c)hyrolean"
  19. #property link      "https://pastebin.com/C7W6v04x"
  20. #property version   "1.01"
  21.  
  22.   // version 1.01
  23.   //   - 発注プロセスを多少改善
  24.  
  25. #include <Trade/Trade.mqh>          // MT5の発注ライブラリ
  26.  
  27. #include <User/hyrGlobal.mqh>  // https://pastebin.com/2PdBW6NQ
  28. #include <User/hyrStatus.mqh>  // https://pastebin.com/d9Z8P2qD
  29. #include <User/hyrIQueue.mqh>  // https://pastebin.com/3pRKTce4
  30. #include <User/hyrTmpl.mqh>    // https://pastebin.com/LG1vurny
  31.  
  32. //+------------------------------------------------------------------+
  33. //| 定数・列挙型                                                      |
  34. //+------------------------------------------------------------------+
  35. #define ENTRY_NAME "3MAUser"
  36. #define MAShift    0
  37. #define ORDER_RETRY 10
  38. #define ORDER_RETRY_SLEEP 100
  39. #define ORDER_RETRY_DURATION 1000
  40.  
  41. #define SELLBTN_NAME       "EntrySell"
  42. #define BUYBTN_NAME        "EntryBuy"
  43. #define CLOSEALLBTN_NAME   "CloseAll"
  44. #define CLOSELONGBTN_NAME  "CloseLong"
  45. #define CLOSESHORTBTN_NAME "CloseShort"
  46. #define FLUSHTLBTN_NAME    "FlushTL"
  47. #define OFFTIME_NAME       "OFF TIME"
  48. #define AMOUNT_NAME        "AMOUNT"
  49. #define DBGINFO_NAME       "DEBUG INFO"
  50.  
  51. enum ENUM_POSI {
  52.    POSI_STOP,
  53.    POSI_ONLY_LONG,
  54.    POSI_ONLY_SHORT,
  55.    POSI_HALF_LONG_AND_SHORT,
  56.    POSI_FULL_LONG_AND_SHORT
  57. };
  58.  
  59. //+------------------------------------------------------------------+
  60. //| 入力パラメーター                                                  |
  61. //+------------------------------------------------------------------+
  62. input bool               Automation       = true;
  63. input ENUM_TIMEFRAMES    MainTimeFrame     = PERIOD_CURRENT;
  64. input int                MAGICMA          = 0;
  65. input bool               TimeControl      = false;
  66. input ENUM_TIMEBASE      TimeBase         = TIMEBASE_LOCAL;
  67. input string             TimeStart        = "09:00";
  68. input string             TimeEnd          = "15:00";
  69. input ENUM_TIMEACT       TimeAction       = TIMEACT_NONE;
  70. input ENUM_MA_METHOD     MAMode           = MODE_EMA;
  71. input ENUM_APPLIED_PRICE MAPriceType      = PRICE_CLOSE;
  72. input bool               MA3              = true;
  73. input int                MA3FastPeriod    = 10;
  74. input int                MA3MediumPeriod  = 20;
  75. input int                MA3SlowPeriod    = 50;
  76. input int                MA3TLPeriod      = 5;
  77. input int                Slippage         = 10;
  78. input int                Spread           = 50;
  79. input double             BaseLots         = 0.1;
  80. input double             StepLots         = 0.01;
  81. input double             MinLots          = 0.01;
  82. input double             MaxLots          = 50.0;
  83. input double             LotsDenomTL      = 3.0;
  84. input double             LotsDenomMAFast  = 2.0;
  85. input double             Takeprofit       = 0;
  86. input double             Stoploss         = 200;
  87. input double             MaxGrosslossPer  = 25;
  88. input bool               Compounding      = false;
  89. input double             CompoundingBase  = 100000;
  90. input bool               BalanceIncludeCredit = true;
  91. input bool               Trailing         = false;
  92. input double             TrailingStart    = 300;
  93. input double             TrailingStop     = 200;
  94. input bool               ShowUserEntry    = true;
  95. input bool               ShowCloseAll     = true;
  96. input bool               ShowCloseLong    = false;
  97. input bool               ShowCloseShort   = false;
  98. input bool               ShowFlushTL      = true;
  99. input bool               ShowAmount       = true;
  100. input int                AmountDig        = 0;
  101. input color              ClrAmountPosi    = clrLightGoldenrod;
  102. input color              ClrAmountNega    = clrLightPink;
  103. input color              ClrTimeControl   = clrYellow;
  104. input color              ClrLongArrow     = clrBlue;
  105. input color              ClrShortArrow    = clrRed;
  106. input bool               DBGMODE          = true;
  107.  
  108. //+------------------------------------------------------------------+
  109. //| グローバル変数                                                    |
  110. //+------------------------------------------------------------------+
  111. double   Lots, PrevBid, PrevAsk;
  112. datetime CurTime, TimeTick, StartTime, CancelTime, UserTime;
  113. int      UserEntry   = 0;
  114. bool     FlushTL     = false;
  115. bool     OffTimeVisible = false;
  116.  
  117. //--- MT5発注ライブラリ
  118. CTrade Trade;
  119.  
  120. //--- IQueue MA (3本分)
  121. CHyrIQueueMA gFastMA, gMediumMA, gSlowMA;
  122.  
  123. //--- IQueue ATR14 (デバッグ用)
  124. CHyrIQueueATR gATR14;
  125.  
  126. //+------------------------------------------------------------------+
  127. //| ユーティリティ                                                    |
  128. //+------------------------------------------------------------------+
  129. double GetBid() { return SymbolInfoDouble(_Symbol, SYMBOL_BID); }
  130. double GetAsk() { return SymbolInfoDouble(_Symbol, SYMBOL_ASK); }
  131.  
  132. double AdjLots(double lots)
  133. {
  134.    double roundLots = MathRound(MathMax(lots, StepLots) / StepLots);
  135.    return MathMin(MathMax(roundLots * StepLots, MinLots), MaxLots);
  136. }
  137.  
  138. void DBGOUT(string text)
  139. {
  140.    if(DBGMODE)
  141.       ObjectSetString(0, DBGINFO_NAME, OBJPROP_TEXT, text);
  142. }
  143.  
  144. //--- メインタイムを返す
  145. datetime MainTime(int shift = 0)
  146. {
  147.    return iTime(_Symbol, MainTimeFrame, shift);
  148. }
  149.  
  150. int MainPeriod()
  151. {
  152.    int period = (int)MainTimeFrame;
  153.    if(!period) period = (int)Period();
  154.    return period;
  155. }
  156.  
  157. //+------------------------------------------------------------------+
  158. //| 注文の発注 (MT5版)                                                |
  159. //+------------------------------------------------------------------+
  160. ulong MakeOrder(ENUM_ORDER_TYPE entryType, double lots, double sl, double tp,
  161.                 string detector, int magic, double entryPrice = 0.0)
  162. {
  163.    string entryName = ENTRY_NAME"(" + detector + ")";
  164.    double bid = GetBid(), ask = GetAsk();
  165.  
  166.    uint start = GetTickCount();
  167.    string lastError;
  168.    for(int retry = 0; retry < ORDER_RETRY; retry++) {
  169.       //--- スプレッドチェック
  170.       lastError="";
  171.       double spreadPts = (double)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
  172.       bool cancel=false ;
  173.       if((entryType == ORDER_TYPE_BUY || entryType == ORDER_TYPE_SELL) && spreadPts > Spread) {
  174.          cancel=true; retry--; lastError = "spread expanding." ;
  175.       }
  176.       if(!cancel) {
  177.         double price = entryPrice;
  178.         if(price == 0.0)
  179.            price = (entryType == ORDER_TYPE_BUY) ? ask : bid;
  180.  
  181.         Trade.SetExpertMagicNumber(magic);
  182.         Trade.SetDeviationInPoints(Slippage);
  183.  
  184.         bool res = false;
  185.         if(entryType == ORDER_TYPE_BUY)
  186.            res = Trade.Buy(lots, _Symbol, price, sl, tp, entryName);
  187.         else if(entryType == ORDER_TYPE_SELL)
  188.            res = Trade.Sell(lots, _Symbol, price, sl, tp, entryName);
  189.  
  190.         if(res) return Trade.ResultOrder();
  191.       }
  192.       if(GetTickCount()-start>=ORDER_RETRY_DURATION) break;
  193.       Sleep(ORDER_RETRY_SLEEP);
  194.    }
  195.    if(lastError!="")
  196.      PrintMessage(lastError);
  197.    else
  198.      PrintLastError();
  199.    return 0;
  200. }
  201.  
  202. //+------------------------------------------------------------------+
  203. //| 注文の決済 (MT5版)                                                |
  204. //+------------------------------------------------------------------+
  205. bool CheckoutOrder(ENUM_ORDER_TYPE orderType, ulong ticket, double orderLots)
  206. {
  207.    uint start = GetTickCount();
  208.    for(int retry = 0; retry < ORDER_RETRY; retry++) {
  209.       bool res = Trade.PositionClosePartial(ticket, orderLots, Slippage);
  210.       if(res) return true;
  211.       if(GetTickCount()-start>=ORDER_RETRY_DURATION) break;
  212.       Sleep(ORDER_RETRY_SLEEP);
  213.    }
  214.    PrintLastError();
  215.    return false;
  216. }
  217.  
  218. struct OBJECT_CHECKOUT {
  219.    ulong  Ticket;
  220.    double Profit;
  221.    OBJECT_CHECKOUT() { Ticket = 0; Profit = 0.0; }
  222.    OBJECT_CHECKOUT(ulong Ticket_, double Profit_) { Ticket = Ticket_; Profit = Profit_; }
  223.    bool operator <(const OBJECT_CHECKOUT &rhs) const { return Profit < rhs.Profit; }
  224. };
  225.  
  226. bool CheckoutOrderAll(int orderFlag, double lotsDenom = 1.0)
  227. {
  228.    bool result = true;
  229.    CArrayObj *array = new CArrayObj();
  230.  
  231.    int total = PositionsTotal();
  232.    for(int i = 0; i < total; i++) {
  233.       ulong ticket = PositionGetTicket(i);
  234.       if(ticket == 0) continue;
  235.       if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
  236.       if((int)PositionGetInteger(POSITION_MAGIC) != MAGICMA) continue;
  237.       ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
  238.       bool isBuy  = (posType == POSITION_TYPE_BUY  && (orderFlag & FLAG_BUY)  != 0);
  239.       bool isSell = (posType == POSITION_TYPE_SELL && (orderFlag & FLAG_SELL) != 0);
  240.       if(isBuy || isSell)
  241.          AddToArray(array, OBJECT_CHECKOUT(ticket, PositionGetDouble(POSITION_PROFIT)));
  242.    }
  243.    array.Sort(ARRAY_SORT_DESCEND);
  244.    for(int i = 0; i < array.Total(); i++) {
  245.       CSortable<OBJECT_CHECKOUT> *node = (CSortable<OBJECT_CHECKOUT>*)array.At(i);
  246.       if(PositionSelectByTicket(node.v.Ticket)) {
  247.          double lots = PositionGetDouble(POSITION_VOLUME) / lotsDenom;
  248.          ENUM_POSITION_TYPE pt = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
  249.          ENUM_ORDER_TYPE ot = (pt == POSITION_TYPE_BUY) ? ORDER_TYPE_BUY : ORDER_TYPE_SELL;
  250.          if(!CheckoutOrder(ot, node.v.Ticket, lots)) { result = false; break; }
  251.       }
  252.    }
  253.    delete array;
  254.    return result;
  255. }
  256.  
  257. //+------------------------------------------------------------------+
  258. //| マニュアルポジション発注                                          |
  259. //+------------------------------------------------------------------+
  260. ulong EntryManualPosition(string detector, ENUM_ORDER_TYPE entryType, double lots)
  261. {
  262.    double bid = GetBid(), ask = GetAsk();
  263.    double sl = 0.0, tp = 0.0;
  264.  
  265.    if(entryType == ORDER_TYPE_BUY) {
  266.       if(Stoploss   != 0.0) sl = ask - Stoploss   * _Point;
  267.       if(Takeprofit != 0.0) tp = ask + Takeprofit * _Point;
  268.    } else {
  269.       if(Stoploss   != 0.0) sl = bid + Stoploss   * _Point;
  270.       if(Takeprofit != 0.0) tp = bid - Takeprofit * _Point;
  271.    }
  272.  
  273.    if(sl == 0.0 && MaxGrosslossPer >= 100.0) {
  274.       double halfSpread = (ask - bid) / 2.0;
  275.       //--- SlowMAの現在値チェック(MAQueueから取得)
  276.       double slowMA0 = gSlowMA[0] + halfSpread;
  277.       if(entryType == ORDER_TYPE_BUY ? slowMA0 >= ask : slowMA0 <= bid) {
  278.          PrintMessage("Entrying failed due to Slow MA over price reached");
  279.          return 0;
  280.       }
  281.    }
  282.    return MakeOrder(entryType, lots, sl, tp, detector, MAGICMA);
  283. }
  284.  
  285. //+------------------------------------------------------------------+
  286. //| 金額表示                                                          |
  287. //+------------------------------------------------------------------+
  288.  
  289. void UpdateAmount(double amount, int positions)
  290. {
  291.    if(!ShowAmount) return;
  292.    if(positions > 0) {
  293.       string s = DoubleToAmount(amount, AmountDig);
  294.       if(amount > 0) s = "+" + s;
  295.       ObjectSetString(0, AMOUNT_NAME, OBJPROP_TEXT, s);
  296.       ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_COLOR,
  297.                        amount < 0 ? ClrAmountNega : ClrAmountPosi);
  298.    } else {
  299.       string s = ObjectGetString(0, AMOUNT_NAME, OBJPROP_TEXT);
  300.       int ln = StringLen(s);
  301.       if(ln > 0 && s[ln-1] != '-')
  302.          ObjectSetString(0, AMOUNT_NAME, OBJPROP_TEXT, s + "-");
  303.    }
  304. }
  305.  
  306. //+------------------------------------------------------------------+
  307. //| タイムコントロール                                                |
  308. //+------------------------------------------------------------------+
  309. void CheckTimeControl(bool nextTicked)
  310. {
  311.   if(!TimeControl) {
  312.     if(OffTimeVisible) {
  313.       ObjectDelete(0,OFFTIME_NAME);
  314.       OffTimeVisible = false ;
  315.     }
  316.     return ;
  317.   }
  318.   if(!nextTicked) return ;
  319.   if(!ControlTimeAction(
  320.       TimeTick,StringToTime(TimeStart),StringToTime(TimeEnd),
  321.       StartTime,MAGICMA,TimeAction)) {
  322.     datetime timOff = StartTime - TimeTick ;
  323.     if(!OffTimeVisible) {
  324.       // OFF TIME テキストを表示
  325.       ObjectCreate(0, OFFTIME_NAME, OBJ_LABEL, 0, 0, 0);
  326.       ObjectSetInteger(0, OFFTIME_NAME, OBJPROP_XDISTANCE, 10);
  327.       ObjectSetInteger(0, OFFTIME_NAME, OBJPROP_YDISTANCE, 25);
  328.       ObjectSetInteger(0, OFFTIME_NAME, OBJPROP_CORNER, CORNER_RIGHT_UPPER);
  329.       ObjectSetInteger(0, OFFTIME_NAME, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER);
  330.       ObjectSetString (0, OFFTIME_NAME, OBJPROP_TEXT, "OFF TIME");
  331.       ObjectSetString (0, OFFTIME_NAME, OBJPROP_FONT, "Verdana");
  332.       ObjectSetInteger(0, OFFTIME_NAME, OBJPROP_FONTSIZE, 8);
  333.       ObjectSetInteger(0, OFFTIME_NAME, OBJPROP_COLOR, ClrTimeControl);
  334.       OffTimeVisible = true ;
  335.     }
  336.   }else if(OffTimeVisible) {
  337.     ObjectDelete(0, OFFTIME_NAME);
  338.     OffTimeVisible = false ;
  339.   }
  340. }
  341.  
  342. //+------------------------------------------------------------------+
  343. //| オーダーの処理(3EMAロジック)                                    |
  344. //+------------------------------------------------------------------+
  345. void ProcessOrders(bool nextTimed, ENUM_ORDER_TYPE orderType,
  346.                    const STATUS &status, const STATUS &revStatus)
  347. {
  348.    if(status.Positions <= 0) return;
  349.    double bid = GetBid(), ask = GetAsk();
  350.    bool isBuy = (orderType == ORDER_TYPE_BUY);
  351.  
  352.    // トレーリング
  353.    if(Trailing) {
  354.       double tstart   = TrailingStart * _Point;
  355.       double tstop    = TrailingStop  * _Point;
  356.       double minPad   = tstart + tstop;
  357.       for(int i=0;i<status.OrdersCount();i++) {
  358.          COrderStatus *order = status.OrdersAt(isBuy ? status.Positions-1-i : i);
  359.          if(isBuy ? order.Price > bid - minPad : order.Price < ask + minPad) break;
  360.          double sl = 0.0;
  361.          if(order.Stoploss == 0.0 ||
  362.             (isBuy ? order.Stoploss < order.Price : order.Stoploss > order.Price))
  363.             sl = isBuy ? order.Price + tstart : order.Price - tstart;
  364.          else
  365.             sl = order.Stoploss;
  366.          while((isBuy ? bid - sl : sl - ask) >= tstop * 2)
  367.             sl += isBuy ? +tstop : -tstop;
  368.          if(!InnerPoint(sl, order.Stoploss)) {
  369.             Trade.PositionModify(order.Ticket, sl, order.Takeprofit);
  370.             order.Stoploss = sl;
  371.          }
  372.       }
  373.    }
  374.  
  375.    // 3EMA処理
  376.    if(MA3 && (nextTimed || FlushTL)) {
  377.       double halfSpread = (ask - bid) / 2.0;
  378.       //--- MAQueueから現在値を取得([0]=最新バー)
  379.       double FastMA0   = gFastMA[0]   + halfSpread;
  380.       double MediumMA0 = gMediumMA[0] + halfSpread;
  381.       double SlowMA0   = gSlowMA[0]   + halfSpread;
  382.  
  383.       for(int i = status.OrdersCount() - 1; i >= 0; i--) {
  384.          COrderStatus *order = status.OrdersAt(isBuy ? status.Positions-1-i : i);
  385.          double price          = order.Price;
  386.          double sl             = order.Stoploss;
  387.          double trail_sl       = 0.0;
  388.          double checkout_denom = 0.0;
  389.          string checkout_reason = "";
  390.  
  391.          if(InnerPoint(sl, price)) {
  392.             if(FlushTL && !nextTimed) continue;
  393.             if(!InnerPoint(MediumMA0, price) &&
  394.                (isBuy ? MediumMA0-halfSpread > price : MediumMA0+halfSpread < price)) {
  395.                if(isBuy ? FastMA0 > ask : FastMA0 < bid) {
  396.                   checkout_denom  = LotsDenomMAFast;
  397.                   checkout_reason = "Check-out by Fast MA";
  398.                   if(isBuy ? MediumMA0 > ask : MediumMA0 < bid)
  399.                   { checkout_reason += " & Medium MA"; checkout_denom = 1.0; }
  400.                   trail_sl = MediumMA0 + (isBuy ? -halfSpread : +halfSpread);
  401.                }
  402.             }
  403.          } else if(sl != 0.0 && (isBuy ? sl > price : sl < price)) {
  404.             if(FlushTL && !nextTimed) continue;
  405.             if(isBuy ? ask <= MediumMA0 : bid >= MediumMA0) {
  406.                checkout_denom  = 1.0;
  407.                checkout_reason = "Check-out by Medium MA";
  408.             }
  409.          } else {
  410.             if(FlushTL || MA3TLPeriod > 0) {
  411.                datetime tperiod = (datetime)(MainPeriod() * 60);
  412.                int period = (int)((CurTime - order.OpenTime) / tperiod);
  413.                if(FlushTL || period >= MA3TLPeriod - 1) {
  414.                   if(isBuy ? bid > price : ask < price) {
  415.                      if(!FlushTL && (isBuy ? FastMA0>ask||MediumMA0>ask : FastMA0<bid||MediumMA0<bid)) {
  416.                         trail_sl = price + (isBuy ? -_Point : +_Point);
  417.                      } else {
  418.                         checkout_denom  = LotsDenomTL;
  419.                         checkout_reason = "Check-out by TL(TimeLimited)";
  420.                         trail_sl        = price;
  421.                      }
  422.                   }
  423.                }
  424.             }
  425.             if(!FlushTL || nextTimed) {
  426.                if(sl == 0.0 && MaxGrosslossPer >= 100.0) {
  427.                   if(isBuy ? ask <= SlowMA0 : bid >= SlowMA0) {
  428.                      checkout_denom  = 1.0;
  429.                      checkout_reason = "Loss-cut order by Slow MA";
  430.                   }
  431.                }
  432.             }
  433.          }
  434.  
  435.          if(trail_sl != 0.0) {
  436.             if(sl==0.0 || (!InnerPoint(sl,trail_sl) && (isBuy ? sl<trail_sl : sl>trail_sl))) {
  437.                sl = trail_sl;
  438.                Trade.PositionModify(order.Ticket, sl, order.Takeprofit);
  439.                order.Stoploss = sl;
  440.             }
  441.          }
  442.          if(checkout_denom > 0.0) {
  443.             double lots = AdjLots(order.Lots / checkout_denom);
  444.             if(lots < MinLots) lots = MinLots;
  445.             if(lots > order.Lots) lots = order.Lots;
  446.             if(CheckoutOrder(orderType, order.Ticket, lots)) {
  447.                PrintMessage(checkout_reason);
  448.                order.Lots -= lots;
  449.             }
  450.          }
  451.       }
  452.    }
  453. }
  454.  
  455. //+------------------------------------------------------------------+
  456. //| 動作チェック                                                      |
  457. //+------------------------------------------------------------------+
  458. void CheckBehavior(bool nextTimed)
  459. {
  460.    if(Compounding) {
  461.       double balance = AccountInfoDouble(ACCOUNT_BALANCE);
  462.       if(BalanceIncludeCredit) balance += AccountInfoDouble(ACCOUNT_CREDIT);
  463.       Lots = balance * BaseLots / CompoundingBase;
  464.       if(Lots < MinLots) Lots = MinLots;
  465.       if(Lots > MaxLots) Lots = MaxLots;
  466.    }
  467.  
  468.    STATUS BuyStatus, SellStatus;
  469.    CheckStatus(OP_BUY,  MAGICMA, &BuyStatus);
  470.    CheckStatus(OP_SELL, MAGICMA, &SellStatus);
  471.  
  472.    double curAmount    = BuyStatus.GrossProfit + SellStatus.GrossProfit;
  473.    int    curPositions = BuyStatus.Positions   + SellStatus.Positions;
  474.    UpdateAmount(curAmount, curPositions);
  475.  
  476.    if(Automation) {
  477.       if(curAmount < 0) {
  478.          double balance = AccountInfoDouble(ACCOUNT_BALANCE);
  479.          if(BalanceIncludeCredit) balance += AccountInfoDouble(ACCOUNT_CREDIT);
  480.          if(balance * MaxGrosslossPer / 100.0 < -curAmount) {
  481.             CheckoutOrderAll(FLAG_BUY | FLAG_SELL);
  482.             PrintMessage("Check-out orders by over Maximum Gross Loss");
  483.             return;
  484.          }
  485.       }
  486.       ProcessOrders(nextTimed, ORDER_TYPE_BUY,  BuyStatus,  SellStatus);
  487.       ProcessOrders(nextTimed, ORDER_TYPE_SELL, SellStatus, BuyStatus);
  488.    }
  489.    FlushTL = false;
  490. }
  491.  
  492. //+------------------------------------------------------------------+
  493. //| OnInit                                                            |
  494. //+------------------------------------------------------------------+
  495. int OnInit()
  496. {
  497.  
  498.    //--- IQueue MA 初期化(3本分)
  499.    int qsize = MA3SlowPeriod * 3; // 余裕を持ったキューサイズ
  500.    if(!gFastMA.Init  (_Symbol, MainTimeFrame, MA3FastPeriod,   MAMode, MAPriceType, qsize) ||
  501.       !gMediumMA.Init(_Symbol, MainTimeFrame, MA3MediumPeriod, MAMode, MAPriceType, qsize) ||
  502.       !gSlowMA.Init  (_Symbol, MainTimeFrame, MA3SlowPeriod,   MAMode, MAPriceType, qsize))
  503.       return INIT_FAILED;
  504.  
  505.    //--- IQueue ATR 14 (デバッグ用)
  506.    if(!gATR14.Init     (_Symbol, PERIOD_CURRENT, 14, 2))
  507.      return INIT_FAILED;
  508.  
  509.    CurTime  = MainTime();
  510.    TimeTick = CancelTime = StartTime = UserTime = BaseTime(TimeBase);
  511.    Lots     = AdjLots(BaseLots);
  512.    PrevBid  = GetBid();
  513.    PrevAsk  = GetAsk();
  514.  
  515.    GlobalSettings(
  516.      ENTRY_NAME,
  517.      Slippage,
  518.      Spread,
  519.      ORDER_RETRY,
  520.      ORDER_RETRY_SLEEP,
  521.      ORDER_RETRY_DURATION );
  522.  
  523.    //--- UI オブジェクト作成
  524.    if(DBGMODE) {
  525.       ObjectCreate(0, DBGINFO_NAME, OBJ_LABEL, 0, 0, 0);
  526.       ObjectSetInteger(0, DBGINFO_NAME, OBJPROP_XDISTANCE, 10);
  527.       ObjectSetInteger(0, DBGINFO_NAME, OBJPROP_YDISTANCE, 15);
  528.       ObjectSetInteger(0, DBGINFO_NAME, OBJPROP_CORNER, CORNER_RIGHT_LOWER);
  529.       ObjectSetInteger(0, DBGINFO_NAME, OBJPROP_ANCHOR, ANCHOR_RIGHT_LOWER);
  530.       ObjectSetString (0, DBGINFO_NAME, OBJPROP_TEXT, "DEBUG INFO");
  531.       ObjectSetString (0, DBGINFO_NAME, OBJPROP_FONT, "Verdana");
  532.       ObjectSetInteger(0, DBGINFO_NAME, OBJPROP_FONTSIZE, 8);
  533.       ObjectSetInteger(0, DBGINFO_NAME, OBJPROP_COLOR, clrAquamarine);
  534.    }
  535.    if(ShowAmount) {
  536.       ObjectCreate(0, AMOUNT_NAME, OBJ_LABEL, 0, 0, 0);
  537.       ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_XDISTANCE, 20);
  538.       ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_YDISTANCE, 35);
  539.       ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_CORNER, CORNER_RIGHT_LOWER);
  540.       ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_ANCHOR, ANCHOR_RIGHT_LOWER);
  541.       ObjectSetString (0, AMOUNT_NAME, OBJPROP_TEXT, "0-");
  542.       ObjectSetString (0, AMOUNT_NAME, OBJPROP_FONT, "Verdana");
  543.       ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_FONTSIZE, 15);
  544.       ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_COLOR, ClrAmountPosi);
  545.    }
  546.    if(ShowUserEntry) {
  547.       ObjectCreate(0, SELLBTN_NAME, OBJ_BUTTON, 0, 0, 0);
  548.       ObjectSetInteger(0, SELLBTN_NAME, OBJPROP_XDISTANCE, 10);
  549.       ObjectSetInteger(0, SELLBTN_NAME, OBJPROP_YDISTANCE, 20);
  550.       ObjectSetInteger(0, SELLBTN_NAME, OBJPROP_XSIZE, 58);
  551.       ObjectSetInteger(0, SELLBTN_NAME, OBJPROP_YSIZE, 32);
  552.       ObjectSetInteger(0, SELLBTN_NAME, OBJPROP_CORNER, CORNER_LEFT_UPPER);
  553.       ObjectSetInteger(0, SELLBTN_NAME, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER);
  554.       ObjectSetInteger(0, SELLBTN_NAME, OBJPROP_FONTSIZE, 12);
  555.       ObjectSetInteger(0, SELLBTN_NAME, OBJPROP_COLOR, clrWhite);
  556.       ObjectSetInteger(0, SELLBTN_NAME, OBJPROP_BGCOLOR, clrFireBrick);
  557.       ObjectSetString (0, SELLBTN_NAME, OBJPROP_TEXT, "SELL");
  558.       ObjectSetString (0, SELLBTN_NAME, OBJPROP_FONT, "Verdana");
  559.  
  560.       ObjectCreate(0, BUYBTN_NAME, OBJ_BUTTON, 0, 0, 0);
  561.       ObjectSetInteger(0, BUYBTN_NAME, OBJPROP_XDISTANCE, 70);
  562.       ObjectSetInteger(0, BUYBTN_NAME, OBJPROP_YDISTANCE, 20);
  563.       ObjectSetInteger(0, BUYBTN_NAME, OBJPROP_XSIZE, 58);
  564.       ObjectSetInteger(0, BUYBTN_NAME, OBJPROP_YSIZE, 32);
  565.       ObjectSetInteger(0, BUYBTN_NAME, OBJPROP_CORNER, CORNER_LEFT_UPPER);
  566.       ObjectSetInteger(0, BUYBTN_NAME, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER);
  567.       ObjectSetInteger(0, BUYBTN_NAME, OBJPROP_FONTSIZE, 12);
  568.       ObjectSetInteger(0, BUYBTN_NAME, OBJPROP_COLOR, clrWhite);
  569.       ObjectSetInteger(0, BUYBTN_NAME, OBJPROP_BGCOLOR, clrRoyalBlue);
  570.       ObjectSetString (0, BUYBTN_NAME, OBJPROP_TEXT, "BUY");
  571.       ObjectSetString (0, BUYBTN_NAME, OBJPROP_FONT, "Verdana");
  572.    }
  573.  
  574.    int btn_ofs_x = 0;
  575.    const int btn_distance = 102;
  576.    if(ShowCloseAll) {
  577.       ObjectCreate(0, CLOSEALLBTN_NAME, OBJ_BUTTON, 0, 0, 0);
  578.       ObjectSetInteger(0, CLOSEALLBTN_NAME, OBJPROP_XDISTANCE, 10 + btn_ofs_x);
  579.       ObjectSetInteger(0, CLOSEALLBTN_NAME, OBJPROP_YDISTANCE, 35);
  580.       ObjectSetInteger(0, CLOSEALLBTN_NAME, OBJPROP_XSIZE, 100);
  581.       ObjectSetInteger(0, CLOSEALLBTN_NAME, OBJPROP_YSIZE, 25);
  582.       ObjectSetInteger(0, CLOSEALLBTN_NAME, OBJPROP_CORNER, CORNER_LEFT_LOWER);
  583.       ObjectSetInteger(0, CLOSEALLBTN_NAME, OBJPROP_ANCHOR, ANCHOR_LEFT_LOWER);
  584.       ObjectSetInteger(0, CLOSEALLBTN_NAME, OBJPROP_FONTSIZE, 10);
  585.       ObjectSetInteger(0, CLOSEALLBTN_NAME, OBJPROP_COLOR, clrWhite);
  586.       ObjectSetInteger(0, CLOSEALLBTN_NAME, OBJPROP_BGCOLOR, clrDarkSlateGray);
  587.       ObjectSetString (0, CLOSEALLBTN_NAME, OBJPROP_TEXT, "CLOSE ALL");
  588.       ObjectSetString (0, CLOSEALLBTN_NAME, OBJPROP_FONT, "Verdana");
  589.       btn_ofs_x += btn_distance;
  590.    }
  591.    if(ShowCloseLong) {
  592.       ObjectCreate(0, CLOSELONGBTN_NAME, OBJ_BUTTON, 0, 0, 0);
  593.       ObjectSetInteger(0, CLOSELONGBTN_NAME, OBJPROP_XDISTANCE, 10 + btn_ofs_x);
  594.       ObjectSetInteger(0, CLOSELONGBTN_NAME, OBJPROP_YDISTANCE, 35);
  595.       ObjectSetInteger(0, CLOSELONGBTN_NAME, OBJPROP_XSIZE, 100);
  596.       ObjectSetInteger(0, CLOSELONGBTN_NAME, OBJPROP_YSIZE, 25);
  597.       ObjectSetInteger(0, CLOSELONGBTN_NAME, OBJPROP_CORNER, CORNER_LEFT_LOWER);
  598.       ObjectSetInteger(0, CLOSELONGBTN_NAME, OBJPROP_ANCHOR, ANCHOR_LEFT_LOWER);
  599.       ObjectSetInteger(0, CLOSELONGBTN_NAME, OBJPROP_FONTSIZE, 10);
  600.       ObjectSetInteger(0, CLOSELONGBTN_NAME, OBJPROP_COLOR, clrWhite);
  601.       ObjectSetInteger(0, CLOSELONGBTN_NAME, OBJPROP_BGCOLOR, clrRoyalBlue);
  602.       ObjectSetString (0, CLOSELONGBTN_NAME, OBJPROP_TEXT, "CLOSE LONG");
  603.       ObjectSetString (0, CLOSELONGBTN_NAME, OBJPROP_FONT, "Verdana");
  604.       btn_ofs_x += btn_distance;
  605.    }
  606.    if(ShowCloseShort) {
  607.       ObjectCreate(0, CLOSESHORTBTN_NAME, OBJ_BUTTON, 0, 0, 0);
  608.       ObjectSetInteger(0, CLOSESHORTBTN_NAME, OBJPROP_XDISTANCE, 10 + btn_ofs_x);
  609.       ObjectSetInteger(0, CLOSESHORTBTN_NAME, OBJPROP_YDISTANCE, 35);
  610.       ObjectSetInteger(0, CLOSESHORTBTN_NAME, OBJPROP_XSIZE, 100);
  611.       ObjectSetInteger(0, CLOSESHORTBTN_NAME, OBJPROP_YSIZE, 25);
  612.       ObjectSetInteger(0, CLOSESHORTBTN_NAME, OBJPROP_CORNER, CORNER_LEFT_LOWER);
  613.       ObjectSetInteger(0, CLOSESHORTBTN_NAME, OBJPROP_ANCHOR, ANCHOR_LEFT_LOWER);
  614.       ObjectSetInteger(0, CLOSESHORTBTN_NAME, OBJPROP_FONTSIZE, 10);
  615.       ObjectSetInteger(0, CLOSESHORTBTN_NAME, OBJPROP_COLOR, clrWhite);
  616.       ObjectSetInteger(0, CLOSESHORTBTN_NAME, OBJPROP_BGCOLOR, clrFireBrick);
  617.       ObjectSetString (0, CLOSESHORTBTN_NAME, OBJPROP_TEXT, "CLOSE SHORT");
  618.       ObjectSetString (0, CLOSESHORTBTN_NAME, OBJPROP_FONT, "Verdana");
  619.       btn_ofs_x += btn_distance;
  620.    }
  621.    if(ShowFlushTL) {
  622.       ObjectCreate(0, FLUSHTLBTN_NAME, OBJ_BUTTON, 0, 0, 0);
  623.       ObjectSetInteger(0, FLUSHTLBTN_NAME, OBJPROP_XDISTANCE, 10 + btn_ofs_x);
  624.       ObjectSetInteger(0, FLUSHTLBTN_NAME, OBJPROP_YDISTANCE, 35);
  625.       ObjectSetInteger(0, FLUSHTLBTN_NAME, OBJPROP_XSIZE, 100);
  626.       ObjectSetInteger(0, FLUSHTLBTN_NAME, OBJPROP_YSIZE, 25);
  627.       ObjectSetInteger(0, FLUSHTLBTN_NAME, OBJPROP_CORNER, CORNER_LEFT_LOWER);
  628.       ObjectSetInteger(0, FLUSHTLBTN_NAME, OBJPROP_ANCHOR, ANCHOR_LEFT_LOWER);
  629.       ObjectSetInteger(0, FLUSHTLBTN_NAME, OBJPROP_FONTSIZE, 10);
  630.       ObjectSetInteger(0, FLUSHTLBTN_NAME, OBJPROP_COLOR, clrWhite);
  631.       ObjectSetInteger(0, FLUSHTLBTN_NAME, OBJPROP_BGCOLOR, clrDarkSlateBlue);
  632.       ObjectSetString (0, FLUSHTLBTN_NAME, OBJPROP_TEXT, "FLUSH TL");
  633.       ObjectSetString (0, FLUSHTLBTN_NAME, OBJPROP_FONT, "Verdana");
  634.    }
  635.  
  636.    UserEntry = 0;
  637.    return INIT_SUCCEEDED;
  638. }
  639.  
  640. //+------------------------------------------------------------------+
  641. //| OnDeinit                                                          |
  642. //+------------------------------------------------------------------+
  643. void OnDeinit(const int reason)
  644. {
  645.    if(ShowFlushTL)   ObjectDelete(0, FLUSHTLBTN_NAME);
  646.    if(ShowCloseShort) ObjectDelete(0, CLOSESHORTBTN_NAME);
  647.    if(ShowCloseLong)  ObjectDelete(0, CLOSELONGBTN_NAME);
  648.    if(ShowCloseAll)   ObjectDelete(0, CLOSEALLBTN_NAME);
  649.    if(ShowUserEntry)  { ObjectDelete(0, BUYBTN_NAME); ObjectDelete(0, SELLBTN_NAME); }
  650.    if(OffTimeVisible) { ObjectDelete(0, OFFTIME_NAME); OffTimeVisible = false; }
  651.    if(ShowAmount)     ObjectDelete(0, AMOUNT_NAME);
  652.    if(DBGMODE)        ObjectDelete(0, DBGINFO_NAME);
  653. }
  654.  
  655. //+------------------------------------------------------------------+
  656. //| OnTick                                                            |
  657. //+------------------------------------------------------------------+
  658. void OnTick()
  659. {
  660.    //--- IQueue を更新
  661.    gFastMA.Update();
  662.    gMediumMA.Update();
  663.    gSlowMA.Update();
  664.    gATR14.Update();
  665.  
  666.    datetime nextTime  = MainTime();
  667.    bool     nextTimed = (nextTime != CurTime);
  668.    CurTime  = nextTime;
  669.  
  670.    datetime nextTick  = BaseTime(TimeBase);
  671.    bool     nextTicked = (nextTick != TimeTick);
  672.    TimeTick = nextTick;
  673.  
  674.    CheckTimeControl(nextTicked);
  675.    CheckBehavior(nextTimed);
  676.  
  677.    double bid    = GetBid(), ask = GetAsk();
  678.    double atr14  = gATR14[0];
  679.    double spread = ask - bid;
  680.  
  681.    if(DBGMODE) {
  682.       DBGOUT(
  683.          StringFormat("ATR(14): %.3f", atr14/_Point) + " | " +
  684.          StringFormat("SPREAD: %g",    spread/_Point) + " | " +
  685.          StringFormat("ATR(14)/SPREAD: %.3f", atr14/(spread<=0?1:spread))
  686.       );
  687.    }
  688.  
  689.    // エントリー処理
  690.    if(AccountInfoInteger(ACCOUNT_TRADE_EXPERT) && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) {
  691.       int busy = AlreadyOrdered(FLAG_BUY|FLAG_SELL, MAGICMA);
  692.       if(UserEntry && TimeTick - UserTime < 60) {
  693.          int user = UserEntry;
  694.          if(user) {
  695.             ENUM_ORDER_TYPE entry = (user == FLAG_BUY) ? ORDER_TYPE_BUY : ORDER_TYPE_SELL;
  696.             if(EntryManualPosition("USER", entry, Lots) > 0)
  697.               busy |= user;
  698.             else
  699.               PlaySound("timeout.wav"); // 約定失敗
  700.             UserEntry = 0;
  701.          }
  702.       } else { UserEntry = 0; }
  703.    } else {
  704.       if(StartTime - TimeTick < 10) StartTime = TimeTick + 10;
  705.    }
  706.  
  707.    PrevBid = bid; PrevAsk = ask;
  708. }
  709.  
  710. //+------------------------------------------------------------------+
  711. //| OnChartEvent                                                      |
  712. //+------------------------------------------------------------------+
  713. void OnChartEvent(const int id, const long &lparam,
  714.                   const double &dparam, const string &sparam)
  715. {
  716.    if(id == CHARTEVENT_OBJECT_CLICK) {
  717.       if(sparam == CLOSEALLBTN_NAME || sparam == CLOSELONGBTN_NAME || sparam == CLOSESHORTBTN_NAME) {
  718.          int flag = 0;
  719.          if(sparam == CLOSEALLBTN_NAME)   flag = FLAG_SELL|FLAG_BUY;
  720.          else if(sparam == CLOSELONGBTN_NAME)  flag = FLAG_BUY;
  721.          else if(sparam == CLOSESHORTBTN_NAME) flag = FLAG_SELL;
  722.          CheckoutOrderAll(flag);
  723.          Sleep(100);
  724.          ObjectSetInteger(0, sparam, OBJPROP_STATE, false);
  725.          CancelTime = TimeTick + 60;
  726.       }
  727.       if(sparam == FLUSHTLBTN_NAME) {
  728.          FlushTL = true;
  729.          Sleep(100);
  730.          ObjectSetInteger(0, FLUSHTLBTN_NAME, OBJPROP_STATE, false);
  731.       }
  732.       if(sparam == SELLBTN_NAME) {
  733.          UserEntry = FLAG_SELL; CancelTime = UserTime = TimeTick; CancelTime += 60;
  734.          Sleep(100);
  735.          ObjectSetInteger(0, SELLBTN_NAME, OBJPROP_STATE, false);
  736.       }
  737.       if(sparam == BUYBTN_NAME) {
  738.          UserEntry = FLAG_BUY; CancelTime = UserTime = TimeTick; CancelTime += 60;
  739.          Sleep(100);
  740.          ObjectSetInteger(0, BUYBTN_NAME, OBJPROP_STATE, false);
  741.       }
  742.    }
  743. }
  744. //+------------------------------------------------------------------+
  745.  
Tags: ea Mt5
Advertisement
Add Comment
Please, Sign In to add comment