在本篇文章中,我们将介绍如何创建一个基于移动平均线交叉的自动交易系统(EA),并通过 Heikin Ashi 指标来优化交易策略。
定义输入参数
//--- 输入参数 input int period_ma_fast = 8; //快速移动平均周期 input int period_ma_slow = 20; //慢速移动平均周期 input double takeProfit = 20.0; //止盈(点数) input double stopLoss = 20.0 //止损(点数) input double lotSize = 0.10; //手数 input double minEquity = 100.0; //最低资金要求(美元) input int Slippage = 3; //滑点 input int MagicNumber = 889; //魔术编号
定义全局变量
//全局变量 double myPoint = 0.0; int mySlippage = 0; int BuyTicket = 0; int SellTicket = 0;
初始化函数
当 EA 被执行时,首先调用的是 OnInit() 函数。在这里,我们通常会进行输入数据的验证和全局变量的初始化。
int OnInit() { //验证输入数据 if (period_ma_fast >= period_ma_slow || takeProfit < 0.0 || stopLoss < 0.0 || lotSize < 0.01 || minEquity < 10) { Alert("警告 - 输入数据无效"); return (INIT_PARAMETERS_INCORRECT); } double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN); if(lotSize<min_volume) { string message =StringFormat("手数小于允许的最小值 %.2f",min_volume); Alert(message); return(INIT_PARAMETERS_INCORRECT); } myPoint = GetPipPoint(Symbol()); mySlippage = GetSlippage(Symbol(),Slippage); return(INIT_SUCCEEDED); }
市场价格变化时的逻辑
当市场价格发生变化时,OnTick() 函数将被调用,执行其中的所有指令。
在 OnTick() 函数中,我们将调用多个其他函数。
首先调用 checkMinEquity() 函数来检查交易资金的充足性。若资金足够(超过最低要求),将继续声明信号变量,并调用 NewCandle() 函数以通知新的蜡烛形成。
getSignal() 函数将读取两个移动平均指标的值,并返回信号信息,指示是否存在向上或向下的交叉信号,作为买入或卖出的依据。
基于此信号信息,将传递给 transaction() 函数以设置开仓方向。
接着调用 setTPSL() 函数来设置止盈和止损价格。
若资金未满足最低要求,将弹出警告并终止 EA。
void OnTick() { if (cekMinEquity()) { int signal = -1; bool isNewCandle = NewCandle(Period(), Symbol()); signal = getSignal(isNewCandle); transaction(isNewCandle, signal); setTPSL(); }else{ //停止交易,因为资金不足 Print("EA 将因资金不足而被终止"); } }
设置止盈和止损的函数
void setTPSL() { int tOrder = 0; string strMN = "", pair = ""; double sl = 0.0, tp = 0.0; pair = Symbol(); tOrder = OrdersTotal(); for (int i=tOrder-1; i>=0; i--) { bool hrsSelect = OrderSelect(i, SELECT_BY_POS, MODE_TRADES); strMN = IntegerToString(OrderMagicNumber()); if (StringFind(strMN, IntegerToString(MagicNumber), 0) == 0 && StringFind(OrderSymbol(), pair, 0) == 0) { if (OrderType() == OP_BUY && (OrderTakeProfit() == 0 || OrderStopLoss() == 0)) { if (takeProfit > 0) { tp = OrderOpenPrice() + (takeProfit * myPoint); }else { tp = OrderOpenPrice(); } if (stopLoss > 0) { sl = OrderOpenPrice() - (stopLoss * myPoint); }else { sl = OrderStopLoss(); } if (OrderTakeProfit() != tp || OrderStopLoss() != sl) { if(OrderModify(OrderTicket(), OrderOpenPrice(), sl, tp, 0, clrBlue)) { Print("订单修改成功"); } } } if (OrderType() == OP_SELL && (OrderTakeProfit() == 0 || OrderStopLoss() == 0)) { if (takeProfit > 0) { tp = OrderOpenPrice() - (takeProfit * myPoint); }else { tp = OrderOpenPrice(); } if (stopLoss > 0) { sl = OrderOpenPrice() + (stopLoss * myPoint); }else { sl = OrderStopLoss(); } if (OrderTakeProfit() != tp || OrderStopLoss() != sl) { if (OrderModify(OrderTicket(), OrderOpenPrice(), sl, tp, 0, clrRed)) { Print("订单修改成功"); } } } }//结束魔术编号和交易对的判断 }
如需获取更多教育和分享内容,欢迎加入我们的 Telegram 群组 t.me/codeMQL
如果您正在寻找支持您交易的应用程序,请在应用商店下载我们的 SignalForex 应用。
https://play.google.com/store/apps/details?id=com.autobotfx.signalforex