//+------------------------------------------------------------------+
//| FixedFiboDayRangeStrategy_v3.mq5 |
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.01"
#property description "修复版:基于斐波那契扩展的交易策略"
#property description "已解决所有编译错误和逻辑问题"
// 输入参数
input double LotSize = 0.1; // 固定交易手数
input int MagicNumber = 2023; // EA唯一标识
input int StopLossPips = 50; // 止损点数
input color FibColor = clrDodgerBlue; // 斐波那契线颜色
input string FibLevels = "0,23.6,38.2,50,61.8,100,138.2,161.8"; // 斐波那契水平
input int CloseHour = 22; // 平仓时间(小时)
input int CloseMinute = 0; // 平仓时间(分钟)
// 全局变量
double prevHigh, prevLow;
double fibLevelsArray[];
int fibLevelsCount;
datetime lastTradeDay;
string objPrefix = "Fibo_";
//+------------------------------------------------------------------+
//| 前置声明 |
//+------------------------------------------------------------------+
void CheckNewTradingDay();
void LoadPreviousDayLevels();
void DrawFibonacciLevels();
bool HasOpenPositions();
void CheckEntrySignals();
void CheckCloseConditions();
void CloseAllPositions();
bool OpenTrade(ENUM_ORDER_TYPE orderType, double sl, double tp);
//+------------------------------------------------------------------+
//| EA初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
// 修复1: 正确解析斐波那契水平
string levelsArray[];
fibLevelsCount = StringSplit(FibLevels, ',', levelsArray);
ArrayResize(fibLevelsArray, fibLevelsCount);
for(int i = 0; i < fibLevelsCount; i++) {
fibLevelsArray[i] = StringToDouble(levelsArray[i]);
}
// 初始化交易日
lastTradeDay = 0;
// 获取前一日高低点
LoadPreviousDayLevels();
// 绘制斐波那契水平线
DrawFibonacciLevels();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| EA终止函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 删除所有斐波那契对象
ObjectsDeleteAll(0, objPrefix);
Comment("");
}
//+------------------------------------------------------------------+
//| 主执行函数 |
//+------------------------------------------------------------------+
void OnTick()
{
// 检查新交易日
CheckNewTradingDay();
// 检查平仓条件
CheckCloseConditions();
// 检查开仓信号
if(!HasOpenPositions())
{
CheckEntrySignals();
}
}
//+------------------------------------------------------------------+
//| 修复2: 获取前一日高低点 |
//+------------------------------------------------------------------+
void LoadPreviousDayLevels()
{
datetime endTime = iTime(_Symbol, PERIOD_D1, 1);
datetime startTime = endTime - PeriodSeconds(PERIOD_D1);
MqlRates rates[];
int copied = CopyRates(_Symbol, PERIOD_D1, startTime, endTime, rates);
if(copied > 0) {
prevHigh = rates[0].high;
prevLow = rates[0].low;
Comment("前一日高低点: High=", prevHigh, " Low=", prevLow);
}
else {
Print("加载前一日数据失败! 错误: ", GetLastError());
}
}
//+------------------------------------------------------------------+
//| 修复3: 检查新交易日函数 |
//+------------------------------------------------------------------+
void CheckNewTradingDay()
{
MqlDateTime currentTime;
TimeCurrent(currentTime);
MqlDateTime lastTradeTime;
TimeToStruct(lastTradeDay, lastTradeTime);
// 修复9: 正确使用TimeDay函数
if(currentTime.day != lastTradeTime.day)
{
LoadPreviousDayLevels();
DrawFibonacciLevels();
lastTradeDay = TimeCurrent();
}
}
//+------------------------------------------------------------------+
//| 修复4: 绘制斐波那契水平线 |
//+------------------------------------------------------------------+
void DrawFibonacciLevels()
{
// 删除旧对象
ObjectsDeleteAll(0, objPrefix);
double range = prevHigh - prevLow;
// 绘制斐波那契水平线
for(int i = 0; i < fibLevelsCount; i++)
{
double levelValue = fibLevelsArray[i];
double priceLevel = prevLow + (range * levelValue / 100.0);
string objName = objPrefix + "Level_" + DoubleToString(levelValue, 1);
if(!ObjectCreate(0, objName, OBJ_HLINE, 0, 0, priceLevel)) {
Print("创建水平线失败: ", GetLastError());
continue;
}
ObjectSetInteger(0, objName, OBJPROP_COLOR, FibColor);
ObjectSetInteger(0, objName, OBJPROP_STYLE, STYLE_DASHDOT);
ObjectSetInteger(0, objName, OBJPROP_WIDTH, 1);
ObjectSetInteger(0, objName, OBJPROP_BACK, true);
string text = DoubleToString(levelValue, 1) + "%";
ObjectSetString(0, objName, OBJPROP_TEXT, text);
}
}
//+------------------------------------------------------------------+
//| 修复5: 检查开仓信号 |
//+------------------------------------------------------------------+
void CheckEntrySignals()
{
// 修复4: 声明bid和ask变量
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double current = (bid + ask) / 2.0;
double range = prevHigh - prevLow;
double threshold = range * 0.05;
// 计算关键斐波那契水平
double fib50 = prevLow + range * 0.5;
double fib61 = prevLow + range * 0.618;
double fib38 = prevLow + range * 0.382;
MqlRates currentBar[];
CopyRates(_Symbol, PERIOD_CURRENT, 0, 1, currentBar);
// 多头信号
if(current > prevHigh && current < (fib50 + threshold) && current > fib38)
{
if(currentBar[0].close < currentBar[0].open)
{
double sl = MathMin(prevLow, fib38);
double tp = fib61;
OpenTrade(ORDER_TYPE_BUY, sl, tp);
}
}
// 空头信号
else if(current < prevLow && current > (fib50 - threshold) && current < fib61)
{
if(currentBar[0].close > currentBar[0].open)
{
double sl = MathMax(prevHigh, fib61);
double tp = fib38;
OpenTrade(ORDER_TYPE_SELL, sl, tp);
}
}
}
//+------------------------------------------------------------------+
//| 修复6: 开仓函数(解决枚举转换错误) |
//+------------------------------------------------------------------+
bool OpenTrade(ENUM_ORDER_TYPE orderType, double sl, double tp)
{
MqlTradeRequest request;
MqlTradeResult result;
// 修复4: 声明bid和ask变量
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
// 修复3: 正确设置枚举值
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = LotSize;
request.magic = MagicNumber;
request.type = orderType;
request.price = (orderType == ORDER_TYPE_BUY) ? ask : bid;
// 设置止损止盈
if(sl > 0) request.sl = NormalizeDouble(sl, _Digits);
if(tp > 0) request.tp = NormalizeDouble(tp, _Digits);
// 发送交易请求
if(!OrderSend(request, result)) {
Print("开仓失败: ", EnumToString(orderType), " 错误=", GetLastError());
return false;
}
Print("开仓成功: ", EnumToString(orderType), " 价格=", request.price);
return true;
}
//+------------------------------------------------------------------+
//| 修复7: 检查平仓条件 |
//+------------------------------------------------------------------+
void CheckCloseConditions()
{
MqlDateTime now;
TimeCurrent(now);
// 修复8: 正确使用括号表达式
if((now.hour == CloseHour && now.min >= CloseMinute) || (now.hour > CloseHour))
{
CloseAllPositions();
}
}
//+------------------------------------------------------------------+
//| 修复8: 平仓所有持仓 |
//+------------------------------------------------------------------+
void CloseAllPositions()
{
for(int i = PositionsTotal()-1; i >= 0; i--)
{
if(PositionGetTicket(i))
{
ulong ticket = PositionGetInteger(POSITION_TICKET);
if(PositionGetInteger(POSITION_MAGIC) == MagicNumber &&
PositionGetString(POSITION_SYMBOL) == _Symbol)
{
MqlTradeRequest request;
MqlTradeResult result;
// 修复3: 正确设置枚举值
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = PositionGetDouble(POSITION_VOLUME);
request.magic = MagicNumber;
request.type = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ?
ORDER_TYPE_SELL : ORDER_TYPE_BUY;
request.position = ticket;
if(!OrderSend(request, result)) {
Print("平仓失败: 错误=", GetLastError());
}
else {
Print("已平仓: ", PositionGetString(POSITION_SYMBOL));
}
}
}
}
}
//+------------------------------------------------------------------+
//| 检查持仓状态 |
//+------------------------------------------------------------------+
bool HasOpenPositions()
{
for(int i = 0; i < PositionsTotal(); i++)
{
if(PositionGetTicket(i))
{
if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
if(PositionGetInteger(POSITION_MAGIC) == MagicNumber) {
return true;
}
}
}
return false;
}
你编写的这个策略不能交易,修改后将完整代码呈现出来可以直接安装应用
最新发布