以下代码展示了一个外汇交易策略,使用魔术码管理订单,并包含止损止盈和补仓策略。

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 = 40; // 盈利目标(美金)
extern int Slippage = 3; // 滑点值

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)
                {
                    if (!OrderClose(OrderTicket(), OrderLots(), Bid, 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(), Bid, 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(), Ask, 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());
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

代码解析

  1. 魔术码: MagicNumber 用于识别和管理由同一策略生成的订单。在代码中,它被用来区分不同策略的订单。
  2. 初始手数: InitialLotSize 定义了初始订单的手数,在本例中为 0.5 手。
  3. 间距: Gap 定义了挂单价格与最新价格之间的点差,在本例中为 100 点。
  4. 补仓倍数: AddLotMultiplier 定义了每次补仓的倍数,在本例中为 0.6 倍。
  5. 补仓次数: MaxAddLotCount 定义了最大补仓次数,在本例中为 5 次。
  6. 盈利目标: ProfitTarget 定义了订单盈利的目标,在本例中为 40 美金。
  7. 滑点值: Slippage 定义了允许的滑点,在本例中为 3 点。

交易逻辑

该交易策略主要包含以下逻辑:

  1. 判断是否持仓: 首先,代码会检查当前魔术码是否持仓。如果未持仓,则进行挂单操作;如果已持仓,则进行平仓或补仓操作。
  2. 挂单操作: 如果没有持仓,代码会根据最新价格计算挂单价格,并分别发送买入止损和卖出止损订单。同时,代码还会设置挂单的止损和止盈。
  3. 平仓操作: 如果持仓,代码会遍历所有持仓订单,并检查每个订单的盈利情况。如果订单的盈利达到盈利目标,则进行平仓操作。
  4. 补仓操作: 如果持仓,代码会判断是否需要补仓。补仓的条件是当前订单的盈利超过了 Gap 的倍数,并且补仓次数没有超过 MaxAddLotCount。代码会根据补仓倍数计算补仓的手数和价格,并发送补仓订单。

代码说明

该代码只是一个示例,实际应用中需要根据具体的交易策略进行调整和完善。

注意: 以下内容需要根据具体的交易平台和语言进行修改。

  • MarketInfo(Symbol(), MODE_BID): 获取当前交易品种的最新卖出报价。
  • OrdersTotal(): 获取当前所有订单的数量。
  • OrderSelect(i, SELECT_BY_POS, MODE_TRADES): 选择第 i 个交易订单。
  • OrderMagicNumber(): 获取订单的魔术码。
  • OrderSend(Symbol(), OP_BUYSTOP, lotSize, buyStopPrice, 0, 0, 0, 'Buy Stop', MagicNumber, 0, Blue): 发送买入止损挂单。
  • OrderModify(buyStopOrderTicket, OrderOpenPrice(), NormalizeDouble(entryPrice - Gap * 2, Digits), OrderTakeProfit(), 0, Green): 修改止损订单。
  • OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, Red): 平仓订单。
  • OrderProfit(): 获取订单的盈利。
  • OrderType(): 获取订单的类型(买入或卖出)。
  • OrderOpenPrice(): 获取订单的开仓价格。
  • OrderLots(): 获取订单的手数。
  • Bid: 获取当前的买入报价。
  • Ask: 获取当前的卖出报价。
  • MathFloor(orderProfit / Gap): 计算补仓次数。
  • MathPow(AddLotMultiplier, k): 计算补仓倍数。
  • NormalizeDouble(entryPrice - Gap * 2, Digits): 将止损价格格式化。
  • Print('Failed to modify buy stop order: ', GetLastError()): 打印错误信息。

免责声明: 本文提供的代码仅供参考,不构成任何投资建议。任何交易行为都需要根据自身情况进行谨慎判断。

外汇交易策略代码解析:魔术码、止损止盈和补仓策略

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

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