直接进入主题,日后补充
MQL5是用来炒外汇的编程语言
基于C++,所以大家应该很熟悉
首先,我们要创建一个Class,
//+------------------------------------------------------------------+ //| MACD Sample expert class | //+------------------------------------------------------------------+ class CSampleExpert { protected: double m_adjusted_point; // point value adjusted for 3 or 5 points CTrade m_trade; // trading object CSymbolInfo m_symbol; // symbol info object CPositionInfo m_position; // trade position object CAccountInfo m_account; // account info wrapper //--- indicators int m_handle_macd; // MACD indicator handle int m_handle_ema; // moving average indicator handle //--- indicator buffers double m_buff_MACD_main[]; // MACD indicator main buffer double m_buff_MACD_signal[]; // MACD indicator signal buffer double m_buff_EMA[]; // EMA indicator buffer //--- indicator data for processing double m_macd_current; double m_macd_previous; double m_signal_current; double m_signal_previous; double m_ema_current; double m_ema_previous; //--- double m_macd_open_level; double m_macd_close_level; double m_traling_stop; double m_take_profit; public: CSampleExpert(); bool Init(); void Deinit(); bool Processing(); protected: bool InitCheckParameters(int digits_adjust); bool InitIndicators(); bool LongClosed(); bool ShortClosed(); bool LongModified(); bool ShortModified(); bool LongOpened(); bool ShortOpened(); };这里解释下,第一部分是成员变量,第二部分是构造函数,init函数,deinit函数,Processing函数,其实都不是必须的,只是为了加强理解。protected里面的东西,下面开始解释。
首先是init函数
//+------------------------------------------------------------------+ //| Initialization and checking for input parameters | //+------------------------------------------------------------------+ bool CSampleExpert::Init() { //--- initialize common information m_symbol.Name(Symbol()); // symbol m_trade.SetExpertMagicNumber(12345); // magic //--- tuning for 3 or 5 digits int digits_adjust=1; if(m_symbol.Digits()==3 || m_symbol.Digits()==5) digits_adjust=10; m_adjusted_point=m_symbol.Point()*digits_adjust; //--- set default deviation for trading in adjusted points m_macd_open_level =InpMACDOpenLevel*m_adjusted_point; m_macd_close_level=InpMACDCloseLevel*m_adjusted_point; m_traling_stop =InpTrailingStop*m_adjusted_point; m_take_profit =InpTakeProfit*m_adjusted_point; //--- set default deviation for trading in adjusted points m_trade.SetDeviationInPoints(3*digits_adjust); //--- if(!InitCheckParameters(digits_adjust)) return(false); if(!InitIndicators()) return(false); //--- ok return(true); }前面的内容,自己去看书,我就说下最后两句,调用了两个函数,一个是初始化参数的,另外一个是初始化,指标
我们一个一个来看
先看
InitCheckParameters代码
//+------------------------------------------------------------------+ //| Checking for input parameters | //+------------------------------------------------------------------+ bool CSampleExpert::InitCheckParameters(int digits_adjust) { //--- initial data checks if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel()) { printf("Take Profit must be greater than %d",m_symbol.StopsLevel()); return(false); } if(InpTrailingStop*digits_adjust<m_symbol.StopsLevel()) { printf("Trailing Stop must be greater than %d",m_symbol.StopsLevel()); return(false); } //--- check for right lots amount if(InpLots<m_symbol.LotsMin() || InpLots>m_symbol.LotsMax()) { printf("Lots amount must be in the range from %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax()); return(false); } if(MathAbs(InpLots/m_symbol.LotsStep()-MathRound(InpLots/m_symbol.LotsStep()))>1.0E-10) { printf("Lots amount is not corresponding with lot step %f",m_symbol.LotsStep()); return(false); } //--- warning if(InpTakeProfit<=InpTrailingStop) printf("Warning: Trailing Stop must be less than Take Profit"); //--- ok return(true); }然后是
//+------------------------------------------------------------------+ //| Initialization of the indicators | //+------------------------------------------------------------------+ bool CSampleExpert::InitIndicators() { //--- create MACD indicator if(m_handle_macd==INVALID_HANDLE) if((m_handle_macd=iMACD(NULL,0,12,26,9,PRICE_CLOSE))==INVALID_HANDLE) { printf("Error creating MACD indicator"); return(false); } //--- create EMA indicator and add it to collection if(m_handle_ema==INVALID_HANDLE) if((m_handle_ema=iMA(NULL,0,InpMATrendPeriod,0,MODE_EMA,PRICE_CLOSE))==INVALID_HANDLE) { printf("Error creating EMA indicator"); return(false); } //--- ok return(true); }初始化都完成以后,开始Processing函数
代码如下
//+------------------------------------------------------------------+ //| main function returns true if any position processed | //+------------------------------------------------------------------+ bool CSampleExpert::Processing() { //--- refresh rates if(!m_symbol.RefreshRates()) return(false); //--- refresh indicators if(BarsCalculated(m_handle_macd)<2 || BarsCalculated(m_handle_ema)<2) return(false); if(CopyBuffer(m_handle_macd,0,0,2,m_buff_MACD_main) !=2 || CopyBuffer(m_handle_macd,1,0,2,m_buff_MACD_signal)!=2 || CopyBuffer(m_handle_ema,0,0,2,m_buff_EMA) !=2) return(false); // m_indicators.Refresh(); //--- to simplify the coding and speed up access //--- data are put into internal variables m_macd_current =m_buff_MACD_main[0]; m_macd_previous =m_buff_MACD_main[1]; m_signal_current =m_buff_MACD_signal[0]; m_signal_previous=m_buff_MACD_signal[1]; m_ema_current =m_buff_EMA[0]; m_ema_previous =m_buff_EMA[1]; //--- it is important to enter the market correctly, //--- but it is more important to exit it correctly... //--- first check if position exists - try to select it if(m_position.Select(Symbol())) { if(m_position.PositionType()==POSITION_TYPE_BUY) { //--- try to close or modify long position if(LongClosed()) return(true); if(LongModified()) return(true); } else { //--- try to close or modify short position if(ShortClosed()) return(true); if(ShortModified()) return(true); } } //--- no opened position identified else { //--- check for long position (BUY) possibility if(LongOpened()) return(true); //--- check for short position (SELL) possibility if(ShortOpened()) return(true); } //--- exit without position processing return(false); }这里的longopen表示卖出下单,longclose表示卖出下单关闭
同理,shortopen表示买入下单,shortclose表示买入下单关闭
因为期货是双向的交易,可以做双向操作。
给出这四个函数
//+------------------------------------------------------------------+ //| Check for long position closing | //+------------------------------------------------------------------+ bool CSampleExpert::LongClosed() { bool res=false; //--- should it be closed? if(m_macd_current>0) if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous) if(m_macd_current>m_macd_close_level) { //--- close position if(m_trade.PositionClose(Symbol())) printf("Long position by %s to be closed",Symbol()); else printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment()); //--- processed and cannot be modified res=true; } //--- return(res); } //+------------------------------------------------------------------+ //| Check for short position closing | //+------------------------------------------------------------------+ bool CSampleExpert::ShortClosed() { bool res=false; //--- should it be closed? if(m_macd_current<0) if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous) if(MathAbs(m_macd_current)>m_macd_close_level) { //--- close position if(m_trade.PositionClose(Symbol())) printf("Short position by %s to be closed",Symbol()); else printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment()); //--- processed and cannot be modified res=true; } //--- return(res); } //+------------------------------------------------------------------+ //| Check for long position opening | //+------------------------------------------------------------------+ bool CSampleExpert::LongOpened() { bool res=false; //--- check for long position (BUY) possibility if(m_macd_current<0) if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous) if(MathAbs(m_macd_current)>(m_macd_open_level) && m_ema_current>m_ema_previous) { double price=m_symbol.Ask(); double tp =m_symbol.Bid()+m_take_profit; //--- check for free money if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_BUY,InpLots,price)<0.0) printf("We have no money. Free Margin = %f",m_account.FreeMargin()); else { //--- open position if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,InpLots,price,0.0,tp)) printf("Position by %s to be opened",Symbol()); else { printf("Error opening BUY position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Open parameters : price=%f,TP=%f",price,tp); } } //--- in any case we must exit from expert res=true; } //--- return(res); } //+------------------------------------------------------------------+ //| Check for short position opening | //+------------------------------------------------------------------+ bool CSampleExpert::ShortOpened() { bool res=false; //--- check for short position (SELL) possibility if(m_macd_current>0) if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous) if(m_macd_current>(m_macd_open_level) && m_ema_current<m_ema_previous) { double price=m_symbol.Bid(); double tp =m_symbol.Ask()-m_take_profit; //--- check for free money if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL,InpLots,price)<0.0) printf("We have no money. Free Margin = %f",m_account.FreeMargin()); else { //--- open position if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,InpLots,price,0.0,tp)) printf("Position by %s to be opened",Symbol()); else { printf("Error opening SELL position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Open parameters : price=%f,TP=%f",price,tp); } } //--- in any case we must exit from expert res=true; } //--- return(res); }再给出两个修改订单的函数
//+------------------------------------------------------------------+ //| Check for long position modifying | //+------------------------------------------------------------------+ bool CSampleExpert::LongModified() { bool res=false; //--- check for trailing stop if(InpTrailingStop>0) { if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop) { double sl=NormalizeDouble(m_symbol.Bid()-m_traling_stop,m_symbol.Digits()); double tp=m_position.TakeProfit(); if(m_position.StopLoss()<sl || m_position.StopLoss()==0.0) { //--- modify position if(m_trade.PositionModify(Symbol(),sl,tp)) printf("Long position by %s to be modified",Symbol()); else { printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Modify parameters : SL=%f,TP=%f",sl,tp); } //--- modified and must exit from expert res=true; } } } //--- return(res); } //+------------------------------------------------------------------+ //| Check for short position modifying | //+------------------------------------------------------------------+ bool CSampleExpert::ShortModified() { bool res=false; //--- check for trailing stop if(InpTrailingStop>0) { if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop)) { double sl=NormalizeDouble(m_symbol.Ask()+m_traling_stop,m_symbol.Digits()); double tp=m_position.TakeProfit(); if(m_position.StopLoss()>sl || m_position.StopLoss()==0.0) { //--- modify position if(m_trade.PositionModify(Symbol(),sl,tp)) printf("Short position by %s to be modified",Symbol()); else { printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Modify parameters : SL=%f,TP=%f",sl,tp); } //--- modified and must exit from expert res=true; } } } //--- return(res); }最后补上这个类的构造函数
CSampleExpert::CSampleExpert() { //--- m_adjusted_point=0; m_handle_macd=INVALID_HANDLE; m_handle_ema =INVALID_HANDLE; //--- ArraySetAsSeries(m_buff_MACD_main,true); ArraySetAsSeries(m_buff_MACD_signal,true); ArraySetAsSeries(m_buff_EMA,true); //--- m_macd_current =0; m_macd_previous =0; m_signal_current =0; m_signal_previous =0; m_ema_current =0; m_ema_previous =0; //--- m_macd_open_level =0; m_macd_close_level=0; m_traling_stop =0; m_take_profit =0; }最后写一个程序的初始化函数
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- create all necessary objects if(!ExtExpert.Init()) return(-1); //--- ok return(0); }还有程序的执行函数
//+------------------------------------------------------------------+ //| Expert new tick handling function | //+------------------------------------------------------------------+ void OnTick() { static datetime limit_time=0; // last trade processing time + timeout //--- don't process if timeout if(TimeCurrent()>=limit_time) { //--- check for data if(Bars(Symbol(),Period())>2*InpMATrendPeriod) { //--- change limit time by timeout in seconds if processed if(ExtExpert.Processing()) limit_time=TimeCurrent()+ExtTimeOut; } } //--- }这两个函数是必须的,否则EA是不能运行的
现在给出完整的代码
//+------------------------------------------------------------------+ //| MACD Sample.mq5 | //| Copyright 2010, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2010, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "5.20" #property description "It is important to make sure that the expert works with a normal" #property description "chart and the user did not make any mistakes setting input" #property description "variables (Lots, TakeProfit, TrailingStop) in our case," #property description "we check TakeProfit on a chart of more than 2*trend_period bars" //--- #include <Trade\Trade.mqh> #include <Trade\SymbolInfo.mqh> #include <Trade\PositionInfo.mqh> #include <Trade\AccountInfo.mqh> //--- input double InpLots =0.1; // Lots input int InpTakeProfit =50; // Take Profit (in pips) input int InpTrailingStop =30; // Trailing Stop Level (in pips) input int InpMACDOpenLevel =3; // MACD open level (in pips) input int InpMACDCloseLevel=2; // MACD close level (in pips) input int InpMATrendPeriod =26; // MA trend period //--- int ExtTimeOut=10; // time out in seconds between trade operations //+------------------------------------------------------------------+ //| MACD Sample expert class | //+------------------------------------------------------------------+ class CSampleExpert { protected: double m_adjusted_point; // point value adjusted for 3 or 5 points CTrade m_trade; // trading object CSymbolInfo m_symbol; // symbol info object CPositionInfo m_position; // trade position object CAccountInfo m_account; // account info wrapper //--- indicators int m_handle_macd; // MACD indicator handle int m_handle_ema; // moving average indicator handle //--- indicator buffers double m_buff_MACD_main[]; // MACD indicator main buffer double m_buff_MACD_signal[]; // MACD indicator signal buffer double m_buff_EMA[]; // EMA indicator buffer //--- indicator data for processing double m_macd_current; double m_macd_previous; double m_signal_current; double m_signal_previous; double m_ema_current; double m_ema_previous; //--- double m_macd_open_level; double m_macd_close_level; double m_traling_stop; double m_take_profit; public: CSampleExpert(); bool Init(); void Deinit(); bool Processing(); protected: bool InitCheckParameters(int digits_adjust); bool InitIndicators(); bool LongClosed(); bool ShortClosed(); bool LongModified(); bool ShortModified(); bool LongOpened(); bool ShortOpened(); }; //--- CSampleExpert ExtExpert; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CSampleExpert::CSampleExpert() { //--- m_adjusted_point=0; m_handle_macd=INVALID_HANDLE; m_handle_ema =INVALID_HANDLE; //--- ArraySetAsSeries(m_buff_MACD_main,true); ArraySetAsSeries(m_buff_MACD_signal,true); ArraySetAsSeries(m_buff_EMA,true); //--- m_macd_current =0; m_macd_previous =0; m_signal_current =0; m_signal_previous =0; m_ema_current =0; m_ema_previous =0; //--- m_macd_open_level =0; m_macd_close_level=0; m_traling_stop =0; m_take_profit =0; } //+------------------------------------------------------------------+ //| Initialization and checking for input parameters | //+------------------------------------------------------------------+ bool CSampleExpert::Init() { //--- initialize common information m_symbol.Name(Symbol()); // symbol m_trade.SetExpertMagicNumber(12345); // magic //--- tuning for 3 or 5 digits int digits_adjust=1; if(m_symbol.Digits()==3 || m_symbol.Digits()==5) digits_adjust=10; m_adjusted_point=m_symbol.Point()*digits_adjust; //--- set default deviation for trading in adjusted points m_macd_open_level =InpMACDOpenLevel*m_adjusted_point; m_macd_close_level=InpMACDCloseLevel*m_adjusted_point; m_traling_stop =InpTrailingStop*m_adjusted_point; m_take_profit =InpTakeProfit*m_adjusted_point; //--- set default deviation for trading in adjusted points m_trade.SetDeviationInPoints(3*digits_adjust); //--- if(!InitCheckParameters(digits_adjust)) return(false); if(!InitIndicators()) return(false); //--- ok return(true); } //+------------------------------------------------------------------+ //| Checking for input parameters | //+------------------------------------------------------------------+ bool CSampleExpert::InitCheckParameters(int digits_adjust) { //--- initial data checks if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel()) { printf("Take Profit must be greater than %d",m_symbol.StopsLevel()); return(false); } if(InpTrailingStop*digits_adjust<m_symbol.StopsLevel()) { printf("Trailing Stop must be greater than %d",m_symbol.StopsLevel()); return(false); } //--- check for right lots amount if(InpLots<m_symbol.LotsMin() || InpLots>m_symbol.LotsMax()) { printf("Lots amount must be in the range from %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax()); return(false); } if(MathAbs(InpLots/m_symbol.LotsStep()-MathRound(InpLots/m_symbol.LotsStep()))>1.0E-10) { printf("Lots amount is not corresponding with lot step %f",m_symbol.LotsStep()); return(false); } //--- warning if(InpTakeProfit<=InpTrailingStop) printf("Warning: Trailing Stop must be less than Take Profit"); //--- ok return(true); } //+------------------------------------------------------------------+ //| Initialization of the indicators | //+------------------------------------------------------------------+ bool CSampleExpert::InitIndicators() { //--- create MACD indicator if(m_handle_macd==INVALID_HANDLE) if((m_handle_macd=iMACD(NULL,0,12,26,9,PRICE_CLOSE))==INVALID_HANDLE) { printf("Error creating MACD indicator"); return(false); } //--- create EMA indicator and add it to collection if(m_handle_ema==INVALID_HANDLE) if((m_handle_ema=iMA(NULL,0,InpMATrendPeriod,0,MODE_EMA,PRICE_CLOSE))==INVALID_HANDLE) { printf("Error creating EMA indicator"); return(false); } //--- ok return(true); } //+------------------------------------------------------------------+ //| Check for long position closing | //+------------------------------------------------------------------+ bool CSampleExpert::LongClosed() { bool res=false; //--- should it be closed? if(m_macd_current>0) if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous) if(m_macd_current>m_macd_close_level) { //--- close position if(m_trade.PositionClose(Symbol())) printf("Long position by %s to be closed",Symbol()); else printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment()); //--- processed and cannot be modified res=true; } //--- return(res); } //+------------------------------------------------------------------+ //| Check for short position closing | //+------------------------------------------------------------------+ bool CSampleExpert::ShortClosed() { bool res=false; //--- should it be closed? if(m_macd_current<0) if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous) if(MathAbs(m_macd_current)>m_macd_close_level) { //--- close position if(m_trade.PositionClose(Symbol())) printf("Short position by %s to be closed",Symbol()); else printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment()); //--- processed and cannot be modified res=true; } //--- return(res); } //+------------------------------------------------------------------+ //| Check for long position modifying | //+------------------------------------------------------------------+ bool CSampleExpert::LongModified() { bool res=false; //--- check for trailing stop if(InpTrailingStop>0) { if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop) { double sl=NormalizeDouble(m_symbol.Bid()-m_traling_stop,m_symbol.Digits()); double tp=m_position.TakeProfit(); if(m_position.StopLoss()<sl || m_position.StopLoss()==0.0) { //--- modify position if(m_trade.PositionModify(Symbol(),sl,tp)) printf("Long position by %s to be modified",Symbol()); else { printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Modify parameters : SL=%f,TP=%f",sl,tp); } //--- modified and must exit from expert res=true; } } } //--- return(res); } //+------------------------------------------------------------------+ //| Check for short position modifying | //+------------------------------------------------------------------+ bool CSampleExpert::ShortModified() { bool res=false; //--- check for trailing stop if(InpTrailingStop>0) { if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop)) { double sl=NormalizeDouble(m_symbol.Ask()+m_traling_stop,m_symbol.Digits()); double tp=m_position.TakeProfit(); if(m_position.StopLoss()>sl || m_position.StopLoss()==0.0) { //--- modify position if(m_trade.PositionModify(Symbol(),sl,tp)) printf("Short position by %s to be modified",Symbol()); else { printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Modify parameters : SL=%f,TP=%f",sl,tp); } //--- modified and must exit from expert res=true; } } } //--- return(res); } //+------------------------------------------------------------------+ //| Check for long position opening | //+------------------------------------------------------------------+ bool CSampleExpert::LongOpened() { bool res=false; //--- check for long position (BUY) possibility if(m_macd_current<0) if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous) if(MathAbs(m_macd_current)>(m_macd_open_level) && m_ema_current>m_ema_previous) { double price=m_symbol.Ask(); double tp =m_symbol.Bid()+m_take_profit; //--- check for free money if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_BUY,InpLots,price)<0.0) printf("We have no money. Free Margin = %f",m_account.FreeMargin()); else { //--- open position if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,InpLots,price,0.0,tp)) printf("Position by %s to be opened",Symbol()); else { printf("Error opening BUY position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Open parameters : price=%f,TP=%f",price,tp); } } //--- in any case we must exit from expert res=true; } //--- return(res); } //+------------------------------------------------------------------+ //| Check for short position opening | //+------------------------------------------------------------------+ bool CSampleExpert::ShortOpened() { bool res=false; //--- check for short position (SELL) possibility if(m_macd_current>0) if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous) if(m_macd_current>(m_macd_open_level) && m_ema_current<m_ema_previous) { double price=m_symbol.Bid(); double tp =m_symbol.Ask()-m_take_profit; //--- check for free money if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL,InpLots,price)<0.0) printf("We have no money. Free Margin = %f",m_account.FreeMargin()); else { //--- open position if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,InpLots,price,0.0,tp)) printf("Position by %s to be opened",Symbol()); else { printf("Error opening SELL position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Open parameters : price=%f,TP=%f",price,tp); } } //--- in any case we must exit from expert res=true; } //--- return(res); } //+------------------------------------------------------------------+ //| main function returns true if any position processed | //+------------------------------------------------------------------+ bool CSampleExpert::Processing() { //--- refresh rates if(!m_symbol.RefreshRates()) return(false); //--- refresh indicators if(BarsCalculated(m_handle_macd)<2 || BarsCalculated(m_handle_ema)<2) return(false); if(CopyBuffer(m_handle_macd,0,0,2,m_buff_MACD_main) !=2 || CopyBuffer(m_handle_macd,1,0,2,m_buff_MACD_signal)!=2 || CopyBuffer(m_handle_ema,0,0,2,m_buff_EMA) !=2) return(false); // m_indicators.Refresh(); //--- to simplify the coding and speed up access //--- data are put into internal variables m_macd_current =m_buff_MACD_main[0]; m_macd_previous =m_buff_MACD_main[1]; m_signal_current =m_buff_MACD_signal[0]; m_signal_previous=m_buff_MACD_signal[1]; m_ema_current =m_buff_EMA[0]; m_ema_previous =m_buff_EMA[1]; //--- it is important to enter the market correctly, //--- but it is more important to exit it correctly... //--- first check if position exists - try to select it if(m_position.Select(Symbol())) { if(m_position.PositionType()==POSITION_TYPE_BUY) { //--- try to close or modify long position if(LongClosed()) return(true); if(LongModified()) return(true); } else { //--- try to close or modify short position if(ShortClosed()) return(true); if(ShortModified()) return(true); } } //--- no opened position identified else { //--- check for long position (BUY) possibility if(LongOpened()) return(true); //--- check for short position (SELL) possibility if(ShortOpened()) return(true); } //--- exit without position processing return(false); } //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- create all necessary objects if(!ExtExpert.Init()) return(-1); //--- ok return(0); } //+------------------------------------------------------------------+ //| Expert new tick handling function | //+------------------------------------------------------------------+ void OnTick() { static datetime limit_time=0; // last trade processing time + timeout //--- don't process if timeout if(TimeCurrent()>=limit_time) { //--- check for data if(Bars(Symbol(),Period())>2*InpMATrendPeriod) { //--- change limit time by timeout in seconds if processed if(ExtExpert.Processing()) limit_time=TimeCurrent()+ExtTimeOut; } } //--- } //+------------------------------------------------------------------+game over!有问题的同学快点提问啊,不然明天我就开始下一讲了~
这个是根据MACD指标和EMA指标来确定交易规则的一个自动交易机器人
当然了,就是一个例子,我们还是要完善它的