HYROLEAN

test_pyramid.mq4

Oct 15th, 2024 (edited)
334
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 40.04 KB | Source Code | 0 0
  1. #property copyright "2024, (c)hyrolean"
  2. #property link      "https://pastebin.com/dJRkQMJp"
  3. #property version   "1.09"
  4. #property strict
  5.  
  6.   //順張りピラミッティングするEAのサンプル
  7.  
  8.   //ver1.09
  9.   //・常に利確出来る位置にピラミッテングを行う PyramidingKeepBorder オプションを追加
  10.   //ver1.08
  11.   //・デバッグ情報を表示するサンプル DEBUG MODE 機能を追加
  12.   //ver1.07
  13.   //・最後に利確または損切した金額をチャートに表示したままにしておく仕様に変更
  14.   //ver1.06
  15.   //・タイムコントロールのベース時間を"GMT/Local/Server"から選んで切替られる TimeBase オプションを追加
  16.   //ver1.05
  17.   //・TimeAction の Close All Positions 系の処理の動作が上手く働いていなかったバグを修正
  18.   //ver1.04
  19.   //・活動時間を制御するタイムコントロール機能を追加
  20.   //ver1.03
  21.   //・PyramidingScaleに1.0よりも大きい値を設定するとピラミッティングしないバグを修正
  22.   //・自動注文 2RSI Detector 機能を追加
  23.   //ver1.02
  24.   //・MoveStoploss有効時にショートしか機能が働かなくなっていたバグを修正
  25.   //ver1.01
  26.   //・MoveStoploss有効時に機能がまったく働かなくなっていたバグを修正
  27.  
  28. /*
  29.   このEAを、指標で使う場合には、以下のように設定してください。
  30.   1) Active Entry Positions を Stop にします。EAの自動ポジション打ちを止めることができます。
  31.   2) Auto Move stop loss to safe position を false にして、sl値の自動更新を止めます。
  32.   3) Pyramiding lots Multiplier を 1.0 より多少大きな値にします。
  33.   次に、左上の|SELL|BUY|ボタンを選んでポジションを自分で打ちます。
  34.   ポジションを打ったら、sl(ストップロス)のBARを自分の好みの場所に移動させます。
  35.   以降、ピラミッティングのslはこのsl値の位置に統一されて張られていきます。
  36.   指標の動きが止まったら、|CLOSE ALL|で利確すれば完了です。
  37.   tpの値の計算式は、PyramidingStrideが40、PyramidingTimesが20、Takeprofitの値が100の場合、
  38.   tp=40*20+100=900points(90.0pips)になります。自動利確を的確に予測して確実のものとするには、
  39.   この計算式を参考にしてください。(PyramidingStrideが40だからといって、必ず40pointsごとに
  40.   ピラミッティグされるのではなく、タイミングがズレるとマージン(空き)が発生します。実際には90pipsよりも
  41.   上の値にtpが来ることになります。)
  42. */
  43.  
  44. enum ENUM_POSI {
  45.   POSI_STOP,                  // Stop
  46.   POSI_LONG_ONLY,             // Only Long
  47.   POSI_SHORT_ONLY,            // Only Short
  48.   POSI_HALF_LONG_AND_SHORT,   // Long & Short (Half duplex)
  49.   POSI_FULL_LONG_AND_SHORT    // Long & Short (Full duplex)
  50. };
  51.  
  52. enum ENUM_TIMEBASE {
  53.   TIMEBASE_GMT,               // Greenwich Mean Time (GMT)
  54.   TIMEBASE_LOCAL,             // Local Time
  55.   TIMEBASE_SERVER             // Server Time
  56. };
  57.  
  58. enum ENUM_TIMEACT {
  59.   TIMEACT_NONE,               // None
  60.   TIMEACT_FORCE_CLOSE_ALL,    // Force Close All positions
  61.   TIMEACT_FORCE_CLOSE_LONG,   // Force Close Long positions
  62.   TIMEACT_FORCE_CLOSE_SHORT,  // Force Close Short positions
  63.   TIMEACT_SOFT_CLOSE_ALL,     // Close All positions if profits are Positive
  64.   TIMEACT_SOFT_CLOSE_LONG,    // Close Long positions if profits are Positive
  65.   TIMEACT_SOFT_CLOSE_SHORT    // Close Short positions if profits are Positive
  66. };
  67.  
  68. input ENUM_POSI ActivePositions = POSI_FULL_LONG_AND_SHORT; // Active Entry Positions
  69. input int       MAGICMA         = 35853;   // Magic Number
  70. input bool      TimeControl     = false;   // Time Control
  71. input ENUM_TIMEBASE TimeBase    = TIMEBASE_LOCAL; // Time Base
  72. input string    TimeStart       = "09:00"; // Time Start
  73. input string    TimeEnd         = "15:00"; // Time End
  74. input ENUM_TIMEACT TimeAction   = TIMEACT_NONE; // Time Action when time end reached
  75. input int       Slippage        = 10;      // Max slippage
  76. input double    Spread          = 50;      // Max spread in points
  77. input double    BaseLots        = 0.06;    // Base lots
  78. input double    MinLots         = 0.01;    // Minimum lots
  79. input double    MaxLots         = 1000.0;  // Maximum lots
  80. input double    Takeprofit      = 100;     // Take profit in points
  81. input double    Stoploss        = 500;     // Stop loss in points
  82. input double    ProfitRatePer   = 50.0;    // Profit Rate in percentage
  83. input bool      MoveStoploss    = true;    // Auto Move stop loss to safe position
  84. input double    StoplossPadding = 100.0;   // Auto move stop loss safe Padding in points
  85. input double    PyramidingStride= 40.0;    // Pyramiding price Stride in points
  86. input double    PyramidingScale = 0.9;     // Pyramiding lots Multiplier
  87. input int       PyramidingTimes = 20;      // Pyramiding max Positions (0=infinite)
  88. input int       PyramidingInterval=0;      // Pyramiding Interval in sec (0=continuous)
  89. input bool      PyramidingKeepBorder=false;// Pyramiding to Keep Border of over profit+padding
  90. input bool      RSI2Detector    = true;    // Detector 2RSI Enabled
  91. input ENUM_TIMEFRAMES RSI2TimeFrame=PERIOD_M5; // Detector 2RSI Time Frame
  92. input int       RSI2FastPeriod  = 13;      // Detector 2RSI Fast period
  93. input int       RSI2SlowPeriod  = 42;      // Detector 2RSI Slow period
  94. input int       RSI2Duration    = 5;       // Detector 2RSI Duration
  95. input double    RSI2Distance    = 20;      // Detector 2RSI Distance
  96. input double    RSI2UpBorder    = 90;      // Detector 2RSI Up border
  97. input double    RSI2DownBorder  = 10;      // Detector 2RSI Down border
  98. input ENUM_APPLIED_PRICE RSI2PriceType = PRICE_CLOSE; // Detector 2RSI Price type
  99. input bool      ShowUserEntry   = true;    // Show user entry SELL/BUY buttons
  100. input bool      ShowCloseAll    = true;    // Show a CLOSE ALL button
  101. input bool      ShowCloseLong   = false;   // Show a CLOSE LONG button
  102. input bool      ShowCloseShort  = false;   // Show a CLOSE SHORT button
  103. input bool      ShowAmount      = true;    // Show Current Amount
  104. input int       AmountDig       = 0;       // Amount Number of decimal places
  105. input bool      DBGMODE         = false;   // DEBUG MODE
  106.  
  107. double Lots;
  108.  
  109. bool PmdTiming=false;
  110. datetime CurTime, CurPmdInt, TimeTick, StartTime, CancelTime, UserTime;
  111.  
  112. #define ORDER_RETRY  10
  113.  
  114. #define FLAG_BUY      1
  115. #define FLAG_SELL     2
  116. #define FLAG_DUPLEX   4
  117.  
  118. int PositionFlag = FLAG_BUY | FLAG_SELL | FLAG_DUPLEX ;
  119. int UserEntry = 0 ;
  120.  
  121. #define SELLBTN_NAME       "EntrySell"
  122. #define BUYBTN_NAME        "EntryBuy"
  123. #define CLOSEALLBTN_NAME   "CloseAll"
  124. #define CLOSELONGBTN_NAME  "CloseLong"
  125. #define CLOSESHORTBTN_NAME "CloseShort"
  126.  
  127. #define BUYBORDER_NAME "LONG BORDER"
  128. #define SELLBORDER_NAME "SHORT BORDER"
  129. bool BuyBorderLined = false, SellBorderLined = false ;
  130.  
  131. #define OFFTIME_NAME "OFF TIME"
  132. bool OffTimeVisible = false ;
  133.  
  134. #define AMOUNT_NAME "AMOUNT"
  135. #define AMOUNT_CLR_NEGA  clrLightPink
  136. #define AMOUNT_CLR_POSI  clrLightGoldenrod
  137.  
  138. #define DBGINFO_NAME "DEBUG INFO"
  139.  
  140. //---------------------------------------------------------------------------
  141. int OnInit()
  142. {
  143.   CurTime = Time[0];
  144.   CurPmdInt = TimeTick = CancelTime = StartTime = UserTime = BaseTime();
  145.  
  146.   Lots = BaseLots ;
  147.   if(Lots<MinLots) Lots = MinLots ;
  148.   if(Lots>MaxLots) Lots = MaxLots ;
  149.  
  150.   DeleteBorderLines() ;
  151.  
  152.   DrawBorderLine(OP_BUY);
  153.   DrawBorderLine(OP_SELL);
  154.  
  155.   // エントリできるポジションの確認
  156.   switch(ActivePositions) {
  157.     case POSI_STOP:                  // Stop
  158.       PositionFlag = 0 ;
  159.       break;
  160.     case POSI_LONG_ONLY:             // Only Long
  161.       PositionFlag = FLAG_BUY ;
  162.       break;
  163.     case POSI_SHORT_ONLY:            // Only Short
  164.       PositionFlag = FLAG_SELL ;
  165.       break;
  166.     case POSI_HALF_LONG_AND_SHORT:   // Long & Short (Half Duplex)
  167.       PositionFlag = FLAG_BUY | FLAG_SELL ;
  168.       break;
  169.     case POSI_FULL_LONG_AND_SHORT:   // Long & Short (Full Duplex)
  170.       PositionFlag = FLAG_BUY | FLAG_SELL | FLAG_DUPLEX ;
  171.       break;
  172.   }
  173.  
  174.   //DEBUG INFO
  175.   if(DBGMODE) {
  176.     ObjectCreate(DBGINFO_NAME, OBJ_LABEL, 0, 0, 0);
  177.     ObjectSet(DBGINFO_NAME, OBJPROP_XDISTANCE, 10);
  178.     ObjectSet(DBGINFO_NAME, OBJPROP_YDISTANCE, 15);
  179.     ObjectSet(DBGINFO_NAME, OBJPROP_CORNER, 3);
  180.     ObjectSetString(0, DBGINFO_NAME, OBJPROP_TEXT, "DEBUG INFO");
  181.     ObjectSetString(0, DBGINFO_NAME, OBJPROP_FONT, "Verdana");
  182.     ObjectSetInteger(0, DBGINFO_NAME, OBJPROP_FONTSIZE, 8);
  183.     ObjectSetInteger(0, DBGINFO_NAME, OBJPROP_COLOR, clrAquamarine);
  184.   }
  185.  
  186.   //金額表示
  187.   if(ShowAmount) {
  188.     ObjectCreate(AMOUNT_NAME, OBJ_LABEL, 0, 0, 0);
  189.     ObjectSet(AMOUNT_NAME, OBJPROP_XDISTANCE, 20);
  190.     ObjectSet(AMOUNT_NAME, OBJPROP_YDISTANCE, 35);
  191.     ObjectSet(AMOUNT_NAME, OBJPROP_CORNER, 3);
  192.     ObjectSetString(0, AMOUNT_NAME, OBJPROP_TEXT, "0-");
  193.     ObjectSetString(0, AMOUNT_NAME, OBJPROP_FONT, "Verdana");
  194.     ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_FONTSIZE, 15);
  195.     ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_COLOR, AMOUNT_CLR_POSI);
  196.   }
  197.  
  198.   //ユーザーエントリ用ボタン
  199.   if(ShowUserEntry) {
  200.  
  201.     //SELLボタン
  202.     ObjectCreate(SELLBTN_NAME, OBJ_BUTTON, 0, 0, 0);
  203.     ObjectSet(SELLBTN_NAME, OBJPROP_XDISTANCE, 10);
  204.     ObjectSet(SELLBTN_NAME, OBJPROP_YDISTANCE, 20);
  205.     ObjectSet(SELLBTN_NAME, OBJPROP_XSIZE, 58);
  206.     ObjectSet(SELLBTN_NAME, OBJPROP_YSIZE, 32);
  207.     ObjectSet(SELLBTN_NAME, OBJPROP_CORNER, 0);
  208.     ObjectSet(SELLBTN_NAME, OBJPROP_FONTSIZE, 12);
  209.     ObjectSet(SELLBTN_NAME, OBJPROP_COLOR, White);
  210.     ObjectSet(SELLBTN_NAME, OBJPROP_BGCOLOR, clrFireBrick);
  211.     ObjectSetString(0, SELLBTN_NAME, OBJPROP_TEXT, "SELL");
  212.     ObjectSetString(0, SELLBTN_NAME, OBJPROP_FONT, "Verdana");
  213.  
  214.     //BUYボタン
  215.     ObjectCreate(BUYBTN_NAME, OBJ_BUTTON, 0, 0, 0);
  216.     ObjectSet(BUYBTN_NAME, OBJPROP_XDISTANCE, 70);
  217.     ObjectSet(BUYBTN_NAME, OBJPROP_YDISTANCE, 20);
  218.     ObjectSet(BUYBTN_NAME, OBJPROP_XSIZE, 58);
  219.     ObjectSet(BUYBTN_NAME, OBJPROP_YSIZE, 32);
  220.     ObjectSet(BUYBTN_NAME, OBJPROP_CORNER, 0);
  221.     ObjectSet(BUYBTN_NAME, OBJPROP_FONTSIZE, 12);
  222.     ObjectSet(BUYBTN_NAME, OBJPROP_COLOR, White);
  223.     ObjectSet(BUYBTN_NAME, OBJPROP_BGCOLOR, clrRoyalBlue);
  224.     ObjectSetString(0, BUYBTN_NAME, OBJPROP_TEXT, "BUY");
  225.     ObjectSetString(0, BUYBTN_NAME, OBJPROP_FONT, "Verdana");
  226.  
  227.   }
  228.  
  229.   int btn_ofs_x = 0 ;
  230.   const int btn_distance = 102 ;
  231.  
  232.   //全決済ボタン
  233.   if(ShowCloseAll) {
  234.     ObjectCreate(CLOSEALLBTN_NAME, OBJ_BUTTON, 0, 0, 0);
  235.     ObjectSet(CLOSEALLBTN_NAME, OBJPROP_XDISTANCE, 10 + btn_ofs_x );
  236.     ObjectSet(CLOSEALLBTN_NAME, OBJPROP_YDISTANCE, 35);
  237.     ObjectSet(CLOSEALLBTN_NAME, OBJPROP_XSIZE, 100);
  238.     ObjectSet(CLOSEALLBTN_NAME, OBJPROP_YSIZE, 25);
  239.     ObjectSet(CLOSEALLBTN_NAME, OBJPROP_CORNER, 2);
  240.     ObjectSet(CLOSEALLBTN_NAME, OBJPROP_FONTSIZE, 10);
  241.     ObjectSet(CLOSEALLBTN_NAME, OBJPROP_COLOR, White);
  242.     ObjectSet(CLOSEALLBTN_NAME, OBJPROP_BGCOLOR, /*clrDarkGreen*/clrDarkSlateGray);
  243.     ObjectSetString(0, CLOSEALLBTN_NAME, OBJPROP_TEXT, "CLOSE ALL");
  244.     ObjectSetString(0, CLOSEALLBTN_NAME, OBJPROP_FONT, "Verdana");
  245.     btn_ofs_x += btn_distance ;
  246.   }
  247.  
  248.   //LONG決済ボタン
  249.   if(ShowCloseLong) {
  250.     ObjectCreate(CLOSELONGBTN_NAME, OBJ_BUTTON, 0, 0, 0);
  251.     ObjectSet(CLOSELONGBTN_NAME, OBJPROP_XDISTANCE, 10 + btn_ofs_x );
  252.     ObjectSet(CLOSELONGBTN_NAME, OBJPROP_YDISTANCE, 35);
  253.     ObjectSet(CLOSELONGBTN_NAME, OBJPROP_XSIZE, 100);
  254.     ObjectSet(CLOSELONGBTN_NAME, OBJPROP_YSIZE, 25);
  255.     ObjectSet(CLOSELONGBTN_NAME, OBJPROP_CORNER, 2);
  256.     ObjectSet(CLOSELONGBTN_NAME, OBJPROP_FONTSIZE, 10);
  257.     ObjectSet(CLOSELONGBTN_NAME, OBJPROP_COLOR, White);
  258.     ObjectSet(CLOSELONGBTN_NAME, OBJPROP_BGCOLOR, clrRoyalBlue);
  259.     ObjectSetString(0, CLOSELONGBTN_NAME, OBJPROP_TEXT, "CLOSE LONG");
  260.     ObjectSetString(0, CLOSELONGBTN_NAME, OBJPROP_FONT, "Verdana");
  261.     btn_ofs_x += btn_distance ;
  262.   }
  263.  
  264.   //SHORT決済ボタン
  265.   if(ShowCloseShort) {
  266.     ObjectCreate(CLOSESHORTBTN_NAME, OBJ_BUTTON, 0, 0, 0);
  267.     ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_XDISTANCE, 10 + btn_ofs_x );
  268.     ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_YDISTANCE, 35);
  269.     ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_XSIZE, 100);
  270.     ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_YSIZE, 25);
  271.     ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_CORNER, 2);
  272.     ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_FONTSIZE, 10);
  273.     ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_COLOR, White);
  274.     ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_BGCOLOR, clrFireBrick);
  275.     ObjectSetString(0, CLOSESHORTBTN_NAME, OBJPROP_TEXT, "CLOSE SHORT");
  276.     ObjectSetString(0, CLOSESHORTBTN_NAME, OBJPROP_FONT, "Verdana");
  277.     btn_ofs_x += btn_distance ;
  278.   }
  279.  
  280.   //ユーザーエントリをリセット
  281.   UserEntry=0;
  282.  
  283.   return(INIT_SUCCEEDED);
  284. }
  285. //---------------------------------------------------------------------------
  286. void OnDeinit(const int reason)
  287. {
  288.   if(ShowCloseShort) ObjectDelete(CLOSESHORTBTN_NAME) ;
  289.   if(ShowCloseLong) ObjectDelete(CLOSELONGBTN_NAME) ;
  290.   if(ShowCloseAll) ObjectDelete(CLOSEALLBTN_NAME) ;
  291.   if(ShowUserEntry) {
  292.     ObjectDelete(BUYBTN_NAME) ;
  293.     ObjectDelete(SELLBTN_NAME) ;
  294.   }
  295.   if(OffTimeVisible) {
  296.     ObjectDelete(OFFTIME_NAME) ;
  297.     OffTimeVisible=false ;
  298.   }
  299.   if(ShowAmount) {
  300.     ObjectDelete(AMOUNT_NAME) ;
  301.   }
  302.   if(DBGMODE) {
  303.     ObjectDelete(DBGINFO_NAME) ;
  304.   }
  305.   DeleteBorderLines() ;
  306. }
  307. //---------------------------------------------------------------------------
  308. void OnTick()
  309. {
  310.   datetime nextTime = Time[0] ;
  311.   bool nextTimed = nextTime != CurTime ;
  312.   CurTime = nextTime ;
  313.  
  314.   datetime nextTick = BaseTime() ;
  315.   bool nextTicked = nextTick != TimeTick ;
  316.   TimeTick = nextTick;
  317.  
  318.   // タイムコントロールチェック
  319.   CheckTimeControl(nextTicked);
  320.  
  321.   // 動作チェック
  322.   CheckBehavior(nextTimed);
  323.  
  324.   // デバッグ欄表示のサンプル
  325.   if(DBGMODE) {
  326.     double atr14 = iATR(NULL,0,14,0) ;
  327.     double spread = Ask-Bid ;
  328.     DBGOUT(
  329.       // ATR in points
  330.       StringFormat("ATR(14): %.3f",atr14/Point) + " | " +
  331.       // SPREAD in points
  332.       StringFormat("SPREAD: %g",spread/Point) + " | " +
  333.       // 現在の値幅の変動倍率(ATR/SPREAD)
  334.       StringFormat("ATR(14)/SPREAD: %.3f",atr14/spread)
  335.     );
  336.   }
  337.  
  338.   // エントリー処理
  339.  
  340.   int busy = AlreadyOrdered(FLAG_BUY|FLAG_SELL,MAGICMA) ;
  341.  
  342.   // ユーザーの注文
  343.   if(UserEntry) {
  344.  
  345.     // ユーザーのエントリを確認
  346.     if(TimeTick-UserTime<60) {  // 発行されてから60秒以内の注文
  347.  
  348.       int user = UserEntry ;
  349.  
  350.       // 注文
  351.       if(user&&!AlreadyOrdered(user,MAGICMA)) {
  352.  
  353.         int entry = user == FLAG_BUY ? OP_BUY : OP_SELL ;
  354.         EntryPosition("USER", entry, Lots);
  355.         busy |= user;
  356.  
  357.       }
  358.  
  359.     }
  360.  
  361.     UserEntry=0;
  362.   }
  363.  
  364.   // 自動注文 開始時間調整
  365.   if(StartTime>TimeTick||CancelTime>TimeTick)
  366.     return ;
  367.  
  368.   // 自動注文 2RSI Detector
  369.   if(RSI2Detector) EAEntryPosition("2RSI", CheckDetectorRSI2(), busy);
  370. }
  371. //---------------------------------------------------------------------------
  372. void OnChartEvent(
  373.   const int id,
  374.   const long &lparam,
  375.   const double &dparam,
  376.   const string &sparam
  377.  )
  378. {
  379.   if( ( sparam == CLOSEALLBTN_NAME ||
  380.         sparam == CLOSELONGBTN_NAME ||
  381.         sparam == CLOSESHORTBTN_NAME ) && id==CHARTEVENT_OBJECT_CLICK) {
  382.     int orderFlag = 0 ;
  383.     if(sparam == CLOSEALLBTN_NAME) orderFlag = FLAG_SELL | FLAG_BUY ;
  384.     else if(sparam == CLOSELONGBTN_NAME) orderFlag = FLAG_BUY ;
  385.     else if(sparam == CLOSESHORTBTN_NAME) orderFlag = FLAG_SELL ;
  386.     CheckoutOrderAll(orderFlag);
  387.     Sleep(100);
  388.     ObjectSet(sparam, OBJPROP_STATE, False);
  389.     // 60秒エントリーを停止する
  390.     CancelTime = TimeTick + 60 ;
  391.   }
  392.   if(sparam == SELLBTN_NAME && id==CHARTEVENT_OBJECT_CLICK) {
  393.     { UserEntry = FLAG_SELL ; CancelTime = UserTime = TimeTick ; CancelTime+=60 ; }
  394.     Sleep(100);
  395.     ObjectSet(SELLBTN_NAME, OBJPROP_STATE, False);
  396.   }
  397.   if(sparam == BUYBTN_NAME && id==CHARTEVENT_OBJECT_CLICK) {
  398.     { UserEntry = FLAG_BUY ; CancelTime = UserTime = TimeTick ; CancelTime+=60 ; }
  399.     Sleep(100);
  400.     ObjectSet(BUYBTN_NAME, OBJPROP_STATE, False);
  401.   }
  402. }
  403. //---------------------------------------------------------------------------
  404. //DBGOUT
  405. void DBGOUT(string text)
  406. {
  407.   if(DBGMODE) {
  408.     ObjectSetString(0, DBGINFO_NAME, OBJPROP_TEXT, text);
  409.   }
  410. }
  411. //---------------------------------------------------------------------------
  412. //タイムコントロールチェック
  413. void CheckTimeControl(bool nextTicked)
  414. {
  415.   if(!TimeControl) {
  416.     if(OffTimeVisible) {
  417.       ObjectDelete(OFFTIME_NAME);
  418.       OffTimeVisible = false ;
  419.     }
  420.     return ;
  421.   }
  422.   if(!nextTicked) return ;
  423.  
  424.   datetime timStart = StringToTime(TimeStart);
  425.   datetime timEnd   = StringToTime(TimeEnd);
  426.  
  427.   MqlDateTime mqlTick, mqlStart, mqlEnd ;
  428.   TimeToStruct(TimeTick, mqlTick);
  429.   TimeToStruct(timStart, mqlStart);
  430.   TimeToStruct(timEnd, mqlEnd);
  431.  
  432.   // 活動時間帯のチェック
  433.   int ct = mqlTick.hour*60 + mqlTick.min ;
  434.   int st = mqlStart.hour*60 + mqlStart.min ;
  435.   int et = mqlEnd.hour*60 + mqlEnd.min ;
  436.   if(et<=st) {
  437.     if(st<=ct) et=24*60;
  438.     if(ct<=et) st=0;
  439.   }
  440.   bool activeTime = st <= ct && ct <= et ;
  441.  
  442.   bool isActivated = StartTime<TimeTick ;
  443.  
  444.   // 現在活動時間帯
  445.   if(activeTime) {
  446.     if(!isActivated)
  447.       StartTime = TimeTick ; // 現在時間を開始時間切り上げて完了
  448.     if(OffTimeVisible) {
  449.       ObjectDelete(OFFTIME_NAME);
  450.       OffTimeVisible = false ;
  451.     }
  452.     return ;
  453.   }
  454.  
  455.   // 活動時間を次の時間にセットする
  456.   MqlDateTime mqlNextStart = mqlTick ;
  457.   mqlNextStart.hour = mqlStart.hour ;
  458.   mqlNextStart.min = mqlStart.min ;
  459.   mqlNextStart.sec = 0 ;
  460.   datetime timNextStart = StructToTime(mqlNextStart) ;
  461.   while(timNextStart<TimeTick)  timNextStart += 24*60*60 ;
  462.   StartTime = timNextStart ;
  463.  
  464.   // 次の開始までの秒数
  465.   datetime timOff = StartTime - TimeTick ;
  466.   if(!OffTimeVisible) {
  467.     // OFF TIME テキストを表示
  468.     ObjectCreate(OFFTIME_NAME, OBJ_LABEL, 0, 0, 0);
  469.     ObjectSet(OFFTIME_NAME, OBJPROP_XDISTANCE, 10);
  470.     ObjectSet(OFFTIME_NAME, OBJPROP_YDISTANCE, 25);
  471.     ObjectSet(OFFTIME_NAME, OBJPROP_CORNER, 1);
  472.     ObjectSetString(0, OFFTIME_NAME, OBJPROP_TEXT, "OFF TIME");
  473.     ObjectSetString(0, OFFTIME_NAME, OBJPROP_FONT, "Verdana");
  474.     ObjectSetInteger(0, OFFTIME_NAME, OBJPROP_FONTSIZE, 8);
  475.     ObjectSetInteger(0, OFFTIME_NAME, OBJPROP_COLOR, clrYellow);
  476.     OffTimeVisible = true ;
  477.   }
  478.  
  479.   int orderFlag = AlreadyOrdered(FLAG_SELL|FLAG_BUY,MAGICMA);
  480.  
  481.   switch(TimeAction) {
  482.     case TIMEACT_NONE:
  483.       // None
  484.       break;
  485.     case TIMEACT_FORCE_CLOSE_ALL:
  486.       // Force Close All positions
  487.       if(orderFlag!=0)
  488.         CheckoutOrderAll(orderFlag);
  489.       break;
  490.     case TIMEACT_FORCE_CLOSE_LONG:
  491.       // Force Close Long positions
  492.       if((orderFlag&FLAG_BUY)!=0)
  493.         CheckoutOrderAll(FLAG_BUY);
  494.       break;
  495.     case TIMEACT_FORCE_CLOSE_SHORT:
  496.       // Force Close Short positions
  497.       if((orderFlag&FLAG_SELL)!=0)
  498.         CheckoutOrderAll(FLAG_SELL);
  499.       break;
  500.     case TIMEACT_SOFT_CLOSE_ALL:
  501.       // Close All positions if profits are Positive
  502.       if(orderFlag!=0) {
  503.         STATUS status_long, status_short;
  504.         CheckStatus(OP_BUY,MAGICMA,status_long);
  505.         CheckStatus(OP_SELL,MAGICMA,status_short);
  506.         double total = status_long.GrossProfit+status_short.GrossProfit ;
  507.         if(total>0) {
  508.           CheckoutOrderAll(orderFlag);
  509.         }
  510.       }
  511.       break;
  512.     case TIMEACT_SOFT_CLOSE_LONG:
  513.       // Close Long positions if profits are Positive
  514.       if((orderFlag&FLAG_BUY)!=0) {
  515.         STATUS status_long;
  516.         CheckStatus(OP_BUY,MAGICMA,status_long);
  517.         double total=status_long.GrossProfit;
  518.         if(total>0) {
  519.           CheckoutOrderAll(FLAG_BUY);
  520.         }
  521.       }
  522.       break;
  523.     case TIMEACT_SOFT_CLOSE_SHORT:
  524.       // Close Short positions if profits are Positive
  525.       if((orderFlag&FLAG_SELL)!=0) {
  526.         STATUS status_short;
  527.         CheckStatus(OP_SELL,MAGICMA,status_short);
  528.         double total=status_short.GrossProfit;
  529.         if(total>0) {
  530.           CheckoutOrderAll(FLAG_SELL);
  531.         }
  532.       }
  533.       break;
  534.   }
  535. }
  536. //---------------------------------------------------------------------------
  537. //タイムコントロールの基軸時間を返す
  538. datetime BaseTime()
  539. {
  540.   switch(TimeBase) {
  541.     case TIMEBASE_GMT:               // Greenwich Mean Time (GMT)
  542.       return TimeGMT();
  543.     case TIMEBASE_LOCAL:             // Local Time
  544.       return TimeLocal();
  545.     case TIMEBASE_SERVER:            // Server Time
  546.       return TimeCurrent();
  547.   }
  548.   return 0;
  549. }
  550. //---------------------------------------------------------------------------
  551. //注文のタイミング検出のサンプル: 2RSI (池辺雪子流手法)
  552. int CheckDetectorRSI2()
  553. {
  554.   double RSI2Fast0 = iRSI(Symbol(), RSI2TimeFrame, RSI2FastPeriod, RSI2PriceType, 0);
  555.   double RSI2Slow0 = iRSI(Symbol(), RSI2TimeFrame, RSI2SlowPeriod, RSI2PriceType, 0);
  556.  
  557.   if(RSI2Fast0-RSI2Slow0 >= RSI2Distance && RSI2Fast0 <= RSI2UpBorder ) {
  558.     bool valid = true ;
  559.     double r1 = RSI2Slow0;
  560.     for(int i=1;i<=RSI2Duration;i++) {
  561.       double r2 = iRSI(Symbol(), RSI2TimeFrame, RSI2SlowPeriod, RSI2PriceType, i) ;
  562.       if(r1<r2) { valid = false ; break ; }
  563.       r1=r2 ;
  564.     }
  565.     if(valid) return FLAG_SELL ; // 逆張りの売りタイミング
  566.   }
  567.  
  568.   if(RSI2Slow0-RSI2Fast0 >= RSI2Distance && RSI2Fast0 >= RSI2DownBorder ) {
  569.     bool valid = true ;
  570.     double r1 = RSI2Slow0;
  571.     for(int i=1;i<=RSI2Duration;i++) {
  572.       double r2 = iRSI(Symbol(), RSI2TimeFrame, RSI2SlowPeriod, RSI2PriceType, i) ;
  573.       if(r1>r2) { valid = false ; break ; }
  574.       r1=r2 ;
  575.     }
  576.     if(valid) return FLAG_BUY ;  // 逆張りの買いタイミング
  577.   }
  578.  
  579.   return 0;
  580. }
  581. //---------------------------------------------------------------------------
  582. //金額表示の更新
  583. void UpdateAmount(double amount, int positions)
  584. {
  585.   if(ShowAmount) {
  586.     if(positions>0) {
  587.       string s = DoubleToStr(amount,AmountDig) ;
  588.       if(amount>0) s = "+" + s ;
  589.       ObjectSetString(0, AMOUNT_NAME, OBJPROP_TEXT, s);
  590.       if(amount<0)
  591.         ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_COLOR, AMOUNT_CLR_NEGA);
  592.       else
  593.         ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_COLOR, AMOUNT_CLR_POSI);
  594.     }else {
  595.       string s = ObjectGetString(0, AMOUNT_NAME, OBJPROP_TEXT);
  596.       int ln=StringLen(s);
  597.       if(ln>0) {
  598.         if(s[ln-1]!='-')
  599.           ObjectSetString(0, AMOUNT_NAME, OBJPROP_TEXT, s+"-");
  600.       }
  601.     }
  602.   }
  603. }
  604. //---------------------------------------------------------------------------
  605. //状態チェック
  606. //-----
  607. struct STATUS {
  608.   int Positions, PyramidPositions;
  609.   double MinPrice, MaxPrice, BorderPrice, ProfitPrice;
  610.   double MinPriceLots, MaxPriceLots;
  611.   double MinPriceProfit, MaxPriceProfit;
  612.   int MinPriceTicket, MaxPriceTicket;
  613.   double MinStoploss, MaxStoploss;
  614.   double MinTakeprofit, MaxTakeprofit;
  615.   double MaxLots, PyramidMaxLots,  PyramidMinLots;
  616.   double TotalPrices, TotalLots;
  617.   double GrossProfit;
  618.   double PositiveProfit;
  619. };
  620. //-----
  621. int CheckStatus(int type, int magic, STATUS &status)
  622. {
  623.   status.Positions = 0 ;
  624.   status.PyramidPositions = 0 ;
  625.   status.MinPrice = DBL_MAX ;
  626.   status.MaxPrice = 0.0 ;
  627.   status.MinPriceLots = 0.0 ;
  628.   status.MaxPriceLots = 0.0 ;
  629.   status.MinPriceProfit = 0.0 ;
  630.   status.MaxPriceProfit = 0.0 ;
  631.   status.MinPriceTicket = 0 ;
  632.   status.MaxPriceTicket = 0 ;
  633.   status.MinStoploss = DBL_MAX ;
  634.   status.MaxStoploss = 0.0 ;
  635.   status.MinTakeprofit = DBL_MAX ;
  636.   status.MaxTakeprofit = 0.0 ;
  637.   status.MaxLots = 0.0 ;
  638.   status.PyramidMinLots = DBL_MAX ;
  639.   status.PyramidMaxLots = 0.0 ;
  640.   status.BorderPrice = 0.0 ;
  641.   status.ProfitPrice = 0.0 ;
  642.   status.GrossProfit = 0.0 ;
  643.   status.PositiveProfit = 0.0 ;
  644.   double totalPrice=0, totalLots=0 ;
  645.   for(int i=OrdersTotal()-1 ; i>=0 ; i--) {
  646.     if( OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == Symbol() ) {
  647.       if(magic==OrderMagicNumber()) {
  648.         if(type==OrderType()) {
  649.           double orderPrice = OrderOpenPrice();
  650.           double orderStoploss = OrderStopLoss();
  651.           double orderTakeprofit = OrderTakeProfit();
  652.           double orderLots = OrderLots();
  653.           double orderProfit = OrderProfit() ;
  654.           int orderTicket = OrderTicket() ;
  655.           status.GrossProfit += orderProfit;
  656.           if(orderProfit>0.0)
  657.             status.PositiveProfit += orderProfit;
  658.           if(orderPrice<status.MinPrice) {
  659.             status.MinPrice = orderPrice ;
  660.             status.MinPriceLots = orderLots ;
  661.             status.MinPriceProfit = orderProfit ;
  662.             status.MinPriceTicket = orderTicket ;
  663.           }
  664.           if(orderPrice>status.MaxPrice) {
  665.             status.MaxPrice = orderPrice ;
  666.             status.MaxPriceLots = orderLots ;
  667.             status.MaxPriceProfit = orderProfit ;
  668.             status.MaxPriceTicket = orderTicket ;
  669.           }
  670.           if(orderStoploss<status.MinStoploss) status.MinStoploss = orderStoploss;
  671.           if(orderStoploss>status.MaxStoploss) status.MaxStoploss = orderStoploss;
  672.           if(orderTakeprofit<status.MinTakeprofit) status.MinTakeprofit = orderTakeprofit;
  673.           if(orderTakeprofit>status.MaxTakeprofit) status.MaxTakeprofit = orderTakeprofit;
  674.           if(orderLots>status.MaxLots) status.MaxLots = orderLots;
  675.           totalPrice += orderPrice*orderLots ;
  676.           totalLots += orderLots;
  677.           string orderComment = OrderComment();
  678.           if(StringFind(orderComment,"PRMD")>=0) {
  679.             if(orderLots>status.PyramidMaxLots)
  680.               status.PyramidMaxLots = orderLots ;
  681.             if(orderLots<status.PyramidMinLots)
  682.               status.PyramidMinLots = orderLots ;
  683.             status.PyramidPositions++;
  684.           }
  685.           status.Positions++;
  686.         }
  687.       }
  688.     }
  689.   }
  690.   if(!status.PyramidPositions) {
  691.     status.PyramidMaxLots = MaxLots ;
  692.     status.PyramidMinLots = Lots ;
  693.   }
  694.   if(totalLots>0) {
  695.     status.BorderPrice = totalPrice / totalLots ;
  696.     switch(type) {
  697.       case OP_BUY:
  698.         status.ProfitPrice =
  699.           (status.MaxPrice-status.BorderPrice) * (ProfitRatePer / 100.0)
  700.             + status.BorderPrice ;
  701.         break;
  702.       case OP_SELL:
  703.         status.ProfitPrice =
  704.           (status.MinPrice-status.BorderPrice) * (ProfitRatePer / 100.0)
  705.             + status.BorderPrice ;
  706.         break;
  707.     }
  708.   }
  709.   status.TotalPrices = totalPrice ;
  710.   status.TotalLots = totalLots ;
  711.   return status.Positions;
  712. }
  713. //---------------------------------------------------------------------------
  714. //動作チェック
  715. void CheckBehavior(bool nextTimed)
  716. {
  717.   // 全体のステータスを取得
  718.   STATUS BuyWholeStatus, SellWholeStatus ;
  719.   CheckStatus(OP_BUY, MAGICMA, BuyWholeStatus);
  720.   CheckStatus(OP_SELL, MAGICMA, SellWholeStatus);
  721.  
  722.   // 金額を更新
  723.   UpdateAmount(
  724.     BuyWholeStatus.GrossProfit+SellWholeStatus.GrossProfit,
  725.     BuyWholeStatus.Positions+SellWholeStatus.Positions );
  726.  
  727.   // ボーダーライン更新
  728.   if(!BuyWholeStatus.Positions) {
  729.     if(BuyBorderLined) {
  730.       ObjectDelete(BUYBORDER_NAME);
  731.       BuyBorderLined=false;
  732.     }
  733.   }else if(nextTimed) {
  734.     DrawBorderLine(OP_BUY);
  735.   }
  736.   if(!SellWholeStatus.Positions) {
  737.     if(SellBorderLined) {
  738.       ObjectDelete(SELLBORDER_NAME);
  739.       SellBorderLined=false;
  740.     }
  741.   }else if(nextTimed) {
  742.     DrawBorderLine(OP_SELL);
  743.   }
  744.  
  745.   // オーダーの処理
  746.   ProcessOrders(OP_BUY, MAGICMA, BuyWholeStatus);
  747.   ProcessOrders(OP_SELL, MAGICMA, SellWholeStatus);
  748.  
  749.   // タイマー更新
  750.   PmdTiming = false ;
  751.   if(PyramidingInterval<=0) PmdTiming = true ;
  752.   else {
  753.     while(TimeTick-CurPmdInt>=PyramidingInterval) {
  754.       CurPmdInt+=PyramidingInterval ;
  755.       PmdTiming = true ;
  756.     }
  757.   }
  758. }
  759. //---------------------------------------------------------------------------
  760. //ボーダーラインを引く
  761. void DrawBorderLine(int orderType)
  762. {
  763.   STATUS status;
  764.   int pos = CheckStatus(orderType, MAGICMA, status);
  765.   switch(orderType) {
  766.     case OP_BUY:
  767.       if(pos) {
  768.         if(!BuyBorderLined) {
  769.           ObjectCreate(BUYBORDER_NAME,OBJ_HLINE,0,0,status.ProfitPrice);
  770.           BuyBorderLined = true ;
  771.         }
  772.         ObjectSet(BUYBORDER_NAME, OBJPROP_STYLE, STYLE_DOT);
  773.         ObjectSet(BUYBORDER_NAME, OBJPROP_COLOR, clrDeepSkyBlue);
  774.         ObjectSet(BUYBORDER_NAME, OBJPROP_PRICE1,status.ProfitPrice);
  775.       }else if(BuyBorderLined) {
  776.         ObjectDelete(BUYBORDER_NAME);
  777.         BuyBorderLined = false ;
  778.       }
  779.       break;
  780.     case OP_SELL:
  781.       if(pos) {
  782.         if(!SellBorderLined) {
  783.           ObjectCreate(SELLBORDER_NAME,OBJ_HLINE,0,0, status.ProfitPrice);
  784.           SellBorderLined = true ;
  785.         }
  786.         ObjectSet(SELLBORDER_NAME, OBJPROP_STYLE, STYLE_DOT);
  787.         ObjectSet(SELLBORDER_NAME, OBJPROP_COLOR, clrViolet);
  788.         ObjectSet(SELLBORDER_NAME, OBJPROP_PRICE1, status.ProfitPrice);
  789.       }else if(SellBorderLined) {
  790.         ObjectDelete(SELLBORDER_NAME);
  791.         SellBorderLined = false ;
  792.       }
  793.       break;
  794.   }
  795. }
  796. //---------------------------------------------------------------------------
  797. //ボーダーラインを消去
  798. void DeleteBorderLines()
  799. {
  800.   if(BuyBorderLined) {
  801.     ObjectDelete(BUYBORDER_NAME);
  802.     BuyBorderLined = false ;
  803.   }
  804.   if(SellBorderLined) {
  805.     ObjectDelete(SELLBORDER_NAME);
  806.     SellBorderLined = false ;
  807.   }
  808. }
  809. //---------------------------------------------------------------------------
  810. //オーダーの処理
  811. void ProcessOrders(int orderType, int magic, const STATUS &status)
  812. {
  813.   if(status.Positions<=0) return ;
  814.   double borderPrice = status.BorderPrice ;
  815.   double profitPrice = status.ProfitPrice ;
  816.   bool underPrice = false ;
  817.   bool timeLimited = false ;
  818.  
  819.   switch(orderType) {
  820.     case OP_BUY:
  821.       if(profitPrice>Bid) underPrice = true;
  822.       break;
  823.     case OP_SELL:
  824.       if(profitPrice<Ask) underPrice = true;
  825.       break;
  826.   }
  827.  
  828.   if(!underPrice) {
  829.     //ピラミッティング
  830.     if(PmdTiming) {
  831.       if(!PyramidingTimes||status.PyramidPositions<PyramidingTimes) {
  832.         bool canPyramid = false ;
  833.         double lots = Lots ;
  834.         int si=0;
  835.         /*
  836.         if(lots<status.PyramidMinLots&&PyramidingScale>1.0) {
  837.           lots = status.PyramidMinLots; si = 1 ;
  838.         }
  839.         if(lots<status.PyramidMaxLots&&PyramidingScale<=1.0) {
  840.           lots = status.PyramidMaxLots; si = 1 ;
  841.         }
  842.         */
  843.         double scale = PyramidingScale;
  844.         for(int i=si;i<=status.PyramidPositions;i++) {
  845.           lots *= scale ;
  846.           if(lots<MinLots) break;
  847.           if(lots>MaxLots) break;
  848.         }
  849.         if(lots<MinLots) lots = MinLots ;
  850.         if(lots>MaxLots) lots = MaxLots ;
  851.         double totalLots = status.TotalLots ;
  852.         double totalPrice = status.TotalPrices ;
  853.         double sl = 0.0, tp =0.0 ;
  854.         switch(orderType) {
  855.           case OP_BUY: {
  856.             if( Ask>=status.MaxPrice+PyramidingStride*Point ) {
  857.               if(PyramidingKeepBorder) {
  858.                 double border = (Ask*lots+totalPrice) / (totalLots+lots);
  859.                 double profit = (Ask-border)*ProfitRatePer/100.0 + border ;
  860.                 if( Ask>=profit+StoplossPadding*Point )
  861.                   canPyramid = true ;
  862.               }else
  863.                 canPyramid = true ;
  864.             }
  865.             if(canPyramid) {
  866.               sl = Bid - (Stoploss * Point);
  867.               if(MoveStoploss) {
  868.                 if(sl<status.MaxStoploss)
  869.                   sl = status.MaxStoploss ;
  870.               }else {
  871.                 //if(sl>status.MinStoploss)
  872.                   sl = status.MinStoploss ;
  873.               }
  874.               if(Takeprofit!=0.0)
  875.                 tp = Ask + Takeprofit*Point ;
  876.             }
  877.             break;
  878.           }
  879.           case OP_SELL: {
  880.             if( Bid<=status.MinPrice-PyramidingStride*Point ) {
  881.               if(PyramidingKeepBorder) {
  882.                 double border = (Bid*lots+totalPrice) / (totalLots+lots);
  883.                 double profit = (Bid-border)*ProfitRatePer/100.0 + border ;
  884.                 if( Bid<=profit-StoplossPadding*Point )
  885.                   canPyramid = true ;
  886.               }else
  887.                 canPyramid = true ;
  888.             }
  889.             if(canPyramid) {
  890.               sl = Ask + (Stoploss * Point);
  891.               if(MoveStoploss) {
  892.                 if(sl>status.MinStoploss)
  893.                   sl = status.MinStoploss ;
  894.               }else {
  895.                 //if(sl<status.MaxStoploss)
  896.                   sl = status.MaxStoploss ;
  897.               }
  898.               if(Takeprofit!=0.0)
  899.                 tp = Bid - Takeprofit*Point ;
  900.             }
  901.             break;
  902.           }
  903.         }
  904.         if(canPyramid) {
  905.           if(MakeOrder(orderType,lots,sl,tp,"PRMD",magic)) {
  906.             //tp値更新
  907.             UpdateSlTp(orderType,magic,tp);
  908.             //ボーダーライン更新
  909.             DrawBorderLine(orderType);
  910.           }
  911.         }
  912.       }
  913.     }
  914.   }
  915.  
  916.   if(PmdTiming) {
  917.     if(MoveStoploss) {
  918.       //sl値自動更新
  919.       UpdateSlTp(orderType, magic);
  920.     }
  921.   }
  922.  
  923. }
  924. //---------------------------------------------------------------------------
  925.  
  926.   bool InnerPoint(double v, double comp) {
  927.     return comp-Point/2.0 < v && v < comp+Point/2.0 ;
  928.   }
  929.  
  930. //sl/tpの一括更新
  931. void UpdateSlTp(int orderType, int magic, double new_tp=0.0)
  932. {
  933.   STATUS status ;
  934.   //ステータス更新
  935.   if(!CheckStatus(orderType, magic, status)) return ;
  936.   double borderPrice = status.BorderPrice ;
  937.   double profitPrice = status.ProfitPrice ;
  938.   double padding = StoplossPadding*Point ;
  939.   bool overBorder = orderType==OP_BUY ?
  940.     Bid >= borderPrice+padding : borderPrice-padding >= Ask ;
  941.   bool overProfit = orderType==OP_BUY ?
  942.     Bid >= profitPrice+padding : profitPrice-padding >= Ask ;
  943.   if(overBorder&&!overProfit) {
  944.     // padding が borderPrice から profitPrice の範囲内にある
  945.     switch(orderType) {
  946.       case OP_BUY:
  947.         profitPrice = Bid-padding ;
  948.         break;
  949.       case OP_SELL:
  950.         profitPrice = Ask+padding ;
  951.         break;
  952.     }
  953.     overProfit = true ;
  954.   }
  955.   // sl/tp 値をすべて更新する
  956.   for(int i=OrdersTotal()-1 ; i>=0 ; i--) {
  957.     if( OrderSelect(i, SELECT_BY_POS) ) {
  958.       if( OrderSymbol() != Symbol() ) continue ;
  959.       if( magic != OrderMagicNumber() ) continue ;
  960.       if( orderType != OrderType() ) continue ;
  961.       double sl, tp = new_tp ;
  962.       double orderStoploss = OrderStopLoss();
  963.       double orderTakeprofit = OrderTakeProfit();
  964.       if( overProfit && MoveStoploss )
  965.         sl = profitPrice;
  966.       else
  967.         sl = orderStoploss;
  968.       switch(orderType) {
  969.         case OP_BUY:
  970.           if(sl<orderStoploss)
  971.             sl = orderStoploss;
  972.           break;
  973.         case OP_SELL:
  974.           if(sl>orderStoploss)
  975.             sl = orderStoploss;
  976.           break;
  977.       }
  978.       if(new_tp==0.0)
  979.         tp = orderTakeprofit;
  980.       if(InnerPoint(sl,orderStoploss)) sl = orderStoploss ;
  981.       if(InnerPoint(tp,orderTakeprofit)) tp = orderTakeprofit ;
  982.       if(sl!=orderStoploss||tp!=orderTakeprofit) {
  983.         if(!OrderModify(OrderTicket(), OrderOpenPrice(), sl, tp,
  984.             OrderExpiration(), orderType==OP_BUY?clrBlue:clrRed)) {
  985.           Print(GetLastError());
  986.         }
  987.       }
  988.     }
  989.   }
  990. }
  991. //---------------------------------------------------------------------------
  992. //すでに注文済みかどうか
  993. int AlreadyOrdered(int orderFlag, int magic)
  994. {
  995.   int flag = 0 ;
  996.   for(int i=OrdersTotal()-1 ; i>=0 ; i--) {
  997.     if( OrderSelect(i, SELECT_BY_POS) ) {
  998.       int orderMagic = OrderMagicNumber() ;
  999.       if( OrderSymbol() == Symbol() && magic==orderMagic ){
  1000.         if( OrderType() == OP_BUY && (orderFlag&FLAG_BUY)!=0 ){
  1001.           flag |= FLAG_BUY  ; if(flag==orderFlag) break;
  1002.         }else if( OrderType() == OP_SELL && (orderFlag&FLAG_SELL)!=0 ){
  1003.           flag |= FLAG_SELL ; if(flag==orderFlag) break;
  1004.         }
  1005.       }
  1006.     }
  1007.   }
  1008.   return flag;
  1009. }
  1010. //---------------------------------------------------------------------------
  1011. //EA用ポジションのエントリー
  1012. bool EAEntryPosition(string detector, int orderFlag, int &busy)
  1013. {
  1014.   // EAの注文を処理
  1015.   if((PositionFlag&orderFlag)!=0&&(busy&orderFlag)==0) {
  1016.     if(!busy||(PositionFlag&FLAG_DUPLEX)!=0) {
  1017.       int entry = orderFlag == FLAG_BUY ? OP_BUY : OP_SELL ;
  1018.       EntryPosition(detector, entry, Lots);
  1019.       busy |= orderFlag ;
  1020.       return true ;
  1021.     }
  1022.   }
  1023.   return false ;
  1024. }
  1025. //---------------------------------------------------------------------------
  1026. //ポジションのエントリー(注文の発注簡易版)
  1027. bool EntryPosition(string detector, int entryType, double lots, int magic=0, double sl=-1.0, double tp=-1.0)
  1028. {
  1029.   switch(entryType) {
  1030.     case OP_BUY:
  1031.       if(sl<0.0) sl = Bid - (Stoploss * Point);
  1032.       if(tp<0.0) {
  1033.         tp=0.0;
  1034.         if(Takeprofit!=0.0)
  1035.           tp = Ask + (Takeprofit * Point);
  1036.       }
  1037.       break;
  1038.     case OP_SELL:
  1039.       if(sl<0.0) sl = Ask + (Stoploss * Point);
  1040.       if(tp<0.0) {
  1041.         tp = 0.0 ;
  1042.         if(Takeprofit!=0.0)
  1043.           tp = Bid - (Takeprofit * Point);
  1044.       }
  1045.       break;
  1046.   }
  1047.   return MakeOrder(entryType,lots,sl,tp,detector,magic) ;
  1048. }
  1049. //---------------------------------------------------------------------------
  1050. //注文の発注
  1051. bool MakeOrder(int entryType, double lots, double sl, double tp, string detector, int magic)
  1052. {
  1053.   bool entried=false ;
  1054.  
  1055.   for(int retry=0; retry<ORDER_RETRY; retry++) {
  1056.  
  1057.     if(MarketInfo(NULL,MODE_SPREAD) > Spread) { Sleep(2000); continue ; }
  1058.  
  1059.     double entryPrice = 0.0 ;
  1060.     color orderColor = clrNONE;
  1061.  
  1062.     switch(entryType) {
  1063.     case OP_BUY:
  1064.       entryPrice = Ask ;
  1065.       orderColor = clrBlue ;
  1066.       break;
  1067.     case OP_SELL:
  1068.       entryPrice = Bid ;
  1069.       orderColor = clrRed ;
  1070.       break;
  1071.     }
  1072.  
  1073.     if(!entried) {
  1074.       if(MakeOrderSub(entryType,entryPrice,lots,sl,tp,"Pyramid("+detector+")",MAGICMA,orderColor))
  1075.         entried = true ;
  1076.     }
  1077.  
  1078.     if(entried) return true ;
  1079.  
  1080.     Sleep(2000);
  1081.   }
  1082.  
  1083.   return false;
  1084. }
  1085. //---------------------------------------------------------------------------
  1086. //注文発注サブルーチン
  1087. bool MakeOrderSub(int entryType, double entryPrice, double lots, double sl, double tp,
  1088.   string comment,int magicNumber,color orderColor)
  1089. {
  1090.    int res = OrderSend(
  1091.                       NULL,
  1092.                       entryType,
  1093.                       lots,
  1094.                       entryPrice,
  1095.                       Slippage,
  1096.                       sl,
  1097.                       tp,
  1098.                       comment,
  1099.                       magicNumber,
  1100.                       0,
  1101.                       orderColor
  1102.                    );
  1103.    if(res<0)
  1104.      Print(GetLastError());
  1105.    return res>=0;
  1106. }
  1107. //---------------------------------------------------------------------------
  1108. //注文の決済
  1109. bool CheckoutOrder( int orderType, int orderTicket, double orderLots)
  1110. {
  1111.   for(int retry=0; retry<ORDER_RETRY; retry++) {
  1112.     double checkoutPrice = 0.0 ;
  1113.     color orderColor = clrNONE ;
  1114.     switch(orderType) {
  1115.     case OP_BUY:
  1116.       checkoutPrice = Bid ;
  1117.       orderColor = clrBlue ;
  1118.       break;
  1119.     case OP_SELL:
  1120.       checkoutPrice = Ask ;
  1121.       orderColor = clrRed ;
  1122.       break;
  1123.     }
  1124.     if(OrderClose(orderTicket, orderLots, checkoutPrice, Slippage, orderColor))
  1125.       return true;
  1126.     Sleep(100);
  1127.   }
  1128.   Print(GetLastError());
  1129.   return false ;
  1130. }
  1131. //---------------------------------------------------------------------------
  1132. //注文の全決済
  1133. bool CheckoutOrderAll(int orderFlag)
  1134. {
  1135.   bool result = true ;
  1136.   for(int i = OrdersTotal() -1; i >= 0; i--){
  1137.     if(OrderSelect(i, SELECT_BY_POS)) {
  1138.       int magic = OrderMagicNumber();
  1139.       int orderType = OrderType() ;
  1140.       if( (orderType==OP_BUY&&(orderFlag&FLAG_BUY)!=0) ||
  1141.           (orderType==OP_SELL&&(orderFlag&FLAG_SELL)!=0) ) {
  1142.         if( OrderSymbol() == Symbol() && magic == MAGICMA ){
  1143.           double profit = OrderProfit();
  1144.           if(!CheckoutOrder(OrderType(),OrderTicket(),OrderLots())) {
  1145.             result = false ; break;
  1146.           }
  1147.         }
  1148.       }
  1149.     }
  1150.   }
  1151.   return result ;
  1152. }
  1153. //---------------------------------------------------------------------------
  1154.  
Tags: Mt4
Advertisement
Add Comment
Please, Sign In to add comment