找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
首页论坛EAHub 外汇论坛
查看: 12|回复: 0

代码未下单,求帮助

[复制链接]

4万

主题

54

回帖

4万

积分

管理员

积分
45954
发表于 2026-8-26 15:43:00 | 显示全部楼层 |阅读模式
//+------------------------------------------------------------------+

//|                                                     裸K交易系统.mq5 |

//|                                      基于裸K文档的策略实现           |

//+------------------------------------------------------------------+

#property copyright "Your Name"

#property version   "1.00"

#property strict


//--- 输入参数

input int      N = 10;               // 箱体计算周期

input double   PointDistance = 3;    // 加仓间隔点数

input double   BidOffset = 5;        // Bid价偏移点数

input int      MaxOrders = 5;        // 最大加仓次数

input bool     UseEarlySession = false; // 是否启用早盘交易

input int      EarlySessionStart = 3; // 早盘开始时间(本地时间)

input int      EarlySessionEnd = 9;  // 早盘结束时间(本地时间)

input double   StopLossPoints = 50;  // 止损点数

input bool     UseCompound = false;  // 是否启用复利

input double   RiskPercent = 2;      // 风险百分比

input double   Lots = 0.01;          // 固定手数

input int      Slippage = 3;         // 滑点


//--- 全局变量

double g_Bid, g_Ask;                 // 当前买卖价格


//--- 函数声明

bool CheckBuyCondition(bool isEarlySession);

bool CheckAddBuyCondition();

bool CheckSellCondition(bool isEarlySession);

bool CheckAddSellCondition();

bool CheckCloseBuyCondition();

bool CheckCloseSellCondition();

double GetAdaptiveLow(int startBar, int period);

double GetAdaptiveHigh(int startBar, int period);

bool IsEarlySession();

double CalculateLots(bool isBuy);

double CalculateStopLoss(bool isBuy);

double CalculateTakeProfit(bool isBuy);

bool OpenBuyOrder();

bool OpenSellOrder();

bool CloseBuyOrders();

bool CloseSellOrders();

void UpdateStopLossTakeProfit();

int CountOrders(int orderType);

bool IsTradingAllowed();  // 添加交易允许检查函数声明


// 处理函数声明

void ProcessBuyOrders(bool isEarlySession);

void ProcessSellOrders(bool isEarlySession);

void ProcessCloseOrders();


//+------------------------------------------------------------------+

//| 专家初始化函数                                                   |

//+------------------------------------------------------------------+

int OnInit()

{

    // 初始化代码

    return(INIT_SUCCEEDED);

}


//+------------------------------------------------------------------+

//| 专家去初始化函数                                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

{

    // 清理代码

}


//+------------------------------------------------------------------+

//| 检查交易是否允许                                                 |

//+------------------------------------------------------------------+

bool IsTradingAllowed()

{

    // 检查交易是否被允许

    if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))

    {

        Print("交易未允许: 终端交易被禁止");

        return false;

    }


    // 检查账户是否允许交易

    if(!AccountInfoInteger(ACCOUNT_TRADE_ALLOWED) || !AccountInfoInteger(ACCOUNT_TRADE_EXPERT))

    {

        Print("交易未允许: 账户交易被禁止");

        return false;

    }


    // 检查交易品种是否允许交易

    if(SymbolInfoInteger(_Symbol, SYMBOL_TRADE_MODE) != SYMBOL_TRADE_MODE_FULL)

    {

        Print("交易未允许: 交易品种不允许交易");

        return false;

    }


    return true;

}


//+------------------------------------------------------------------+

//| 专家订单检查函数                                                 |

//+------------------------------------------------------------------+

void OnTick()

{

    // 获取当前价格

    g_Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

    g_Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);


    // 检查是否允许交易

    if(!IsTradingAllowed()) return;


    // 检查早盘开关

    bool isEarlySession = IsEarlySession();


    // 处理多单逻辑

    ProcessBuyOrders(isEarlySession);


    // 处理空单逻辑

    ProcessSellOrders(isEarlySession);


    // 处理平仓逻辑

    ProcessCloseOrders();


    // 更新止损止盈

    UpdateStopLossTakeProfit();

}


//+------------------------------------------------------------------+

//| 处理多单开仓                                                     |

//+------------------------------------------------------------------+

void ProcessBuyOrders(bool isEarlySession)

{

    int buyCount = CountOrders(POSITION_TYPE_BUY);


    if(buyCount == 0)

    {

        // 首单开仓条件

        if(CheckBuyCondition(isEarlySession))

        {

            OpenBuyOrder();

        }

    }

    else if(buyCount < MaxOrders)

    {

        // 加仓条件检查

        if(CheckAddBuyCondition())

        {

            OpenBuyOrder();

        }

    }

}


//+------------------------------------------------------------------+

//| 处理空单开仓                                                     |

//+------------------------------------------------------------------+

void ProcessSellOrders(bool isEarlySession)

{

    int sellCount = CountOrders(POSITION_TYPE_SELL);


    if(sellCount == 0)

    {

        // 首单开仓条件

        if(CheckSellCondition(isEarlySession))

        {

            OpenSellOrder();

        }

    }

    else if(sellCount < MaxOrders)

    {

        // 加仓条件检查

        if(CheckAddSellCondition())

        {

            OpenSellOrder();

        }

    }

}


//+------------------------------------------------------------------+

//| 处理平仓逻辑                                                     |

//+------------------------------------------------------------------+

void ProcessCloseOrders()

{

    // 检查平多条件

    if(CheckCloseBuyCondition())

    {

        CloseBuyOrders();

    }


    // 检查平空条件

    if(CheckCloseSellCondition())

    {

        CloseSellOrders();

    }

}


//+------------------------------------------------------------------+

//| 多单开仓条件检查                                                 |

//+------------------------------------------------------------------+

bool CheckBuyCondition(bool isEarlySession)

{

    // 条件1:上根K线收盘价高于自适应根K线最低价间距

    if(!isEarlySession)

    {

        double adaptiveLow = GetAdaptiveLow(1, N);

        if(iClose(_Symbol, PERIOD_CURRENT, 1) <= adaptiveLow)

            return false;

    }


    // 条件2:上根K线收盘价下破前根K线最低价

    double prevLow = iLow(_Symbol, PERIOD_CURRENT, 2);

    if(iClose(_Symbol, PERIOD_CURRENT, 1) >= prevLow)

        return false;


    // 条件3:价格区间位置判断

    double highest = iHigh(_Symbol, PERIOD_CURRENT, iHighest(_Symbol, PERIOD_CURRENT, MODE_HIGH, N, 1));

    double lowest = iLow(_Symbol, PERIOD_CURRENT, iLowest(_Symbol, PERIOD_CURRENT, MODE_LOW, N, 1));

    double range = highest - lowest;

    double closePrice = iClose(_Symbol, PERIOD_CURRENT, 2);

    double position = (closePrice - highest) / range * 100; // 转换为百分比位置


    if(position > -90) // 根据文档示例调整

        return false;


    // 条件4:Bid价格小于上根K线收盘价+5点

    double lastClose = iClose(_Symbol, PERIOD_CURRENT, 1);

    if(g_Bid >= lastClose + BidOffset * _Point)

        return false;


    return true;

}


//+------------------------------------------------------------------+

//| 加仓多单条件检查                                                 |

//+------------------------------------------------------------------+

bool CheckAddBuyCondition()

{

    // 这里需要实现加仓条件

    // 条件:前一个多单开仓价下方3个点间隔

    // 条件:上根K线的收盘价高于特定位置

    // 条件:Bid价格小于上根K线收盘价+5个点

    // 条件:只在K线开盘的前10秒开单


    // 当前只返回false,需要根据文档实现完整逻辑

    return false;

}


//+------------------------------------------------------------------+

//| 空单开仓条件检查                                                 |

//+------------------------------------------------------------------+

bool CheckSellCondition(bool isEarlySession)

{

    // 条件1:上根K线收盘价低于自适应根K线最高价间距

    if(!isEarlySession)

    {

        double adaptiveHigh = GetAdaptiveHigh(1, N);

        if(iClose(_Symbol, PERIOD_CURRENT, 1) >= adaptiveHigh)

            return false;

    }


    // 条件2:上根K线收盘价上破前根K线最高价

    double prevHigh = iHigh(_Symbol, PERIOD_CURRENT, 2);

    if(iClose(_Symbol, PERIOD_CURRENT, 1) <= prevHigh)

        return false;


    // 条件3:价格区间位置判断

    double highest = iHigh(_Symbol, PERIOD_CURRENT, iHighest(_Symbol, PERIOD_CURRENT, MODE_HIGH, N, 1));

    double lowest = iLow(_Symbol, PERIOD_CURRENT, iLowest(_Symbol, PERIOD_CURRENT, MODE_LOW, N, 1));

    double range = highest - lowest;

    double closePrice = iClose(_Symbol, PERIOD_CURRENT, 2);

    double position = (closePrice - highest) / range * 100; // 转换为百分比位置


    if(position < -10) // 根据文档示例调整

        return false;


    // 条件4:Bid价格大于上根K线收盘价-5点

    double lastClose = iClose(_Symbol, PERIOD_CURRENT, 1);

    if(g_Bid <= lastClose - BidOffset * _Point)

        return false;


    return true;

}


//+------------------------------------------------------------------+

//| 加仓空单条件检查                                                 |

//+------------------------------------------------------------------+

bool CheckAddSellCondition()

{

    // 这里需要实现加仓条件

    // 条件:前一个空单开仓价上方3个点间隔

    // 条件:上根K线的收盘价低于特定位置

    // 条件:Bid价格大于上根K线收盘价-5个点

    // 条件:只在K线开盘的前10秒开单


    // 当前只返回false,需要根据文档实现完整逻辑

    return false;

}


//+------------------------------------------------------------------+

//| 平多条件检查                                                     |

//+------------------------------------------------------------------+

bool CheckCloseBuyCondition()

{

    // 这里需要实现平多条件

    // 条件1:前根K线收盘价上破它的前面N根K线的最高价

    // 条件2:价格位置判断

    // 条件3:多单总体盈利


    // 当前只返回false,需要根据文档实现完整逻辑

    return false;

}


//+------------------------------------------------------------------+

//| 平空条件检查                                                     |

//+------------------------------------------------------------------+

bool CheckCloseSellCondition()

{

    // 这里需要实现平空条件

    // 条件1:前根K线收盘价下破它的前面N根K线的最低价

    // 条件2:价格位置判断

    // 条件3:空单总体盈利


    // 当前只返回false,需要根据文档实现完整逻辑

    return false;

}


//+------------------------------------------------------------------+

//| 获取自适应最低价                                                 |

//+------------------------------------------------------------------+

double GetAdaptiveLow(int startBar, int period)

{

    // 这里实现自适应逻辑,可能需要根据波动率调整period

    double lowest = 1000000; // 使用一个大数作为初始值

    for(int i = startBar; i < startBar + period; i++)

    {

        lowest = MathMin(lowest, iLow(_Symbol, PERIOD_CURRENT, i));

    }

    return lowest;

}


//+------------------------------------------------------------------+

//| 获取自适应最高价                                                 |

//+------------------------------------------------------------------+

double GetAdaptiveHigh(int startBar, int period)

{

    // 这里实现自适应逻辑,可能需要根据波动率调整period

    double highest = 0; // 使用0作为初始值

    for(int i = startBar; i < startBar + period; i++)

    {

        highest = MathMax(highest, iHigh(_Symbol, PERIOD_CURRENT, i));

    }

    return highest;

}


//+------------------------------------------------------------------+

//| 判断是否在早盘时间                                               |

//+------------------------------------------------------------------+

bool IsEarlySession()

{

    if(!UseEarlySession) return false;


    MqlDateTime dt;

    TimeCurrent(dt);

    int hour = dt.hour;


    // 根据本地时间判断

    if(EarlySessionStart < EarlySessionEnd)

    {

        return (hour >= EarlySessionStart && hour < EarlySessionEnd);

    }

    else

    {

        return (hour >= EarlySessionStart || hour < EarlySessionEnd);

    }

}


//+------------------------------------------------------------------+

//| 计算开仓手数                                                     |

//+------------------------------------------------------------------+

double CalculateLots(bool isBuy)

{

    double lotSize = Lots;


    if(UseCompound)

    {

        // 复利计算:手数 = 净值 * 风险百分比 / 100万

        lotSize = AccountInfoDouble(ACCOUNT_EQUITY) * RiskPercent / 1000000;

    }


    // 手数限制

    lotSize = MathMax(lotSize, 0.01);

    lotSize = MathMin(lotSize, 50.0);


    return lotSize;

}


//+------------------------------------------------------------------+

//| 开多单                                                           |

//+------------------------------------------------------------------+

bool OpenBuyOrder()

{

    MqlTradeRequest request = {};

    MqlTradeResult result = {};


    request.action = TRADE_ACTION_DEAL;

    request.symbol = _Symbol;

    request.volume = CalculateLots(true);

    request.type = ORDER_TYPE_BUY;

    request.price = g_Ask;

    request.sl = CalculateStopLoss(true);

    request.tp = CalculateTakeProfit(true);

    request.deviation = Slippage;

    request.type_filling = ORDER_FILLING_FOK;


    // 发送订单并检查结果

    bool success = OrderSend(request, result);


    if(!success)

    {

        Print("开多单失败,错误代码: ", result.retcode);

    }


    return success;

}


//+------------------------------------------------------------------+

//| 开空单                                                           |

//+------------------------------------------------------------------+

bool OpenSellOrder()

{

    MqlTradeRequest request = {};

    MqlTradeResult result = {};


    request.action = TRADE_ACTION_DEAL;

    request.symbol = _Symbol;

    request.volume = CalculateLots(false);

    request.type = ORDER_TYPE_SELL;

    request.price = g_Bid;

    request.sl = CalculateStopLoss(false);

    request.tp = CalculateTakeProfit(false);

    request.deviation = Slippage;

    request.type_filling = ORDER_FILLING_FOK;


    // 发送订单并检查结果

    bool success = OrderSend(request, result);


    if(!success)

    {

        Print("开空单失败,错误代码: ", result.retcode);

    }


    return success;

}


//+------------------------------------------------------------------+

//| 平掉所有多单                                                     |

//+------------------------------------------------------------------+

bool CloseBuyOrders()

{

    bool allClosed = true;


    for(int i = PositionsTotal()-1; i >= 0; i--)

    {

        if(PositionGetSymbol(i) == _Symbol &&

           PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)

        {

            MqlTradeRequest request = {};

            MqlTradeResult result = {};


            request.action = TRADE_ACTION_DEAL;

            request.symbol = _Symbol;

            request.volume = PositionGetDouble(POSITION_VOLUME);

            request.type = ORDER_TYPE_SELL;

            request.position = PositionGetInteger(POSITION_TICKET);

            request.price = g_Bid;

            request.deviation = Slippage;


            // 发送订单并检查结果

            bool success = OrderSend(request, result);


            if(!success)

            {

                Print("平多单失败,错误代码: ", result.retcode);

                allClosed = false;

            }

        }

    }


    return allClosed;

}


//+------------------------------------------------------------------+

//| 平掉所有空单                                                     |

//+------------------------------------------------------------------+

bool CloseSellOrders()

{

    bool allClosed = true;


    for(int i = PositionsTotal()-1; i >= 0; i--)

    {

        if(PositionGetSymbol(i) == _Symbol &&

           PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)

        {

            MqlTradeRequest request = {};

            MqlTradeResult result = {};


            request.action = TRADE_ACTION_DEAL;

            request.symbol = _Symbol;

            request.volume = PositionGetDouble(POSITION_VOLUME);

            request.type = ORDER_TYPE_BUY;

            request.position = PositionGetInteger(POSITION_TICKET);

            request.price = g_Ask;

            request.deviation = Slippage;


            // 发送订单并检查结果

            bool success = OrderSend(request, result);


            if(!success)

            {

                Print("平空单失败,错误代码: ", result.retcode);

                allClosed = false;

            }

        }

    }


    return allClosed;

}


//+------------------------------------------------------------------+

//| 计算止损价                                                       |

//+------------------------------------------------------------------+

double CalculateStopLoss(bool isBuy)

{

    if(UseEarlySession)

    {

        // 早盘模式:固定点数止损

        return (isBuy ?

                g_Ask - StopLossPoints * _Point :

                g_Bid + StopLossPoints * _Point);

    }

    else

    {

        // 非早盘:使用前N根K线的最低价/最高价

        if(isBuy)

            return iLow(_Symbol, PERIOD_CURRENT, iLowest(_Symbol, PERIOD_CURRENT, MODE_LOW, N, 1));

        else

            return iHigh(_Symbol, PERIOD_CURRENT, iHighest(_Symbol, PERIOD_CURRENT, MODE_HIGH, N, 1));

    }

}


//+------------------------------------------------------------------+

//| 计算止盈价                                                       |

//+------------------------------------------------------------------+

double CalculateTakeProfit(bool isBuy)

{

    double highest = iHigh(_Symbol, PERIOD_CURRENT, iHighest(_Symbol, PERIOD_CURRENT, MODE_HIGH, N, 1));

    double lowest = iLow(_Symbol, PERIOD_CURRENT, iLowest(_Symbol, PERIOD_CURRENT, MODE_LOW, N, 1));

    double center = (highest + lowest) / 2;

    double range = highest - lowest;


    if(isBuy)

        return center + range;  // 多单止盈:中心点+间距

    else

        return center - range;  // 空单止盈:中心点-间距

}


//+------------------------------------------------------------------+

//| 更新止损止盈                                                     |

//+------------------------------------------------------------------+

void UpdateStopLossTakeProfit()

{

    // 这里实现动态更新止损止盈的逻辑

    // 根据文档,可能需要根据价格变化调整止损止盈

}


//+------------------------------------------------------------------+

//| 统计当前持仓数量                                                 |

//+------------------------------------------------------------------+

int CountOrders(int orderType)

{

    int count = 0;

    for(int i = 0; i < PositionsTotal(); i++)

    {

        if(PositionGetSymbol(i) == _Symbol &&

           PositionGetInteger(POSITION_TYPE) == orderType)

        {

            count++;

        }

    }

    return count;

}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|EAHub外汇论坛

GMT+8, 2026-10-11 00:14 , Processed in 0.114195 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表