该代码实现多空共存的交易策略,并添加了参数总亏损1000美金平仓功能。当亏损超过1000美元时,无论多头还是空头信号,都会自动平仓。

extern int MagicNumber = 92133; // 魔术码
extern double InitialLotSize = 0.5; // 初始手数
extern int Gap = 100; // 间距
extern double AddLotMultiplier = 0.6; // 补仓倍数
extern int MaxAddLotCount = 5; // 补仓次数
extern double ProfitTarget = 0; // 盈利目标(美金)
extern int Slippage = 3; // 滑点值
extern double MaxLoss = -1000; // 最大亏损(美金)

void OnTick()
{
    double latestPrice = MarketInfo(Symbol(), MODE_BID); // 获取最新价格
    int totalOrders = OrdersTotal(); // 获取订单总数

    // 检查当前魔术码是否持仓
    bool hasPosition = false;
    for (int i = 0; i < totalOrders; i++)
    {
        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber)
        {
            hasPosition = true;
            break;
        }
    }

    // 如果没有持仓
    if (!hasPosition)
    {
        double entryPrice = latestPrice;
        double lotSize = InitialLotSize;

        // 根据最新价格加100点挂单一次多单
        double buyStopPrice = entryPrice + Gap;
        int buyStopOrderTicket = OrderSend(Symbol(), OP_BUYSTOP, lotSize, buyStopPrice, 0, 0, 0, 'Buy Stop', MagicNumber, 0, Blue);

        // 根据最新价格减100点挂单一次空单
        double sellStopPrice = entryPrice - Gap;
        int sellStopOrderTicket = OrderSend(Symbol(), OP_SELLSTOP, lotSize, sellStopPrice, 0, 0, 0, 'Sell Stop', MagicNumber, 0, Red);

        // 设置挂单的止损和止盈
        if (buyStopOrderTicket > -1)
        {
            if (!OrderModify(buyStopOrderTicket, OrderOpenPrice(), NormalizeDouble(entryPrice - Gap * 2, Digits), OrderTakeProfit(), 0, Green))
            {
                Print('Failed to modify buy stop order: ', GetLastError());
            }
        }
        if (sellStopOrderTicket > -1)
        {
            if (!OrderModify(sellStopOrderTicket, OrderOpenPrice(), NormalizeDouble(entryPrice + Gap * 2, Digits), OrderTakeProfit(), 0, Green))
            {
                Print('Failed to modify sell stop order: ', GetLastError());
            }
        }
    }
    else // 如果持仓
    {
        double firstOrderProfitTarget = 0;

        for (int j = 0; j < totalOrders; j++)
        {
            if (OrderSelect(j, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber)
            {
                double orderProfit = OrderProfit();

                // 判断当前魔术码下的所有持仓订单
                if (orderProfit >= ProfitTarget || orderProfit <= MaxLoss)
                {
                    if (!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, Red))
                    {
                        Print('Failed to close order: ', GetLastError());
                    }
                }
                else
                {
                    if (j == 0) // 第一单
                    {
                        firstOrderProfitTarget = orderProfit;

                        // 如果持仓多单,最新价小于第一单多单100点时,以初始手数0.5手做空
                        if (OrderType() == OP_BUY && latestPrice < OrderOpenPrice() - Gap)
                        {
                            if (!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, Red))
                            {
                                Print('Failed to close initial buy order: ', GetLastError());
                            }

                            int shortOrderTicket = OrderSend(Symbol(), OP_SELL, InitialLotSize, 0, 0, 0, 0, 'Initial Short', MagicNumber, 0, Red);
                            if (shortOrderTicket < 0)
                            {
                                Print('Failed to open initial short order: ', GetLastError());
                            }
                        }

                        // 如果持仓空单,最新价大于第一单空单100点时,以初始手数0.5手做多
                        if (OrderType() == OP_SELL && latestPrice > OrderOpenPrice() + Gap)
                        {
                            if (!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, Red))
                            {
                                Print('Failed to close initial sell order: ', GetLastError());
                            }

                            int longOrderTicket = OrderSend(Symbol(), OP_BUY, InitialLotSize, 0, 0, 0, 0, 'Initial Long', MagicNumber, 0, Blue);
                            if (longOrderTicket < 0)
                            {
                                Print('Failed to open initial long order: ', GetLastError());
                            }
                        }
                    }
                    else // 非第一单
                    {
                        int addLotCount = MathFloor(orderProfit / Gap); // 补仓次数计数

                        if (OrderType() == OP_BUY) // 多单
                        {
                            for (int k = 1; k <= addLotCount && k <= MaxAddLotCount; k++)
                            {
                                double addLotSize = InitialLotSize * MathPow(AddLotMultiplier, k);
                                double addLotEntryPrice = firstOrderProfitTarget + Gap * k;
                                int buyOrderTicket = OrderSend(Symbol(), OP_BUY, addLotSize, addLotEntryPrice, 0, 0, 0, 'Buy Add', MagicNumber, 0, Blue);
                                if (buyOrderTicket < 0)
                                {
                                    Print('Failed to open buy add order: ', GetLastError());
                                }
                            }
                        }
                        else if (OrderType() == OP_SELL) // 空单
                        {
                            for (int k = 1; k <= addLotCount && k <= MaxAddLotCount; k++)
                            {
                                double addLotSize = InitialLotSize * MathPow(AddLotMultiplier, k);
                                double addLotEntryPrice = firstOrderProfitTarget - Gap * k;
                                int sellOrderTicket = OrderSend(Symbol(), OP_SELL, addLotSize, addLotEntryPrice, 0, 0, 0, 'Sell Add', MagicNumber, 0, Red);
                                if (sellOrderTicket < 0)
                                {
                                    Print('Failed to open sell add order: ', GetLastError());
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

void OnStart()
{
    OnTick();
}

该策略还使用了以下参数:

  • MagicNumber: 魔术码,用于识别交易者自己的订单
  • InitialLotSize: 初始手数
  • Gap: 间距,用于设置挂单的价格
  • AddLotMultiplier: 补仓倍数
  • MaxAddLotCount: 最大补仓次数
  • ProfitTarget: 盈利目标(美金)
  • Slippage: 滑点值
  • MaxLoss: 最大亏损(美金)
多空共存交易策略:添加总亏损1000美金平仓功能

原文地址: https://www.cveoy.top/t/topic/cjo7 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录