整合所有功能
现在,我们将展示最终使用本章创建的各种辅助函数重构后的 MA 交叉 EA 的完整代码结构。我们假设所有这些函数(如手数计算、验证、开仓、平仓、SL/TP 计算、调整、添加 SL/TP 等)都定义在 IncludeExample.mqh
文件中。
// --- 1. 预处理器指令 ---
#property copyright "tudao"
#include <IncludeExample.mqh> // 包含所有自定义辅助函数
// --- 2. 输入参数 ---
extern bool UseDynamicLotSize = true;
extern double EquityPercent = 2.0;
extern double FixedLotSize = 0.1;
extern double StopLossPips = 50; // SL/TP 点数应命名清晰
extern double TakeProfitPips = 100;
extern int Slippage = 5; // 滑点 (pips)
extern int MagicNumber = 123;
extern int FastMAPeriod = 10;
extern int SlowMAPeriod = 20;
// --- 3. 全局变量 ---
int g_BuyTicket = 0; // 当前买单号
int g_SellTicket = 0; // 当前卖单号
double g_onePipValue = 0.0; // 1 pip 价值
int g_slippagePoints = 0; // 滑点 points
// --- 4. 初始化函数 ---
int OnInit()
{
g_onePipValue = PipPoint(Symbol()); // 调用 IncludeExample.mqh 中的函数
g_slippagePoints = GetSlippage(Symbol(), Slippage); // 调用 IncludeExample.mqh 中的函数
return(INIT_SUCCEEDED);
}
// --- 5. 核心逻辑函数 ---
void OnTick()
{
// a. 计算指标
double FastMA = iMA(NULL, 0, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
double SlowMA = iMA(NULL, 0, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
// b. 计算并验证手数
// 注意: 此处 StopLossPips 使用外部输入值,实际应根据信号动态决定
double lotSize = CalcLotSize(UseDynamicLotSize, EquityPercent, StopLossPips, FixedLotSize);
lotSize = VerifyLotSize(lotSize); // 验证并规范化手数
if (lotSize <= 0) return(0); // 手数无效则不交易
// c. 买入逻辑 (金叉且无买单)
if (FastMA > SlowMA && g_BuyTicket == 0)
{
// i. 关闭反向卖单
bool closedOK = CloseOppositeOrder(Symbol(), g_SellTicket, g_slippagePoints); // 调用平仓函数
if (closedOK) g_SellTicket = 0; // 成功关闭或无需关闭才清零
// ii. 开立新买单 (仅当反向单处理完毕)
if (g_SellTicket == 0)
{
g_BuyTicket = OpenBuyOrder(Symbol(), lotSize, g_slippagePoints, MagicNumber); // 调用开买单函数
// iii. 如果开单成功且需要 SL/TP,则添加
if (g_BuyTicket > 0 && (StopLossPips > 0 || TakeProfitPips > 0))
{
// 封装好的添加 SL/TP 逻辑
AddAndVerifySLTP(g_BuyTicket, StopLossPips, TakeProfitPips);
/*
// 或者展开逻辑:
if (OrderSelect(g_BuyTicket, SELECT_BY_TICKET)) {
double openPrice = OrderOpenPrice();
double slPrice = CalcBuyStopLoss(Symbol(), StopLossPips, openPrice);
double tpPrice = CalcBuyTakeProfit(Symbol(), TakeProfitPips, openPrice);
slPrice = AdjustBelowStopLevel(Symbol(), slPrice, 5, openPrice); // 调整
tpPrice = AdjustAboveStopLevel(Symbol(), tpPrice, 5, openPrice); // 调整
AddStopProfit(g_BuyTicket, slPrice, tpPrice); // 添加
}
*/
}
} // end if g_SellTicket == 0
} // end if 买入条件
// d. 卖出逻辑 (与买入逻辑对称)
if (FastMA < SlowMA && g_SellTicket == 0) // 死叉且无卖单
{
// i. 关闭反向买单
bool closedOK = CloseOppositeOrder(Symbol(), g_BuyTicket, g_slippagePoints); // 调用平仓函数
if (closedOK) g_BuyTicket = 0; // 成功关闭或无需关闭才清零
// ii. 开立新卖单 (仅当反向单处理完毕)
if (g_BuyTicket == 0)
{
g_SellTicket = OpenSellOrder(Symbol(), lotSize, g_slippagePoints, MagicNumber); // 调用开卖单函数
// iii. 如果开单成功且需要 SL/TP,则添加
if (g_SellTicket > 0 && (StopLossPips > 0 || TakeProfitPips > 0))
{
// 封装好的添加 SL/TP 逻辑
AddAndVerifySLTP(g_SellTicket, StopLossPips, TakeProfitPips);
/*
// 或者展开逻辑:
if (OrderSelect(g_SellTicket, SELECT_BY_TICKET)) {
double openPrice = OrderOpenPrice();
double slPrice = CalcSellStopLoss(Symbol(), StopLossPips, openPrice);
double tpPrice = CalcSellTakeProfit(Symbol(), TakeProfitPips, openPrice);
slPrice = AdjustAboveStopLevel(Symbol(), slPrice, 5, openPrice); // 调整
tpPrice = AdjustBelowStopLevel(Symbol(), tpPrice, 5, openPrice); // 调整
AddStopProfit(g_SellTicket, slPrice, tpPrice); // 添加
}
*/
}
} // end if g_BuyTicket == 0
} // end if 卖出条件
return;
}
代码解释:
- 包含文件: 代码开头通过
#include <IncludeExample.mqh>
引入了包含所有自定义辅助函数的文件。 - 手数处理: 在函数开始处,调用
CalcLotSize()
和VerifyLotSize()
函数来计算并验证最终要使用的手数lotSize
。 - 买入/卖出逻辑块:
- 关闭反向订单: 使用封装好的
CloseBuyOrder()
和CloseSellOrder()
函数。注意修正后的逻辑: 只有在确认平仓成功(或订单本就不存在/已关闭)后,才将对应的全局票号变量(g_SellTicket
或g_BuyTicket
)置零。 - 开立新订单: 使用封装好的
OpenBuyOrder()
或OpenSellOrder()
函数(这些函数内部已包含交易上下文检查和基本错误处理,且发送时不带 SL/TP)。 - 添加 SL/TP: 在新订单成功开立后 (
g_BuyTicket > 0
或g_SellTicket > 0
) 且用户设置了 SL/TP 点数 (StopLossPips > 0 || TakeProfitPips > 0
) 的情况下,执行以下系列调用:OrderSelect()
选中新订单。OrderOpenPrice()
获取开仓价。- 调用
CalcBuyStopLoss()
/CalcSellStopLoss()
计算目标止损价。 - 调用
CalcBuyTakeProfit()
/CalcSellTakeProfit()
计算目标止盈价。 - 调用
AdjustBelowStopLevel()
/AdjustAboveStopLevel()
对计算出的 SL/TP 价格进行停止级别验证和自动调整(示例中使用了 5 pips 的缓冲)。 - 最后调用
AddStopProfit()
函数将最终验证和调整过的 SL/TP 价格应用到订单上。
- 关闭反向订单: 使用封装好的
关于函数使用的章节内容结束,给大家展示了如何通过函数将复杂的交易逻辑模块化,从而构建出结构清晰、功能健壮且易于维护的智能交易系统。