随着智能化技术的发展,自动化交易渐渐成为投资者的新选择。因此,编写程序化交易EA(Expert Advisor)已经成为期货、外汇等交易领域中的必修课。MQL4是目前最为广泛使用的一种程序化交易语言,它有着丰富的特性和强大的功能,可以帮助投资者在交易中实现自动化操作。本文将会通过讲解几个实例,带领读者深入了解MQL4的编程思想和操作方法,为读者在编写EA程序方面提供实用的建议。
一、止损点位追踪策略
止损点是股票交易不可或缺的一个环节,它可以帮助投资者保持资金安全和控制风险。止损点位追踪策略是一种常见的风险控制策略,它可以帮助投资者在价格波动剧烈时,快速调整止损点位,避免巨额亏损。
以下是一个使用MQL4编写的止损点追踪程序的示例代码:
“`
bool ChangeStopLoss(double dPrice, double dSlippage)
{
double dOrderStopLoss = OrderStopLoss();
double dNewStopLoss = NormalizeDouble(dPrice – dSlippage * Point, Digits);
if(dOrderStopLoss == dNewStopLoss) return(false);
if(OrderModify(OrderTicket(), OrderOpenPrice(), dNewStopLoss, OrderTakeProfit(), 0, Green))
{
Print(“Stop Loss Changed from “, dOrderStopLoss, ” to “, dNewStopLoss);
return(true);
}
return(false);
}
double GetAveragePrice(int iMagicNumber)
{
double dTotalAmount = 0.0;
double dTotalSum = 0.0;
int iTotalOrders = OrdersTotal();
for(int i=0; i<iTotalOrders; i++)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if(OrderMagicNumber() != iMagicNumber) continue;
if(OrderType() == OP_BUY)
{
dTotalAmount += OrderLots();
dTotalSum += OrderLots() * OrderOpenPrice();
}
else if(OrderType() == OP_SELL)
{
dTotalAmount -= OrderLots();
dTotalSum -= OrderLots() * OrderOpenPrice();
}
}
return(dTotalSum / dTotalAmount);
}
void OnTick()
{
double dPrice = MarketInfo(Symbol(), MODE_BID);
double dSlippage = 3.0;
double dAveragePrice = GetAveragePrice(1001);
double dNewStopLoss = NormalizeDouble(dAveragePrice – dSlippage * Point, Digits);
if(ChangeStopLoss(dNewStopLoss, dSlippage))
{
SendNotification(“Stop Loss Changed to “, DoubleToString(dNewStopLoss, Digits));
}
}
“`
以上代码实现了一个简单的止损点位追踪程序,在该程序中,通过计算所有购买和出售订单的平均价格来确定新的止损点位。当程序检测到当前价格低于新的止损点位时,程序会自动修改订单中的止损点位。此外,程序还设置了一个滑点值(dSlippage),用于保证在操作时不会影响到市价的变化。
二、交易信号识别策略
交易信号识别是指使用技术分析工具和技术指标,来识别并预测股票价格走势和买入卖出信号。在MQL4编写中,可以使用iMA()等内置函数及其它自定义使用特定算法的技术指标函数来实现信号识别。
以下是一个使用MQL4编写的交易信号识别程序的示例代码:
“`
double GetIndicatorValue(string sIndicatorName, int iTimeFrame, int iPeriod, int iShift)
{
double value = -1;
int handle = iCustom(NULL, iTimeFrame, sIndicatorName, iPeriod, 0, iShift);
if(handle != INVALID_HANDLE)
{
value = NormalizeDouble(iCustom(NULL, iTimeFrame, sIndicatorName, iPeriod, 0, iShift),Digits);
}
return value;
}
void OnTick()
{
double dCurrentPrice = MarketInfo(Symbol(),MODE_BID);
double dSMA50 = GetIndicatorValue(“Moving Average”, PERIOD_D1, 50, 0);
double dSMA20 = GetIndicatorValue(“Moving Average”, PERIOD_D1, 20, 0);
if(dSMA20 > dSMA50)
{
// generate buy signal
SendNotification(“Buy signal detected!”);
}
else if(dSMA20 < dSMA50)
{
// generate sell signal
SendNotification(“Sell signal detected!”);
}
}
“`
以上代码实现了通过计算短期和长期移动平均线的方法来识别买卖信号的程序。当短期移动平均线(20天)上穿长期移动平均线(50天)时,程序会生成一个买入信号;当两条移动平均线相交时,程序则会生成一个卖出信号。
三、风险管理策略
在编写EA程序时,风险管理是至关重要的一个方面。正确的风险管理策略可以大大降低投资者的损失,并增加交易的盈利性。风险管理策略中,最常用的就是资金管理和仓位管理。
以下是一个使用MQL4编写的风险管理策略的示例代码:
“`
// 资金最大风险百分比
double g_dMaxRisk = 0.01;
double GetLots(double dTotalMoney, double dPrice, double dStopLoss)
{
double dRiskPerUnit = dPrice – dStopLoss;
double dLots = (dTotalMoney * g_dMaxRisk) / ((dRiskPerUnit * MarketInfo(Symbol(), MODE_TICKVALUE)) * Point);
dLots = NormalizeDouble(dLots, 2);
return(dLots);
}
void Buy(double dLots, double dPrice, double dStopLoss, double dTakeProfit)
{
if(OrderSend(Symbol(), OP_BUY, dLots, dPrice, 3, dStopLoss, dTakeProfit, “Buy Order”, 1001, 0, Green))
{
SendNotification(“Buy Order executed!”);
}
}
void Sell(double dLots, double dPrice, double dStopLoss, double dTakeProfit)
{
if(OrderSend(Symbol(), OP_SELL, dLots, dPrice, 3, dStopLoss, dTakeProfit, “Sell Order”, 1002, 0, Red))
{
SendNotification(“Sell Order executed!”);
}
}
void OnTick()
{
double dCurrentPrice = MarketInfo(Symbol(),MODE_BID);
double dBollingerBandUpper = iBands(NULL, 0, 20, 2.0, 0, PRICE_CLOSE, MODE_UPPER, 0);
double dBollingerBandLower = iBands(NULL, 0, 20, 2.0, 0, PRICE_CLOSE, MODE_LOWER, 0);
double dStopLoss = dBollingerBandUpper;
double dTakeProfit = dBollingerBandLower;
double dTotalMoney = AccountFreeMargin();
double dLots = GetLots(dTotalMoney, dCurrentPrice, dStopLoss);
if(!OrderSelect(0, SELECT_BY_POS))
{
// no open order
if(dCurrentPrice > dBollingerBandUpper)
{
// generate sell signal
Sell(dLots,dCurrentPrice,dStopLoss,dTakeProfit);
}
else if(dCurrentPrice < dBollingerBandLower)
{
// generate buy signal
Buy(dLots,dCurrentPrice,dStopLoss,dTakeProfit);
}
}
else
{
// has open order
if(OrderType() == OP_BUY)
{
if(dCurrentPrice < dBollingerBandLower)
{
// close buy order
OrderClose(OrderTicket(), OrderLots(), dCurrentPrice, 0, Red);
}
}
else if(OrderType() == OP_SELL)
{
if(dCurrentPrice > dBollingerBandUpper)
{
// close sell order
OrderClose(OrderTicket(), Order