请教移动挂单问题

 

高手们,谁帮我修改下这个EA,非常感谢。

想实现,价格每上涨超过启动点数时或者价格每下跌超过启动点数时,移动一次挂单。

现在的代码不对,好像是波动超过这个点数就移动一次挂单了。

    
input double stop单手数倍数 = 2.0;          
input double stop单距离点数 = 200;             
input double limit单手数倍数 = 1.0;      
input double limit单距离点数 = 400;
input double 总盈利大于几美金平仓 = 1000;
input double 总亏损大于几美金清仓 = 200000;
input bool 挂单移动开关 = false;   // Enable/disable moving pending order
input double 移动挂单启动点数 = 300.0;    // Move trigger distance
input double 挂单移动点数 = 100.0; // Pending order move distance

double lastKnownPrice = 0;

void OnTick()
{
  
       double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
       if (currentPrice > lastKnownPrice + 移动挂单启动点数 * Point)
{
    // Price is rising, move sell stop and buy limit
    lastKnownPrice = currentPrice;
    
    // Move the pending orders if enabled
    if (挂单移动开关)           
        MovePendingUpOrder(挂单移动点数);
}
else if (lastKnownPrice-currentPrice > 移动挂单启动点数 * Point)
{
    // Price is falling, move sell limit and buy stop
    lastKnownPrice = currentPrice;
    
    // Move the pending orders if enabled
    if (挂单移动开关)           
        MovePendingDownOrder(挂单移动点数);  // Use negative value for falling prices
}


        if ((sellprofit()+buyprofit()) > 总盈利大于几美金平仓)
        {
            closeAllOrders();
            Alert("本币达到盈利金额全平");
        }
        //else if (totalLoss > 总亏损大于几美金清仓)
        {
            //closeAllOrders();
            //Alert("本币达到亏损金额全平");
        }
   CheckAndPlaceReverseStopLoss();
    
}
     
void CheckAndPlaceReverseStopLoss()
{
    int totalOrders = OrdersHistoryTotal();

    if (totalOrders > 0)
    {
        int latestPositionIndex = -1;
        int latestOrderType = 0;

        for (int i = totalOrders - 1; i >= 0; i--)
        {
            if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol() == Symbol())
            {
                latestPositionIndex = i;
                latestOrderType = OrderType();
                break;
            }
        }

        if (latestPositionIndex >= 0)
        {
            if (OrderSelect(latestPositionIndex, SELECT_BY_POS, MODE_TRADES))
            {
                double stopLossPrice = 0;
                double limitPrice = 0;  // 初始化 limitPrice

                if (latestOrderType == OP_BUY)
                {
                    stopLossPrice = OrderOpenPrice() - stop单距离点数 * Point;
                    limitPrice = OrderOpenPrice() + limit单距离点数 * Point;
                }
                else if (latestOrderType == OP_SELL)
                {
                    stopLossPrice = OrderOpenPrice() + stop单距离点数 * Point;
                    limitPrice = OrderOpenPrice() - limit单距离点数 * Point;
                }

                double lotSize = OrderLots() * stop单手数倍数;
                int orderType = (latestOrderType == OP_BUY) ? OP_SELLSTOP : OP_BUYSTOP;

                // 发送反向止损订单
                int stopLossTicket = OrderSend(OrderSymbol(), orderType, lotSize, stopLossPrice, 30000, 0, 0, "ziyou457457", 0, 0, clrNONE);

                if (stopLossTicket > 0)
                {
                    Print("Reverse stop loss order placed successfully. Ticket: ", stopLossTicket);

                    // 同向限价订单
                    lotSize = OrderLots() * limit单手数倍数;
                    int limitOrderType = (latestOrderType == OP_BUY) ? OP_SELLLIMIT : OP_BUYLIMIT;

                    // 发送同向限价订单
                    int limitTicket = OrderSend(OrderSymbol(), limitOrderType, lotSize, limitPrice, 30000, 0, 0, "ziyou457457", 0, 0, clrNONE);

                    if (limitTicket > 0)
                        Print("Limit order placed successfully. Ticket: ", limitTicket);
                    else
                        Print("Error placing limit order. Error code: ", GetLastError());
                }
                else
                {
                    Print("Error placing reverse stop loss order. Error code: ", GetLastError());
                }
            }
        }
    }
}
bool OrderExists(int orderType)
{
   for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol() == Symbol() && OrderType() == orderType)
      {
         return true;
      }
   }
   return false;
}
double buyprofit()
  {
     double a=0;
     int t=OrdersTotal();
     for(int i=t-1;i>=0;i--)
         {
           if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
             {
               if(OrderSymbol()==Symbol() && OrderType()==OP_BUY)
                 {
                   a=a+OrderProfit()+OrderCommission()+OrderSwap();
                 }
             }
         }  
    return(a);
  }
double sellprofit()
  {
     double a=0;
     int t=OrdersTotal();
     for(int i=t-1;i>=0;i--)
         {
           if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
             {
               if(OrderSymbol()==Symbol() && OrderType()==OP_SELL )
                 {
                   a=a+OrderProfit()+OrderCommission()+OrderSwap();
                 }
             }
         }  
    return(a);
  }


void closeAllOrders()
{
    int t = OrdersTotal();
    for (int i = t - 1; i >= 0; i--)
    {
        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true && OrderSymbol() == Symbol())
        {
            if (OrderType() == OP_SELL || OrderType() == OP_BUY || OrderType() == OP_BUYLIMIT || OrderType() == OP_BUYSTOP || OrderType() == OP_SELLLIMIT || OrderType() == OP_SELLSTOP)
            {
                OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 300, clrNONE);
                OrderDelete(OrderTicket());
            }
        }
    }
}
void MovePendingDownOrder(double moveDistance)
{
    // Find the pending order
    for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
    {
        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol() == Symbol() &&(OrderType() == OP_BUYSTOP || OrderType() == OP_SELLLIMIT))
        {
            double newPrice;

            // Calculate the new price based on the order type and move distance
            if (OrderType() == OP_BUYSTOP || OrderType() == OP_SELLLIMIT)
                newPrice = OrderOpenPrice() - moveDistance * Point;            
            if (OrderModify(OrderTicket(), newPrice, OrderTakeProfit(), OrderStopLoss(), 0, clrNONE))
            {
                Print("Pending order moved successfully. New Price: ", newPrice);
            }
            else
            {
                Print("Error moving pending order. Error code: ", GetLastError());
            }

            // Exit the loop after modifying the first pending order found
            break;
        }
    }
}

void MovePendingUpOrder(double moveDistance)
{
    // Find the pending order
    for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
    {
        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol() == Symbol() &&(OrderType() == OP_SELLSTOP || OrderType() == OP_BUYLIMIT ))
        {
            double newPrice;

            if (OrderType() == OP_SELLSTOP || OrderType() == OP_BUYLIMIT)
                newPrice = OrderOpenPrice() + moveDistance * Point;

            // Modify the order with the new price
            if (OrderModify(OrderTicket(), newPrice, OrderTakeProfit(), OrderStopLoss(), 0, clrNONE))
            {
                Print("Pending order moved successfully. New Price: ", newPrice);
            }
            else
            {
                Print("Error moving pending order. Error code: ", GetLastError());
            }

            // Exit the loop after modifying the first pending order found
            break;
        }
    }
}
 
Frist001:

高手们,谁帮我修改下这个EA,非常感谢。

想实现,价格每上涨超过启动点数时或者价格每下跌超过启动点数时,移动一次挂单。

现在的代码不对,好像是波动超过这个点数就移动一次挂单了。

你的預算多少?

 
Frist001:

高手们,谁帮我修改下这个EA,非常感谢。

想实现,价格每上涨超过启动点数时或者价格每下跌超过启动点数时,移动一次挂单。

现在的代码不对,好像是波动超过这个点数就移动一次挂单了。

Print()把函數或變數打印出來自己找原因,編程就只是不定期的三個步驟。

1.了解程式語言經常會用到的語法,舉例if...else,for,函數,變數,參數。

2.了解程式語言的內建函數功能。

3.遇到困難時,但編譯又沒有錯時,將函數返回結果給打印出來。

上面三個步驟不一定要按照順序,照自己的節奏調整就好。

編程就只是這樣而已,但很多人都會忘記第三個步驟的重要性,自己找答案會比求神問佛還要有效率。

而且下次遇到類似的問題時,也才知道要如何找到答案。

 
Hong Yi Li #:

Print()把函數或變數打印出來自己找原因,編程就只是不定期的三個步驟。

1.了解程式語言經常會用到的語法,舉例if...else,for,函數,變數,參數。

2.了解程式語言的內建函數功能。

3.遇到困難時,但編譯又沒有錯時,將函數返回結果給打印出來。

上面三個步驟不一定要按照順序,照自己的節奏調整就好。

編程就只是這樣而已,但很多人都會忘記第三個步驟的重要性,自己找答案會比求神問佛還要有效率。

而且下次遇到類似的問題時,也才知道要如何找到答案。

好的,谢谢您的回复。