0

我的目标是在图表上创建一个矩形对象,从指定时间范围内的最高高点和最低低点测量X几天?

一个示例 ScreenView

我知道如何为图表创建一个对象,但我不确定如何让它重复X几天。我怎样才能做到这一点?我在想也许 For 循环会是一个好方法?我可以使用一些指导。

4

2 回答 2

1

试试这个代码(专家顾问)。好的,它效率不高(因为它重新计算每个刻度),但我很好地展示了这个概念。 在此处输入图像描述

这是它的代码:

//+------------------------------------------------------------------+
//|                                            GeraldHighLowV0R1.mq4 |
//|               Copyright 2015, joseph.lee @ fs [dot] com [dot] my |
//|                                            http://www.fs.com.my/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, joseph.lee @ fs [dot] com [dot] my"
#property link      "http://www.fs.com.my/"
#property version   "1.00"
#property strict

extern int      viTimeOfDayStartHour    =  3;
extern int      viTimeOfDayEndHour      =  9;
extern int      viDaysToDraw            = 10;


void OnTick() {
    string      vsGlobalDebug           = "";
    datetime    vdCurrentDayStart       = iTime(Symbol(), PERIOD_D1, 0);    //Get Broker Today DateTime as of Midnight

    ObjectsDeleteAll();
    //---------------------------------------------------------------
    //Process [viDaysToDraw] number of days (**Sat/Sun is included)
    //---------------------------------------------------------------
    for(int viDay=0; viDay<viDaysToDraw; viDay++) {
        datetime vdDateOfSection        = vdCurrentDayStart-(viDay*PERIOD_D1*60);                       //Get Section Midnight DateTime
        datetime    vdSectionStart      = vdDateOfSection + (viTimeOfDayStartHour*PERIOD_H1*60);        //Add Hours to Mark start of section
        datetime    vdSectionEnd        = vdDateOfSection + (viTimeOfDayEndHour  *PERIOD_H1*60);        //Add Hours to mark End of section

        //----------------------------------------------------------------------
        //Calculate the number of bars between (inclusive) Start and End time
        //----------------------------------------------------------------------
        int     viSectionEndBarIndex         = iBarShift(Symbol(), PERIOD_CURRENT, vdSectionEnd,false);
        int     viSectionStartBarIndex       = iBarShift(Symbol(), PERIOD_CURRENT, vdSectionStart,false);
        int     viBarCountBtwStartAndEndHour = viSectionStartBarIndex-viSectionEndBarIndex+1;
        //-----------------------------------------------------------------

        //-----------------------------------------------------------------
        //Find the Highest/Lowest Bar index within the Day Section
        //-----------------------------------------------------------------
        int     viSectionHighestBar     = iHighest(Symbol(), PERIOD_CURRENT, MODE_HIGH, viBarCountBtwStartAndEndHour, viSectionEndBarIndex);
        int     viSectionLowestBar      = iLowest(Symbol(), PERIOD_CURRENT, MODE_LOW, viBarCountBtwStartAndEndHour, viSectionEndBarIndex);
        //-----------------------------------------------------------------

        //-----------------------------------------------------------------
        //Find the Highest/Lowest Price within the Day Section
        //-----------------------------------------------------------------
        double  viSectionHighestPrice   = iHigh(Symbol(), PERIOD_CURRENT, viSectionHighestBar);
        double  viSectionLowestPrice    = iLow( Symbol(), PERIOD_CURRENT, viSectionLowestBar);
        //-----------------------------------------------------------------

        //-----------------------------------------------------------------
        //Add Verbose/Debug Info for display
        //-----------------------------------------------------------------
        StringAdd(
            vsGlobalDebug, "\n[Day" + IntegerToString(viDay) + "]: "
                + "Start: "     + TimeToString(vdSectionStart)
                + ", Lowest: "  + DoubleToString(viSectionLowestPrice,Digits)
                + ", End: "     + TimeToString(vdSectionEnd)
                + ", Highest: " + DoubleToString(viSectionHighestPrice,Digits));
        //-----------------------------------------------------------------

        //-----------------------------------------------------------------
        //Crete Rectangle Object for the Day section
        //-----------------------------------------------------------------
        string  vsObjName   = "HLDay" + IntegerToString(viDay);
        ObjectCreate(0, vsObjName, OBJ_RECTANGLE, 0, vdSectionStart, viSectionLowestPrice, vdSectionEnd, viSectionHighestPrice);
        ObjectSetInteger(0, vsObjName, OBJPROP_COLOR, clrDarkGreen);
        ObjectSetInteger(0, vsObjName, OBJPROP_WIDTH, 0);
        ObjectSetInteger(0, vsObjName, OBJPROP_BACK, true);
        ObjectSetInteger(0, vsObjName, OBJPROP_SELECTABLE, false);
        //-----------------------------------------------------------------
    }
    ChartRedraw();

    //-----------------------------------------------------------------
    // Show Debug/Verbose Info
    //-----------------------------------------------------------------
    Comment("\n" + vsGlobalDebug );
}
于 2015-06-03T15:56:28.957 回答
0

避免术语混淆

TimeFRAME是一个行业广泛接受的术语,用于表示市场事件流的“基于时间的框架”,并且几十年来一直将这种含义标准化。

由于自然时间流中与周末相关的间隙以及上述任务定义的性质,在下面的代码片段中(包括PERIOD_D1PERIOD_H1隐藏PERIOD_CURRENT依赖项(未知(隐式),因此完全避免使用),以便允许指针计数和反向索引更新(^PTR->TimeSERIES)。

因此,在整个进一步开发过程中,让我们在给定的任务定义下使用另一个术语来表示aGreenBOX ,并以不同的方式调用 aTimeDOMAIN 绑定属性 - aTimeWINDOW & al(但不是 TimeFRAME,好吗?)

参数化

最简单的形式将使用下面所述的一组extern-s。值得注意的是,extern如果您的 GUI 层应用程序变得更加智能和复杂,并且如果它直接与XTO接口(例如X ecute - Trade - Operation (s)),构造函数是危险的。

#property strict

extern int    aGreenBoxWindow_HOUR__ENDs = 7;      // aTimeWINDOW.ends <<- 05:00 - 07:00 [GMT-ABCD]
extern int    aGreenBoxWindow_HOURs_WIDE = 2;      // aTimeWINDOW.width
extern int    aGreenBoxWindow_nDAYs_BACK = 4;      // aTimeWINDOW.repeatDays
       int    aCallLockPTR               = 0; 
       string anObjNamePREFIX            = "aGreenBOX.id=";

警告

对于基于 MT4 的实时增强交易服务,其中 XTO 操作自动绑定/挂钩到某些 GUI 层元素(-triade的可视化部分),必须避免构造函数绑定变量,因为其价值的任何变化(由于MT4架构设计)都会导致实时增强服务的模型和控制器部分发生重置和不可重入冲突,并且此类交易服务将对使用和 XTO。MVCextern

extern没有-s的增强交易服务的参数化

为了实时操作的增强交易服务,有更好(和更安全)的方法来避免extern对正在运行的服务的破坏性影响。除了其他我最喜欢使用进程到进程/分布式计算消息传递之外,这主要使您的MT4-Terminal 成为基于私有云的交易基础设施内的节点,并且您MQL4的基于 EA 开始在 Symphonic 管弦乐队中播放,以及其他编排工具(无论是 AI/ML-NeuralNetwork 决策计算过程,还是用于投资组合优化量化模型的基于 GPU 的协方差矩阵评估器,简而言之,这样的任何东西都可以“指导”/“命令”一个MQL4过程“里面”MT4- 以流畅、不间断和实时、非阻塞、完全异步的方式终端,这听起来是不是很吸引人?是的,它确实!查看这个一次大约 1 [ms] 和更少

一个简单的解决方案 - CPU 有效的低优先级方法的示例

一旦您进入 UI 设计领域,您的(最初隐藏的)问题称为 UI 控制循环和整体 UI 响应性(UI 响应您的(MMI连接器界面)和外部流“的响应速度有多快”输入”(鼠标单击/鼠标移动/鼠标拖放/aMarketEVENT/等)。MMI

有必要进行合理的监管,以避免对重复任务的低效调用,这些调用不会给 XTO/MVC 优先/MVC 延迟视觉部分重绘操作带来任何新内容。

尽管 Joseph建议将 UI 进程直接作为OnTick()阻塞任务挂起,原则上TickArrivalEVENT是可能的,但是在 XTO的生产级软件和 CPU/内存访问/db.POOL 资源中都是致命的危险。浪费处理能力(通常需要用于其他任务)

int init(){
    // ------------------------------------------- // ------------------------
    aGreenBoxWINDOWs_Update();                     // .init
    aCallLockPTR = iBars( NULL, PERIOD_H1 );       // .set  a CPU-clock saving LOCK
    // ------------------------------------------- // ------------------------
   }

int start(){
    // ------------------------------------------- // -----------------
    // HIGH-PRIORITY OPERATIONS
    // ...
    // ..
    // .
    // ||||||||||||||||||||||||||||||||||||||||||| // |||||||||||||||||
    if (  iBars( NULL, PERIOD_H1 )                 // .TEST
       != aCallLockPTR
       ){ 
          aGreenBoxWINDOWs_UpdateJusTheLiveOne();  // .UPD GUI
          aCallLockPTR = iBars( NULL, PERIOD_H1 ); // .SET PTR
       }
    else {// ///////////////////////////////////// // .UPD GUI in .id=1
          // in case LowestLow or HighestHigh inside the Live part of
          // aGreenBOX "aGreenBOX.id=1"
          // was moved:
          // aGreenBoxWINDOW_UpdateJustTheLiveOne();
          // re-lock Hi/Lo_LOCKs                   // .UPD LOCKs
       }
    }

用于增强 Visual MVC 部分的 aGreenBOX 魔法

void aGreenBoxWINDOWs_Update(){
     int      static aGreenBoxWindow_Duration_SECs = aGreenBoxWindow_HOURs_WIDE
                                                   * PeriodSeconds( PERIOD_H1 );
     int             aGreenBoxWindow_H1Offset_ENDs = TimeHour( TimeCurrent() )
                                                   - aGreenBoxWindow_HOUR__ENDs;
     if (            aGreenBoxWindow_H1Offset_ENDs < 0 ){
                     aGreenBoxWindow_H1Offset_ENDs+= 24;
        }
     datetime        aGreenBoxWindow_DATETIME_ENDs = iTime( NULL,
                                                            PERIOD_D1,
                                                            0
                                                            )
                                                   + aGreenBoxWindow_HOUR__ENDs
                                                   * PeriodSeconds( PERIOD_H1 );
     if (            aGreenBoxWindow_DATETIME_ENDs
                   - aGreenBoxWindow_Duration_SECs > iTime( NULL,
                                                            PERIOD_H1,
                                                            0
                                                            )
          ){
                     aGreenBoxWindow_DATETIME_ENDs = iTime( NULL,
                                                            PERIOD_D1,
                                                            1
                                                            )
                                                   + aGreenBoxWindow_HOUR__END
                                                   * PeriodSeconds( PERIOD_H1 );
        }
     for ( 
         //----------------------------------------------- // --------------------
           int    anObjIDX  = 1,                           // loop-pre-setting(s)
           string anObjNAME = anObjNamePREFIX + "1",       //      var(s)=value(s) ( life-span only "inside" for(){...}-constructor in MQL4.5+ ...)
           int    anObjENDs = aGreenBoxWindow_DATETIME_ENDs;
         //----------------------------------------------- // --------------------
                  anObjIDX <= aGreenBoxWindow_nDAYs_BACK;  // loop-pre-condition
         //----------------------------------------------- // --------------------
                                                           // loop-post-update(s)
                  anObjIDX++,                              //      IDX
                  anObjNAME = anObjNamePREFIX + anObjIDX,  //      NAME     
                  anObjENDs = iTime( NULL,                 //      ENDs
                                     PERIOD_D1,
                                     anObjIDX
                                     )
                            + PeriodSeconds( PERIOD_H1 )
                            * aGreenBoxWindow_HOUR__ENDs,
                  aGreenBoxWindow_H1Offset_ENDs+= 24       //     ENDs ^H1
         //----------------------------------------------- // --------------------
           ){                                              // loop-body:
           if ( ObjectFind(   anObjNAME ) < 0 ){           // !found .ADD
                ObjectCreate( anObjNAME, OBJ_RECTANGLE, 0,
                                         aGreenBoxWindow_DATETIME_ENDs,
                                         iHigh( NULL,
                                                PERIOD_H1,
                                                iHighest( NULL,
                                                          PERIOD_H1,
                                                          MODE_HIGH,
                                                          aGreenBoxWindow_HOURs_WIDE,
                                                          aGreenBoxWindow_H1Offset_ENDs
                                                          )
                                                ),
                                         aGreenBoxWindow_DATETIME_ENDs
                                       - aGreenBoxWindow_Duration_SECs,
                                         iLow(  NULL,
                                                PERIOD_H1,
                                                iLowest(  NULL,
                                                          PERIOD_H1,
                                                          MODE_LOW,
                                                          aGreenBoxWindow_HOURs_WIDE,
                                                          aGreenBoxWindow_H1Offset_ENDs
                                                          )
                                                )
                              );
                ObjectSet(    anObjNAME, OBJPROP_COLOR, DarkGreen );
                ObjectSet(    anObjNAME, OBJPROP_BACK,  True );
             }
           else {                                          //  found .UPD
                ObjectMove(   anObjNAME, 0,
                                         aGreenBoxWindow_DATETIME_ENDs,
                                         iHigh( NULL,
                                                PERIOD_H1,
                                                iHighest( NULL,
                                                          PERIOD_H1,
                                                          MODE_HIGH,
                                                          aGreenBoxWindow_HOURs_WIDE,
                                                          aGreenBoxWindow_H1Offset_ENDs
                                                          )
                                                )
                              );
                ObjectMove(   anObjNAME, 1,
                                         aGreenBoxWindow_DATETIME_ENDs
                                       - aGreenBoxWindow_Duration_SECs,
                                         iLow(  NULL,
                                                PERIOD_H1,
                                                iLowest(  NULL,
                                                          PERIOD_H1,
                                                          MODE_LOW,
                                                          aGreenBoxWindow_HOURs_WIDE,
                                                          aGreenBoxWindow_H1Offset_ENDs
                                                          )
                                                )
                              );
                ObjectSet(    anObjNAME, OBJPROP_COLOR, DarkGreen );
                ObjectSet(    anObjNAME, OBJPROP_BACK,  True );
             }
        }
    }
于 2015-06-01T16:18:18.170 回答