找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
首页论坛EAHub 外汇论坛
查看: 7|回复: 0

【ATR源码】ATR源码

[复制链接]

7553

主题

54

回帖

4871

积分

管理员

积分
4871
发表于 6 天前 | 显示全部楼层 |阅读模式
//+------------------------------------------------------------------+

//|                                                   TradeByATR.mq5 |

//|                                  Copyright 2022, MetaQuotes Ltd. |

//|                                             https://www.mql5.com |

//+------------------------------------------------------------------+

#property copyright "Copyright 2022, MetaQuotes Ltd."

#property link      "https://www.mql5.com"

#property version   "1.00"


input double lots=0.1;        // 交易量手数

input double kATR=3;          // ATR中的信号蜡烛长度

input int    ATRperiod=20;    // ATR指标周期

input int    holdbars=8;      // 保持持仓的柱形图数量

input int    slippage=10;     // 可允许滑移

input bool   revers=false;    //反向信号?

input ulong  EXPERT_MAGIC=0;  // EA幻数

//--- 用于存储ATR指标句柄

int atr_handle;

//--- 在这里,我们将存储ATR最后值和蜡烛体

double last_atr,last_body;

datetime lastbar_timeopen;

double trade_lot;

//+------------------------------------------------------------------+

//| EA交易初始化函数                                                   |

//+------------------------------------------------------------------+

int OnInit()

  {

//--- 初始化全局变量

   last_atr=0;

   last_body=0;

//--- 设置正确的交易量

   double min_lot=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);

   trade_lot=lots>min_lot? lots:min_lot;   

//--- 创建ATR指标句柄

   atr_handle=iATR(_Symbol,_Period,ATRperiod);

   if(atr_handle==INVALID_HANDLE)

     {

      PrintFormat("%s: failed to create iATR, error code %d",__FUNCTION__,GetLastError());

      return(INIT_FAILED);

     }

//--- EA成功初始化

   return(INIT_SUCCEEDED);

  }

//+------------------------------------------------------------------+

//| EA交易去初始化函数                                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

  {

//--- 通知EA操作结束代码

   Print(__FILE__,": Deinitialization reason code = ",reason);

  }

//+------------------------------------------------------------------+

//| EA报价函数                                                        |

//+------------------------------------------------------------------+

void OnTick()

  {

//--- 交易信号

   static int signal=0; // +1表示买入信号, -1 表示卖出信号

//--- 检查和关闭‘holdbars’柱形图之前开仓的旧持仓

   ClosePositionsByBars(holdbars,slippage,EXPERT_MAGIC);

//--- 检查新柱形图

   if(isNewBar())

     {

      //--- 检查信号是否存在     

      signal=CheckSignal();

     }

//--- 如果持有单边持仓,跳过信号-等候直至关闭

   if(signal!=0 && PositionsTotal()>0 && (ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_NETTING)

     {

      signal=0;

      return; // 退出NewTick事件处理程序,并在新柱形图出现之前不要进入市场

     }

//--- 对于锁仓账户,每个持仓都是单独持仓和平仓

   if(signal!=0)

     {

      //--- 买入信号

      if(signal>0)

        {

         PrintFormat("%s: Buy signal! Revers=%s",__FUNCTION__,string(revers));

         if(Buy(trade_lot,slippage,EXPERT_MAGIC))

            signal=0;

        }

      //--- 卖出信号

      if(signal<0)

        {

         PrintFormat("%s: Sell signal! Revers=%s",__FUNCTION__,string(revers));

         if(Sell(trade_lot,slippage,EXPERT_MAGIC))

            signal=0;

        }

     }

//--- OnTick函数结束

  }

//+------------------------------------------------------------------+

//| 检查新的交易信号                                                   |

//+------------------------------------------------------------------+

int CheckSignal()

  {

//--- 0 意味着没有信号

   int res=0;

//--- 获得倒数第二个完整柱形图的ATR值(柱形图索引是2)

   double atr_value[1];

   if(CopyBuffer(atr_handle,0,2,1,atr_value)!=-1)

     {

      last_atr=atr_value[0];

      //--- 获得最后关闭的柱形图的MqlRates类型数组数据

      MqlRates bar[1];

      if(CopyRates(_Symbol,_Period,1,1,bar)!=-1)

        {

         //--- 计算最后完整柱形图的柱体大小

         last_body=bar[0].close-bar[0].open;

         //--- 如果最后柱形图的柱体(索引为1)超过的之前ATR的值(柱形图索引为2),那么会收到一个交易信号

         if(MathAbs(last_body)>kATR*last_atr)

            res=last_body>0?1:-1; // 向上蜡烛图的正值

        }

      else

         PrintFormat("%s: Failed to receive the last bar! Error",__FUNCTION__,GetLastError());

     }

   else

      PrintFormat("%s: Failed to receive ATR indicator value! Error",__FUNCTION__,GetLastError());

//--- 如果启用了反向交易模式

   res=revers?-res:res;  // 在必要时反转信号(返回-1而不是1,反之亦然)

//--- 返回一个交易信号值

   return (res);

  }

//+------------------------------------------------------------------+

//|  当新柱形图出现时返回'true'                                         |

//+------------------------------------------------------------------+

bool isNewBar(const bool print_log=true)

  {

   static datetime bartime=0; //存储当前柱形图的开盘时间

//--- 获得零柱的开盘时间

   datetime currbar_time=iTime(_Symbol,_Period,0);

//--- 如果开盘时间更改,则新柱形图出现

   if(bartime!=currbar_time)

     {

      bartime=currbar_time;

      lastbar_timeopen=bartime;

      //--- 在日志中显示新柱形图开盘时间的数据      

      if(print_log && !(MQLInfoInteger(MQL_OPTIMIZATION)||MQLInfoInteger(MQL_TESTER)))

        {

         //--- 显示新柱形图开盘时间的信息

         PrintFormat("%s: new bar on %s %s opened at %s",__FUNCTION__,_Symbol,

                     StringSubstr(EnumToString(_Period),7),

                     TimeToString(TimeCurrent(),TIME_SECONDS));

         //--- 获取关于最后报价的数据

         MqlTick last_tick;

         if(!SymbolInfoTick(Symbol(),last_tick))

            Print("SymbolInfoTick() failed, error = ",GetLastError());

         //--- 显示最后报价的时间,精确至毫秒

         PrintFormat("Last tick was at %s.%03d",

                     TimeToString(last_tick.time,TIME_SECONDS),last_tick.time_msc%1000);

        }

      //--- 我们有一个新柱形图

      return (true);

     }

//--- 没有新柱形图

   return (false);

  }

//+------------------------------------------------------------------+

//| 以指定交易量和市场价买入                                            |

//+------------------------------------------------------------------+

bool Buy(double volume,ulong deviation=10,ulong  magicnumber=0)

  {

//--- 以市场价买入

   return (MarketOrder(ORDER_TYPE_BUY,volume,deviation,magicnumber));

  }

//+------------------------------------------------------------------+

//| 以指定交易量和市场价卖出                                             |

//+------------------------------------------------------------------+

bool Sell(double volume,ulong deviation=10,ulong  magicnumber=0)

  {

//--- 以市场价卖出

   return (MarketOrder(ORDER_TYPE_SELL,volume,deviation,magicnumber));

  }

//+------------------------------------------------------------------+

//| 在柱形图中根据持有时间平仓                                           |

//+------------------------------------------------------------------+

void ClosePositionsByBars(int holdtimebars,ulong deviation=10,ulong  magicnumber=0)

  {

   int total=PositionsTotal(); // 持仓数量  

//--- 重复持仓

   for(int i=total-1; i>=0; i--)

     {

      //--- 持仓参数

      ulong  position_ticket=PositionGetTicket(i);                                      // 持仓单号

      string position_symbol=PositionGetString(POSITION_SYMBOL);                        //交易品种

      ulong  magic=PositionGetInteger(POSITION_MAGIC);                                  // 持仓幻数

      datetime position_open=(datetime)PositionGetInteger(POSITION_TIME);               // 持仓开盘时间

      int bars=iBarShift(_Symbol,PERIOD_CURRENT,position_open)+1;                       // 开仓之前有多少柱形图


      //--- 如果持仓的生命周期很长,则幻数和交易品种匹配

      if(bars>holdtimebars && magic==magicnumber && position_symbol==_Symbol)

        {

         int    digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS);           // 小数位数

         double volume=PositionGetDouble(POSITION_VOLUME);                              // 持仓交易量

         ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // 持仓类型

         string str_type=StringSubstr(EnumToString(type),14);

         StringToLower(str_type); //纠正消息格式的小写文本案例

         PrintFormat("Close position #%d %s %s %.2f",

                     position_ticket,position_symbol,str_type,volume);

         //--- 设置一个订单类型并发送交易请求

         if(type==POSITION_TYPE_BUY)

            MarketOrder(ORDER_TYPE_SELL,volume,deviation,magicnumber,position_ticket);

         else

            MarketOrder(ORDER_TYPE_BUY,volume,deviation,magicnumber,position_ticket);

        }

     }

  }

//+------------------------------------------------------------------+

//| 准备和发送交易请求                                                  |

//+------------------------------------------------------------------+

bool MarketOrder(ENUM_ORDER_TYPE type,double volume,ulong slip,ulong magicnumber,ulong pos_ticket=0)

  {

//--- 声明和初始化结构

   MqlTradeRequest request={};

   MqlTradeResult  result={};

   double price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

   if(type==ORDER_TYPE_BUY)

      price=SymbolInfoDouble(Symbol(),SYMBOL_ASK);

//--- 请求参数

   request.action   =TRADE_ACTION_DEAL;                     // 交易操作类型

   request.position =pos_ticket;                            // 关闭情况下的持仓单号

   request.symbol   =Symbol();                              // 交易品种

   request.volume   =volume;                                // 交易量

   request.type     =type;                                  // 订单类型

   request.price    =price;                                 // 交易价格

   request.deviation=slip;                                  // 可允许的价格偏差

   request.magic    =magicnumber;                           // 订单幻数

   request.type_filling=ORDER_FILLING_IOC;

//--- 发送请求

   if(!OrderSend(request,result))

     {

      //--- 显示数据失败

      PrintFormat("OrderSend %s %s %.2f at %.5f error %d",

                  request.symbol,EnumToString(type),volume,request.price,GetLastError());

      return (false);

     }

//--- 通知成功操作

   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);

   return (true);

  }
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|EAHub外汇论坛

GMT+8, 2026-8-25 16:36 , Processed in 0.106049 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表