在今天的文章中,我们将一起创建一个基于移动平均线交叉策略的EA(专家顾问)。首先,我们需要定义输入参数。
//--- 输入参数 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 pesan =StringFormat("交易手数低于允许的最低值 %.2f",min_volume); Alert (pesan); return(INIT_PARAMETERS_INCORRECT); } myPoint = GetPipPoint(Symbol()); mySlippage = GetSlippage(Symbol(),Slippage); return(INIT_SUCCEEDED); }
当市场价格发生变动时(即tick),将调用 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群组。
如果你在寻找可以支持你交易的应用程序,欢迎下载我们的SignalForex应用程序,支持安卓系统。