请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  量化平台 帖子:3364679 新帖:0

价格行为. 自动化内含柱交易策略

jaykuo发表于:5 月 7 日 09:20回复(0)

简介

所有的外汇交易者或多或少都接触过价格行为. 它不仅仅是一项图表分析技术, 而是包含了定义未来价格可能走向的整个系统. 在本文中, 我们将详细研究内含柱模式, 并且会基于该模式开发一个EA交易以跟踪内含柱信息及进行交易.



关于价格行为

价格行为是一种非指标的价格移动侦测方法, 它可以使用简单或者复杂的模式, 也可以使用辅助的图表元件(例如水平线, 垂直线, 趋势线, 斐波那契水平, 支撑/阻力水平等等).

乍一看来, 此方法貌似复杂, 但事实上并非如此. 这种方法现已日益流行, 因为和使用技术指标的方法相比较, 它的优势显而易见.



内含柱

内含柱也就是某个柱的柱体以及引线都包含在其前一个柱(母柱)的范围之内. 内含柱的最高价比其母柱的最高价要低, 而最低价比其母柱最低价要高. 母柱和内柱构成了潜在的进入市场的模式.

这是一个两面性的模式, 因为它可能指出趋势的反转或者持续.

图 1. 内含柱

图 1. 内含柱



图 2. 内含柱模式布局

图 2. 内含柱模式布局




内含柱规则:


  • 内含柱模式在更高时间框架内更有意义, 例如 H4 或 D1.

  • 此模式可能暗示趋势的反转, 也可能暗示趋势的持续.

  • 使用额外的图形分析工具, 包括趋势线, 支撑/阻力水平, 斐波那契水平以及其他的价格行为模式等等, 可以获得更加清晰的进场信号.

  • 使用挂单来避免过早或者错误地进入市场.

  • 不要在平缓的市场中重复使用内含柱作为进场信号.


图 3. 在 GBPUSD D1 图表上定义真正的内含柱

图 3. 在 GBPUSD D1 图表上定义真正的内含柱

把这些都记住后, 让我们尝试定义一个真正的内含柱. 在上图中, 我们可以看到在价格陡然下降之后出现一个牛势柱形. 但是, 这个柱整个位于前一个柱范围之内. 另外, 此柱也位于支撑水平之上, 进一步确认了该模式. 第三点确认是这并非平缓的市场环境. 因为此模式满足了这些规则, 它可以被确认为真实.



定义入场点并设置止损单

就这样, 我们已经在图表上发现了一个真正的内含柱 (图 3). 我们应该怎样进入市场?还有我们在哪里设置订单的止损位呢?让我们看图4.

图 4. 设置止损买入订单并设置止损

图 4. 设置止损买入 订单并设置止损

首先, 我们应该使用上面的例子来考虑止损水平的设置:


  1. 设置一个比母柱最高价略高的止损买入挂单(只需要高几个点, 用于确认).

  2. 设置一个比支撑位, 也就是母柱的最低价略低的一个止损水平. 这是一个额外的保护, 以防挂单被触发以后, 价格又回到支撑水平而反弹后再向正确方向移动.

  3. 再在略低于阻力位的地方设置获利水平.

别忘了, 内含柱可能跟随着趋势的反转或者持续, 所以我们还要设置一个止损卖出订单.


图 5. 设置止损卖出订单及止损

图 5. 设置止损卖出订单及止损

首先, 我们应该使用上面的例子来考虑止损水平的设置:


  1. 设置一个比母柱最低价略低的止损卖出订单(只要低几个点, 以作确认).

  2. 在母柱最高价上方设置止损水平.

  3. 在最近的支撑水平略高处设置获利水平.


基于内含柱交易开发一个EA交易

现在我们已经了解了定义内含柱的所有规则, 进入市场及设置止损单, 我们最终可以使用内含柱模式来实现对应的EA交易了.

从MetaTrader 4终端开启 MetaEditor 并创建一个新的 EA 交易 (相信我不必在此方面涉及过多, 网站上已经有了很多如何创建EA交易的信息了). 在这个阶段把所有的参数设置成空. 您可以按照您的喜好对它们进行命名. 结果代码看起来如下:


//++ //|                                                    InsideBar.mq4 | //|                                  Copyright 2015, Iglakov Dmitry. | //|                                               cjdmitri@gmail.com | //++ #property copyright "Copyright 2015, Iglakov Dmitry." #property link      "cjdmitri@gmail.com" #property version   "1.00" #property strict //++ //| EA 初始化函数                                                     | //++ int OnInit()   { //- //-    return(INIT_SUCCEEDED);   } //++ //| EA 终止化函数                                                     | //++ void OnDeinit(const int reason)   { //-   } //++ //| EA 订单处理函数                                                    | //++ void OnTick()   { //-   } //++


把模式转换为MQL4算法

当我们创建了EA之后, 我们需要在柱关闭后定义一个内含柱. 为此, 我们会引入新的变量并为它们赋值. 参照以下代码:

//++ //|                                                    InsideBar.mq4 | //|                                  Copyright 2015, Iglakov Dmitry. | //|                                               cjdmitri@gmail.com | //++ #property copyright "Copyright 2015, Iglakov Dmitry." #property link      "cjdmitri@gmail.com" #property version   "1.00" #property strict double   open1,//第一个柱的开盘价 open2,    //第二个柱的开盘价 close1,   //第一个柱的收盘价 close2,   //第二个柱的收盘价 low1,     //第一个柱的最低价 low2,     //第二个柱的最低价 high1,    //第一个柱的最高价 high2;    //第二个柱的最高价 //++ //| EA 初始化函数                                                     | //++ int OnInit()   {    return(INIT_SUCCEEDED);   } //++ //| EA 终止化函数                                                     | //++ void OnDeinit(const int reason)   {   } //++ //| EA 订单处理函数                                                   | //++ void OnTick()   { //- 定义所需的柱的价格    open1        = NormalizeDouble(iOpen(Symbol(), Period(), 1), Digits);    open2        = NormalizeDouble(iOpen(Symbol(), Period(), 2), Digits);    close1       = NormalizeDouble(iClose(Symbol(), Period(), 1), Digits);    close2       = NormalizeDouble(iClose(Symbol(), Period(), 2), Digits);    low1         = NormalizeDouble(iLow(Symbol(), Period(), 1), Digits);    low2         = NormalizeDouble(iLow(Symbol(), Period(), 2), Digits);    high1        = NormalizeDouble(iHigh(Symbol(), Period(), 1), Digits);    high2        = NormalizeDouble(iHigh(Symbol(), Period(), 2), Digits);   } //++

作为例子, 让我们考虑母柱是熊势柱 (柱 2), 而内含柱为牛势柱 (柱 1)的状况. 让我们在 OnTick()函数体中增加一系列条件:

void OnTick()   { //- 定义所需的柱的价格    open1        = NormalizeDouble(iOpen(Symbol(), Period(), 1), Digits);    open2        = NormalizeDouble(iOpen(Symbol(), Period(), 2), Digits);    close1       = NormalizeDouble(iClose(Symbol(), Period(), 1), Digits);    close2       = NormalizeDouble(iClose(Symbol(), Period(), 2), Digits);    low1         = NormalizeDouble(iLow(Symbol(), Period(), 1), Digits);    low2         = NormalizeDouble(iLow(Symbol(), Period(), 2), Digits);    high1        = NormalizeDouble(iHigh(Symbol(), Period(), 1), Digits);    high2        = NormalizeDouble(iHigh(Symbol(), Period(), 2), Digits); //- 如果第二个柱为熊势而第一个柱为牛势    if(open2>close2 && //第二个柱为牛势       close1>open1 && //第一个柱是熊势       high2>high1 &&  //第二柱的最高价高于第一个柱的最高价       open2>close1 && //第二柱的开盘价高于第一柱的收盘价       low2<low1)      //第二柱的最低价低于第一柱的收盘价      {       //- 我们已经列出了第一柱内含于第二柱的所有条件      }   }
  • 创建可定制的变量: 止损单, 点差, 订单过期时间, EA 幻数, 交易手数. 止损值可以不用, 因为它决定于内含柱的原则.

  • 为这些变量增加代码中的局部变量.

  • 止损订单由距离柱价位的某个距离设置. 为了实现这一点, 增加Interval变量, 作为止损订单和最高/最低价的距离以及挂单的水平.

  • 增加timeBarInside变量以避免在此模式上重复开启订单.

  • 增加bar2size变量以确认母柱足够大, 是当前市场并不平缓的很好的标记.

结果我们可以获得如下代码:

//++ //|                                                    InsideBar.mq4 | //|                                  Copyright 2015, Iglakov Dmitry. | //|                                               cjdmitri@gmail.com | //++ #property copyright "Copyright 2015, Iglakov Dmitry." #property link      "cjdmitri@gmail.com" #property version   "1.00" #property strict extern int     interval          = 20;                               //距离 extern double  lot               = 0.1;                              //手数 extern int     TP                = 300;                              //获利 extern int     magic             = 555124;                           //幻数 extern int     slippage          = 2;                                //点差 extern int     ExpDate           = 48;                               //订单过期小时数 extern int     bar2size          = 800;                              //柱 2 的大小 double   buyPrice,//定义止损买入价位 buyTP,      //止损买入单的获利价位 buySL,      //止损买入单的止损价位 sellPrice,  //定义止损卖出价位 sellTP,     //止损卖出单的获利价位 sellSL;     //止损卖出单的止损价位 double   open1,//第一个柱的开盘价 open2,    //第二个柱的开盘价 close1,   //第一个柱的收盘价 close2,   //第二个柱的收盘价 low1,     //第一个柱的最低价 low2,     //第二个柱的最低价 high1,    //第一个柱的最高价 high2;    //第二个柱的最高价 datetime _ExpDate=0;          //定义订单过期时间的局部变量 double     _bar2size; datetime timeBarInside;         //内含柱开启的时间, 用于防止重复开单 //++ //| EA 初始化函数                                                     | //++ int OnInit()   {    return(INIT_SUCCEEDED);   } //++ //| EA 终止化函数                                                     | //++ void OnDeinit(const int reason)   {   } //++ //| EA 订单处理函数                                                    | //++ void OnTick()   {    double   _bid     = NormalizeDouble(MarketInfo(Symbol(), MODE_BID), Digits); //定义低价     double   _ask     = NormalizeDouble(MarketInfo(Symbol(), MODE_ASK), Digits); //定义高价    double   _point   = MarketInfo(Symbol(), MODE_POINT); //- 定义所需的柱的价格    open1        = NormalizeDouble(iOpen(Symbol(), Period(), 1), Digits);    open2        = NormalizeDouble(iOpen(Symbol(), Period(), 2), Digits);    close1       = NormalizeDouble(iClose(Symbol(), Period(), 1), Digits);    close2       = NormalizeDouble(iClose(Symbol(), Period(), 2), Digits);    low1         = NormalizeDouble(iLow(Symbol(), Period(), 1), Digits);    low2         = NormalizeDouble(iLow(Symbol(), Period(), 2), Digits);    high1        = NormalizeDouble(iHigh(Symbol(), Period(), 1), Digits);    high2        = NormalizeDouble(iHigh(Symbol(), Period(), 2), Digits); //-    _bar2size=NormalizeDouble(((high2-low2)/_point),0); //- 如果第二个柱为熊势而第一个柱为牛势    if(timeBarInside!=iTime(Symbol(),Period(),1) && //此模式尚未开启订单       _bar2size>bar2size && //第二个柱足够大, 说明市场并不平缓       open2>close2 && //第二个柱为牛势       close1>open1 && //第一个柱是熊势       high2>high1 &&  //第二柱的最高价高于第一个柱的最高价       open2>close1 && //第二个柱的开盘价高于第一个柱的收盘价       low2<low1)      //第二个柱的最低价低于第一个柱的最低价      {       //- 我们已经列出了第一柱内含于第二柱的所有条件       timeBarInside=iTime(Symbol(),Period(),1); //表明已经为此模式开启订单      }   } //++


定义止损订单水平

现在所有的准备工作都已完成, 我们只需要定义止损订单水平和订单价格了. 并且, 别忘了订单过期时间的计算.

让我们把以下代码加入OnTick()函数体:

buyPrice=NormalizeDouble(high2+interval*_point,Digits);       //根据距离定义订单价格       buySL=NormalizeDouble(low2-interval*_point,Digits);     //根据距离定义止损       buyTP=NormalizeDouble(buyPrice+TP*_point,Digits);       //定义获利价位       _ExpDate=TimeCurrent()+ExpDate*60*60;                   //计算挂单过期时间       sellPrice=NormalizeDouble(low2-interval*_point,Digits);       sellSL=NormalizeDouble(high2+interval*_point,Digits);       sellTP=NormalizeDouble(sellPrice-TP*_point,Digits);


执行错误的修正

如果您开发过EA交易, 您也许知道当关闭订单, 设置订单, 包括等待时间, 不正确的止损值等等经常可能引发错误. 为了消除此类错误, 我们应该使用简单的内部基本错误处理写一个独立的函数.

//++ //| 开启和设置订单的函数                                                                                                    | //| symbol      - 订单的交易品种                                                                                           | //| cmd         - 交易类型 (可能等于任何交易类型值).                                                                         | //| volume      - 手数.                                                                                                   | //| price       - 开单价格.                                                                                               | //| slippage    - 市场买入或者卖出订单的最大点差.                                                                            | //| stoploss    - 当亏损达到某种水平关闭仓位的价位 (如果不设止损则为0).                                                         | //| takeprofit  - 当获利达到某种水平关闭仓位的价位 (如果不设获利则为0).                                                         | //| comment     - 订单注释. 注释的最后部分可能被交易服务器修改.                                                                | //| magic       - 订单幻数. 可以使用用户自定义的ID.                                                                          | //| expiration  - 挂单的过期时间.                                                                                          | //| arrow_color - 图表上开启订单的箭头颜色. 如果此参数空缺或者等于CLR_NONE,                                                     | //|               开单的箭头在图表上则不做显示.                                                                              | //++ int OrderOpenF(string     OO_symbol,                int        OO_cmd,                double     OO_volume,                double     OO_price,                int        OO_slippage,                double     OO_stoploss,                double     OO_takeprofit,                string     OO_comment,                int        OO_magic,                datetime   OO_expiration,                color      OO_arrow_color)   {    int      result      = -1;    //开启订单的结果    int      Error       = 0;     //开启订单出错编号    int      attempt     = 0;     //已经进行的尝试次数    int      attemptMax  = 3;     //最大尝试次数    bool     exit_loop   = false; //退出循环    string   lang=TerminalInfoString(TERMINAL_LANGUAGE);  //交易终端语言, 为了定义消息的语言    和double   stopllvl=NormalizeDouble(MarketInfo(OO_symbol,MODE_STOPLEVEL)*MarketInfo(OO_symbol,MODE_POINT),Digits);  //最小止损/获利水平点数                                                                                                                      //本模块提供了安全的订单开启功能.  //- 检查买入订单    if(OO_cmd==OP_BUY || OO_cmd==OP_BUYLIMIT || OO_cmd==OP_BUYSTOP)      {       double tp = (OO_takeprofit - OO_price)/MarketInfo(OO_symbol, MODE_POINT);       double sl = (OO_price - OO_stoploss)/MarketInfo(OO_symbol, MODE_POINT);       if(tp>0 && tp<=stopllvl)         {          OO_takeprofit=OO_price+stopllvl+2*MarketInfo(OO_symbol,MODE_POINT);         }       if(sl>0 && sl<=stopllvl)         {          OO_stoploss=OO_price -(stopllvl+2*MarketInfo(OO_symbol,MODE_POINT));         }      } //- 检查卖出订单    if(OO_cmd==OP_SELL || OO_cmd==OP_SELLLIMIT || OO_cmd==OP_SELLSTOP)      {       double tp = (OO_price - OO_takeprofit)/MarketInfo(OO_symbol, MODE_POINT);       double sl = (OO_stoploss - OO_price)/MarketInfo(OO_symbol, MODE_POINT);       if(tp>0 && tp<=stopllvl)         {          OO_takeprofit=OO_price -(stopllvl+2*MarketInfo(OO_symbol,MODE_POINT));         }       if(sl>0 && sl<=stopllvl)         {          OO_stoploss=OO_price+stopllvl+2*MarketInfo(OO_symbol,MODE_POINT);         }      } //- while 循环    while(!exit_loop)      {       result=OrderSend(OO_symbol,OO_cmd,OO_volume,OO_price,OO_slippage,OO_stoploss,OO_takeprofit,OO_comment,OO_magic,OO_expiration,OO_arrow_color); //尝试使用指定的参数下单       //- 如果开启订单出错       if(result<0)         {          Error = GetLastError();                                     //给错误码赋值          switch(Error)                                               //枚举错误            {                                                         //关闭订单出错的枚举, 并尝试修复错误             case  2:                if(attempt<attemptMax)                  {                   attempt=attempt+1;                                 //再多尝试一次                   Sleep(3000);                                       //延迟3秒                   RefreshRates();                   break;                                             //退出 switch                  }                if(attempt==attemptMax)                  {                   attempt=0;                                         //把尝试次数重设为0                    exit_loop = true;                                  //退出 while                   break;                                             //退出 switch                  }             case  3:                RefreshRates();                exit_loop = true;                                     //退出 while                break;                                                //退出 switch                case  4:                if(attempt<attemptMax)                  {                   attempt=attempt+1;                                 //再多尝试一次                   Sleep(3000);                                       //延迟3秒                   RefreshRates();                   break;                                             //退出 switch                  }                if(attempt==attemptMax)                  {                   attempt = 0;                                       //把尝试次数重设为0                   exit_loop = true;                                  //退出 while                   break;                                             //退出 switch                  }             case  5:                exit_loop = true;                                     //退出 while                break;                                                //退出 switch                case  6:                if(attempt<attemptMax)                  {                   attempt=attempt+1;                                 //再多尝试一次                   Sleep(5000);                                       //延迟5秒                   break;                                             //退出 switch                  }                if(attempt==attemptMax)                  {                   attempt = 0;                                       //把尝试次数重设为0                   exit_loop = true;                                  //退出 while                   break;                                             //退出 switch                  }             case  8:                if(attempt<attemptMax)                  {                   attempt=attempt+1;                                 //再多尝试一次                   Sleep(7000);                                       //延迟7秒                   break;                                             //退出 switch                  }                if(attempt==attemptMax)                  {                   attempt = 0;                                       //把尝试次数重设为0                   exit_loop = true;                                  //退出 while                   break;                                             //退出 switch                  }             case 64:                exit_loop = true;                                     //退出 while                break;                                                //退出 switch             case 65:                exit_loop = true;                                     //退出 while                break;                                                //退出 switch             case 128:                Sleep(3000);                RefreshRates();                continue;                                             //退出 switch             case 129:                if(attempt<attemptMax)                  {                   attempt=attempt+1;                                 //再多尝试一次                   Sleep(3000);                                       //延迟3秒                   RefreshRates();                   break;                                             //退出 switch                  }                if(attempt==attemptMax)                  {                   attempt = 0;                                       //把尝试次数重设为0                   exit_loop = true;                                  //退出 while                   break;                                             //退出 switch                  }             case 130:                exit_loop=true;                                       //退出 while                break;             case 131:                exit_loop = true;                                     //退出 while                break;                                                //退出 switch             case 132:                Sleep(10000);                                         //延迟10秒                RefreshRates();                                       //更新数据                //exit_loop = true;                                   //退出 while                break;                                                //退出 switch             case 133:                exit_loop=true;                                       //退出 while                break;                                                //退出 switch             case 134:                exit_loop=true;                                       //退出 while                break;                                                //退出 switch             case 135:                if(attempt<attemptMax)                  {                   attempt=attempt+1;                                 //再多尝试一次                   RefreshRates();                   break;                                             //退出 switch                  }                if(attempt==attemptMax)                  {                   attempt = 0;                                       //把尝试次数设为0                    exit_loop = true;                                  //退出 while                   break;                                             //退出 switch                  }             case 136:                if(attempt<attemptMax)                  {                   attempt=attempt+1;                                 //再多尝试一次                   RefreshRates();                   break;                                             //退出 switch                  }                if(attempt==attemptMax)                  {                   attempt = 0;                                       //把尝试次数设为0                    exit_loop = true;                                  //退出 while                   break;                                             //退出 switch                  }             case 137:                if(attempt<attemptMax)                  {                   attempt=attempt+1;                   Sleep(2000);                   RefreshRates();                   break;                  }                if(attempt==attemptMax)                  {                   attempt=0;                   exit_loop=true;                   break;                  }             case 138:                if(attempt<attemptMax)                  {                   attempt=attempt+1;                   Sleep(1000);                   RefreshRates();                   break;                  }                if(attempt==attemptMax)                  {                   attempt=0;                   exit_loop=true;                   break;                  }             case 139:                exit_loop=true;                break;             case 141:                Sleep(5000);                exit_loop=true;                break;             case 145:                exit_loop=true;                break;             case 146:                if(attempt<attemptMax)                  {                   attempt=attempt+1;                   Sleep(2000);                   RefreshRates();                   break;                  }                if(attempt==attemptMax)                  {                   attempt=0;                   exit_loop=true;                   break;                  }             case 147:                if(attempt<attemptMax)                  {                   attempt=attempt+1;                   OO_expiration=0;                   break;                  }                if(attempt==attemptMax)                  {                   attempt=0;                   exit_loop=true;                   break;                  }             case 148:                exit_loop=true;                break;             default:                Print("错误: ",Error);                exit_loop=true; //退出 while                 break;          //其他选项             }         }       //- 如果没有发现出错       else         {          if(lang == "Russian") {Print("Ордер успешно открыт. ", result);}          if(lang == "English") {Print("The order is successfully opened.", result);}          Error = 0;                                //把错误码重设为0          break;                                    //退出 while          //errorCount =0;                          //把尝试次数设为0         }      }    return(result);   } //++

结果我们可以获得如下代码:

//++ //|                                                    InsideBar.mq4 | //|                                  Copyright 2015, Iglakov Dmitry. | //|                                               cjdmitri@gmail.com | //++ #property copyright "Copyright 2015, Iglakov Dmitry." #property link      "cjdmitri@gmail.com" #property version   "1.00" #property strict extern int     interval          = 20;                               //距离 extern double  lot               = 0.1;                              //手数 extern int     TP                = 300;                              //获利 extern int     magic             = 555124;                           //幻数 extern int     slippage          = 2;                                //点差 extern int     ExpDate           = 48;                               //订单过期小时数 extern int     bar2size          = 800;                              //柱 2 的大小 double   buyPrice,//定义止损买入价位 buyTP,      //止损买入单的获利价位 buySL,      //止损买入单的止损价位 sellPrice,  //定义止损卖出价位 sellTP,     //止损卖出单的获利价位 sellSL;     //止损卖出单的止损价位 double   open1,//第一个柱的开盘价 open2,    //第二个柱的开盘价 close1,   //第一个柱的收盘价 close2,   //第二个柱的收盘价 low1,     //第一个柱的最低价 low2,     //第二个柱的最低价 high1,    //第一个柱的最高价 high2;    //第二个柱的最高价 datetime _ExpDate=0;          //定义订单过期时间的局部变量 double     _bar2size; datetime timeBarInside;       //内含柱订单开启的柱的时间, 防止重复下单 //++ //| EA 初始化函数                                                     | //++ int OnInit()   {    return(INIT_SUCCEEDED);   } //++ //| EA 终止化函数                                                     | //++ void OnDeinit(const int reason)   {   } //++ //| EA 订单处理函数                                                    | //++ void OnTick()   {    double   _bid     = NormalizeDouble(MarketInfo(Symbol(), MODE_BID), Digits); //定义低价     double   _ask     = NormalizeDouble(MarketInfo(Symbol(), MODE_ASK), Digits); //定义高价    double   _point   = MarketInfo(Symbol(), MODE_POINT); //- 定义所需的柱的价格    open1        = NormalizeDouble(iOpen(Symbol(), Period(), 1), Digits);    open2        = NormalizeDouble(iOpen(Symbol(), Period(), 2), Digits);    close1       = NormalizeDouble(iClose(Symbol(), Period(), 1), Digits);    close2       = NormalizeDouble(iClose(Symbol(), Period(), 2), Digits);    low1         = NormalizeDouble(iLow(Symbol(), Period(), 1), Digits);    low2         = NormalizeDouble(iLow(Symbol(), Period(), 2), Digits);    high1        = NormalizeDouble(iHigh(Symbol(), Period(), 1), Digits);    high2        = NormalizeDouble(iHigh(Symbol(), Period(), 2), Digits); //-    _bar2size=NormalizeDouble(((high2-low2)/_point),0); //- 如果第二个柱为熊势而第一个柱为牛势    if(timeBarInside!=iTime(Symbol(),Period(),1) && //此模式尚未开启订单       _bar2size>bar2size && //第二个柱足够大, 说明市场并不平缓       open2>close2 && //第二个柱为牛势       close1>open1 && //第一个柱是熊势       high2>high1 &&  //第二柱的最高价高于第一个柱的最高价       open2>close1 && //第二个柱的开盘价高于第一个柱的收盘价       low2<low1)      //第二个柱的最低价低于第一个柱的最低价      {       buyPrice=NormalizeDouble(high2+interval*_point,Digits); //根据间隔定义的订单价格       buySL=NormalizeDouble(low2-interval*_point,Digits);     //根据间隔定义的止损价格       buyTP=NormalizeDouble(buyPrice+TP*_point,Digits);       //定义获利价位       _ExpDate=TimeCurrent()+ExpDate*60*60;                   //挂单过期时间的计算       sellPrice=NormalizeDouble(low2-interval*_point,Digits);       sellSL=NormalizeDouble(high2+interval*_point,Digits);       sellTP=NormalizeDouble(sellPrice-TP*_point,Digits);       OrderOpenF(Symbol(),OP_BUYSTOP,lot,buyPrice,slippage,buySL,buyTP,NULL,magic,_ExpDate,Blue);       OrderOpenF(Symbol(),OP_SELLSTOP,lot,sellPrice,slippage,sellSL,sellTP,NULL,magic,_ExpDate,Blue);       //- we h*e listed all the conditions defining that the first bar is completely within the second one       timeBarInside=iTime(Symbol(),Period(),1); //指出此模式已经下单      }   } //++

现在让我们进行编译并在记录中检查错误信息.


测试EA交易

现在是时候测试我们的EA交易了. 让我们运行策略测试期并设置输入参数. 我设置了如下的参数:

图 6. 测试的输入参数

图 6. 测试的输入参数

  1. 选择一个交易品种 (在我的例子中是 CADJPY ).

  2. 请确认使用"每一订单(Every tick)"模式, 并且定义测试将在历史数据上进行. 我已经选择了2014年整年的数据.

  3. 设置的时间框架是D1.

  4. 运行测试.

  5. 测试结束后检查记录. 我们可以看到, 过程中没有错误.

以下是EA交易测试的日志:

图 7. EA 交易测试日志

图 7. EA 交易测试日志

确认没有出错后优化EA交易.


优化

我选择了如下的参数进行优化:

图 8. 优化参数

图 8. 优化参数



图 9. 优化设置

图 9. 优化设置

就这样, 我们就拥有了可以使用的EA交易.


优化和测试结果

图 10. 测试结果

图 10. 测试结果



图 11. 测试结果图

图 11. 测试结果图



结论

  1. 我们已经开发了可用的基于内含柱交易的 EA 交易.

  2. 我们已经确认, 即使不使用额外的进场过滤器价格行为模式也是可行的.

  3. 没有使用特殊的技巧(例如马丁格尔或者平均).

  4. 通过止损单的正确设置, 回撤已经被减到最小.

  5. 没有使用技术指标. 此交易机器人仅仅依赖于读取基本图表.


感谢您的阅读!我希望本文会有所帮助.


全部回复

0/140

量化课程

    移动端课程