19评论

0收藏

MACD Sample 真正的用面向对象的思路来写EA

avatar 编程逆袭仔 | 6597 人阅读 | 19 人评论 | 2013-11-22

我初步看了下系统自带的MACD Sample EA,这个实例其实用原来MT4的方式实现起来很简单。

但是我看了系统自带的代码:简直和C++代码没什么区别了:

首先应用头文件或者说是库文件。这些文件其实都是类库文件,每个类里面自带了许多处理方法

接着定义一个类

然后吧一些变量和方法都封装到类中。

最后void OnTick()程序实体部分简单的不可想象:

就是定义一个类的实例,然后调用一个类的方法就完了。

以后有时间我好好分析分析。

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

//| MACD Sample.mq5 |

//| Copyright 2001-2009, MetaQuotes Software Corp. |

//| http://www.mql5.com |

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

#property copyright "Copyright 2001-2009, MetaQuotes Software Corp."

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

#property version "5.04"

#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>
#include <Indicators\Indicators.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 double InpMACDOpenLevel =0.3; // MACD open level

input double InpMACDCloseLevel=0.2; // MACD close level

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

CIndicators *m_indicators; // indicator collection to fast recalculations

CiMACD *m_MACD; // MACD indicator object

CiMA *m_EMA; // moving average indicator object

//--- 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;

public:

CSampleExpert();

~CSampleExpert() { Deinit(); }

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_indicators=NULL;

m_MACD=NULL;

m_EMA =NULL;

//---

m_macd_current =0;

m_macd_previous =0;

m_signal_current =0;

m_signal_previous=0;

m_ema_current =0;

m_ema_previous =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_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(MathMod(InpLots,m_symbol.LotsStep()))>1.0E-15)

{

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 greater than Take Profit");

//--- ok

return(true);

}

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

//| Initialization of the indicators |

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

bool CSampleExpert::InitIndicators()

{

//--- create indicators collection

if(m_indicators==NULL)

if((m_indicators=new CIndicators)==NULL)

{

printf("Error creating indicators collection");

return(false);

}

//--- create MACD indicator and add it to collection

if(m_MACD==NULL)

if((m_MACD=new CiMACD)==NULL)

{

printf("Error creating MACD indicator");

return(false);

}

if(!m_indicators.Add(m_MACD))

{

printf("Error adding MACD indicator to collection");

return(false);

}

//--- initialize MACD indicator

if(!m_MACD.Create(NULL,0,12,26,9,PRICE_CLOSE))

{

printf("Error MACD indicator init");

return(false);

}

m_MACD.BuffSize(2);

//--- create EMA indicator and add it to collection

if(m_EMA==NULL)

if((m_EMA=new CiMA)==NULL)

{

printf("Error creating EMA indicator");

return(false);

}

if(!m_indicators.Add(m_EMA))

{

printf("Error adding EMA indicator to collection");

return(false);

}

//--- initialize EMA indicator

if(!m_EMA.Create(NULL,0,InpMATrendPeriod,0,MODE_EMA,PRICE_CLOSE))

{

printf("Error EMA indicator init");

return(false);

}

m_EMA.BuffSize(2);

//--- ok

return(true);

}

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

//| Function for deleting of dynamic objects |

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

void CSampleExpert::Deinit()

{

//--- delete indicators collection

if(m_indicators!=NULL)

{

delete m_indicators;

m_indicators=NULL;

m_MACD=NULL;

m_EMA =NULL;

}

//---

}

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

//| 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>InpMACDCloseLevel*m_adjusted_point)

{

//--- 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)>InpMACDCloseLevel*m_adjusted_point)

{

//--- 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)

{

if(m_position.StopLoss()<m_symbol.Bid()-m_adjusted_point*InpTrailingStop || m_position.StopLoss()==0.0)

{

double sl=m_symbol.Bid()-m_adjusted_point*InpTrailingStop;

double tp=m_position.TakeProfit();

//--- 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))

{

if((m_position.StopLoss()>(m_symbol.Ask()+m_adjusted_point*InpTrailingStop)) || m_position.StopLoss()==0.0)

{

double sl=m_symbol.Ask()+m_adjusted_point*InpTrailingStop;

double tp=m_position.TakeProfit();

//--- 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)>(InpMACDOpenLevel*m_adjusted_point) && m_ema_current>m_ema_previous)

{

//--- check for free money

if(m_account.FreeMarginCheck(Symbol(),0,InpLots)<0.0)

printf("We have no money. Free Margin = %f",m_account.FreeMargin());

else

{

double price=m_symbol.Ask();

double tp =m_symbol.Ask()+InpTakeProfit*m_adjusted_point;

//--- 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>(InpMACDOpenLevel*m_adjusted_point) && m_ema_current<m_ema_previous)

{

//--- check for free money

if(m_account.FreeMarginCheck(Symbol(),0,InpLots)<0.0)

printf("We have no money. Free Margin = %f",m_account.FreeMargin());

else

{

double price=m_symbol.Bid();

double tp =m_symbol.Bid()-InpTakeProfit*m_adjusted_point;

//--- 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

m_indicators.Refresh();

//--- to simplify the coding and speed up access

//--- data are put into internal variables

m_macd_current =m_MACD.Main(0);

m_macd_previous =m_MACD.Main(1);

m_signal_current =m_MACD.Signal(0);

m_signal_previous=m_MACD.Signal(1);

m_ema_current =m_EMA.Main(0);

m_ema_previous =m_EMA.Main(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()==OP_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())

{

ExtExpert.Deinit();

return(-1);

}

//--- ok

return(0);

}

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

//| Expert deinitialization function |

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

void OnDeinit(const int reason)

{

ExtExpert.Deinit();

}

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

//| 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;

}

}

//---

}

//+------------------------------------------------------------------+
""
还没有人打赏,支持一下

评论|共 19 个

clklcjl

发表于 2014-8-10 19:21:02 | 显示全部楼层

[s:135]

bhhbnela

发表于 2014-11-10 20:03:33 | 显示全部楼层

没有使用说明书

xctj

发表于 2014-11-27 01:00:00 | 显示全部楼层

亏损中……………………

365个日夜

发表于 2014-12-2 00:51:35 | 显示全部楼层

看看吧,谢谢分享

お灯心草ぷ

发表于 2014-12-10 15:05:22 | 显示全部楼层

xiexiefenxiang

80℃

发表于 2014-12-10 15:47:58 | 显示全部楼层

看看是什么东西啊

amm308

发表于 2014-12-10 15:48:10 | 显示全部楼层

ddddddddddddddddddddddddd

血狼舞

发表于 2020-3-4 11:25:30 | 显示全部楼层

真是 收益 匪浅

小丑

发表于 2020-6-30 16:57:31 | 显示全部楼层

LZ真是人才

12下一页
您需要登录后才可以回帖 登录 | 注册 微信登录

EA之家评论守则