【问题标题】:Highest high and lowest low between a time frame and drawing a rectangle for visual for an X amount of days时间范围内的最高价和最低价之间的最高价和最低价为 X 天的可视化矩形
【发布时间】:2015-08-13 19:35:00
【问题描述】:

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

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

【问题讨论】:

  • 杰拉德,将您希望在屏幕上显示的结果的草图张贴出来是公平的。发布此类插图的链接,我可以将其上传到您的帖子中,因为您的初始 [声誉]-score 不允许您直接发布图,好吗?
  • 伟大的举动,杰拉德。包括图(下一个保存为PNGP-ortable 是值得的),StackOverflow 拒绝一些其他常见的格式(无论是由于许可还是版税问题 - 它只是拒绝,谁在乎为什么?)。所以,问题来了:您的基本图表是 M15 图表,而您的 GreenBoxOBJECT 跨越 8 个柱,[Q1]您的目标是 H2 的合成超级时间框架还是无意的?[Q2] 在这种情况下 X 是如上所述的 == 4 吗?[Q3] 你如何声明 GreenBoxOBJECT 开始日期时间?看起来好像从第一个回顾日 - 是吗?
  • 我只是碰巧使用了 M15 图表,只是为了显示更多我正在寻找的示例。至于这个例子中的时间范围,我使用了 05:00 到 07:00。我想要指定时间范围的外部选项。在时间范围内,我想要最高价和最低价。这应该是矩形框的范围。我想一旦最后一个时间框架为真,是否可以实时绘制该框。此外,如果可以在照片中绘制 X 天前的框。

标签: user-interface trading algorithmic-trading mql4 forex


【解决方案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 );
}

【讨论】:

  • 感谢两位的帮助,非常感谢。
  • 请你帮我看看这个问题stackoverflow.com/questions/53397898/…
  • 我意识到这解决了我的部分问题。如何解决余数并将其转换为指标?
【解决方案2】:

避免术语混淆

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

由于自然时间流中与周末相关的间隙以及上述任务定义的性质,在下面的代码-sn-p 中,确实在多个 TimeFRAME 层上并行存在许多与 TimeFRAME 相关的操作(包括PERIOD_D1PERIOD_H1 并隐藏PERIOD_CURRENT 依赖项(unknown(隐式),因此完全避免使用),以便允许指针计数和后退索引更新(^PTR->TimeSERIES)。

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

参数化

最简单的形式是使用下面所述的extern-s 集合。值得注意的是,extern 构造函数是危险的,以防您的 GUI 层应用程序变得更加智能和复杂,并且如果它直接连接到 XTOs ( eX ecute-Trade-O操作)。

#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 层元素(MVisual-part VC-triade ),extern 构造函数绑定变量必须避免,因为它们的值的任何变化(由于 MT4 架构设计)都会导致实时增强服务的 Model 和 Controller 部分中的重置和不可重入冲突以及此类交易服务对使用和 XTO。

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

为了实时操作的增强交易服务,有更好(和更安全)的方法来避免extern 对正在运行的服务的破坏性影响。除了其他我最喜欢使用进程到进程/分布式计算消息传递之外,这主要使您的 MT4-Terminal 成为基于私有云的交易基础设施和您的基于MQL4 的 EA 中的节点开始在交响乐团中演奏,与其他编排乐器一起演奏(无论是 AI/ML-NeuralNetwork 决策计算过程,还是用于投资组合优化量化模型的基于 GPU 的协方差矩阵评估器,简单地说,像这样的任何东西都可以"direct" / "command" an MQL4-process "inside" MT4-终端以平滑、不间断和实时、非阻塞、完全异步的方式,不是吗听起来很吸引人?Yes, it does! 查看this 一次大约 1 [ms] 或更短时间

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

一旦您进入 UI 设计领域,您的(最初隐藏的)问题称为 UI 控制循环和整体 UI 响应性(UI 响应您的 MMIMan-Machine-Interface)和外部“输入”流(鼠标单击/鼠标移动/鼠标拖放/aMarketEVENT/等)。

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

充分尊重 Joseph 的建议,将 UI 进程作为OnTick()blocking-task 直接挂起到每个 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 );
             }
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2016-01-16
    • 2019-06-13
    • 1970-01-01
    • 2016-01-26
    相关资源
    最近更新 更多