设为首页 收藏本站 切换语言 切换语言

代码未下单,求帮助

| 发表于 昨天 11:53 | 显示全部楼层 |复制链接
//+------------------------------------------------------------------+
//|                                                     裸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;
}

举报

评论 使用道具

发新帖
EA交易
您需要登录后才可以评论 登录 | 立即注册

 简体中文国旗 简体中文
 繁體中文国旗 繁體中文
 English国旗 English(英语)
 日本語国旗 日本語(日语)
 Deutsch国旗 Deutsch(德语)
 Русский язык国旗 Русский язык(俄语)
 بالعربية国旗 بالعربية(阿拉伯语)
 Türkçe国旗 Türkçe(土耳其语)
 Português国旗 Português(葡萄牙语)
 ภาษาไทย国旗 ภาษาไทย(泰国语)
 한어国旗 한어(朝鲜语/韩语)
 Français国旗 Français(法语)
翻译