Стратегии и роботы > Остановка робота по достижению указанной прибыли

Обсуждение, описание стратегий и роботов, идеи для стратегий
Аватара пользователя
ip851874
Сообщения: 50
Зарегистрирован: 21 ноя 2020, 22:56
Откуда: Москва
Благодарил (а): 19 раз
Контактная информация:

Остановка робота по достижению указанной прибыли

Непрочитанное сообщение ip851874 » 02 июл 2025, 22:07

Доброго времени!
Добавьте пожалуйста код для остановки робота по достижению указанной прибыли. Спасибо!

Аватара пользователя
evge
Администратор
Сообщения: 1816
Зарегистрирован: 04 фев 2016, 09:46
Откуда: Млечный путь, планета Земля
Благодарил (а): 83 раза
Поблагодарили: 373 раза
Контактная информация:

Re: Остановка робота по достижению указанной прибыли

Непрочитанное сообщение evge » 03 июл 2025, 13:13

Добрый день,

в function Initialize()

добавить

Код: Выделить всё

AddParameter("RPL", 9999999, "Остановить робота, если прибыль достигла значения", 0);


в function OnUpdate()

добавить

Код: Выделить всё

if (RealizedPL() >= RPL)
   {
   Stop();
   }




RealizedPL() – возвращает текущий реализованный доход по закрытым сделкам робота (стратегии).

Нужно учитывать! Если сделка открыта, робот будет работать даже если прибыль достигнута по открытой сделке.

Если нужно чтобы учитывалась и открытая, то нужно изменить условие на RealizedPL() + CurrentPL() и добавить ClosePosition() перед Stop().
никогда такого не было и вот опять

Аватара пользователя
ip851874
Сообщения: 50
Зарегистрирован: 21 ноя 2020, 22:56
Откуда: Москва
Благодарил (а): 19 раз
Контактная информация:

Re: Остановка робота по достижению указанной прибыли

Непрочитанное сообщение ip851874 » Вчера, 09:49

При компиляции выдает:
//----------- Код, оказавшийся вне методов -----------//
//if (RealizedPL()) >= RPL)
// {
// Stop();
// }

Аватара пользователя
ip851874
Сообщения: 50
Зарегистрирован: 21 ноя 2020, 22:56
Откуда: Москва
Благодарил (а): 19 раз
Контактная информация:

Re: Остановка робота по достижению указанной прибыли

Непрочитанное сообщение ip851874 » Вчера, 10:46

Код: Выделить всё

function Initialize()
{
    StrategyName = "MyMTS557";
    AddInput("Input1", Inputs.Candle, 5, true, "GAZP=МБ ЦК");
    AddParameter("StartQ", 100, "Стартовое кол-во", 0);
    AddParameter("Q", 10, "Кол-во докупки", 0);
    AddParameter("RPL", 9999999, "Остановить робота, если прибыль достигла значения", 0);
    AddParameter("DeltaPercent", 1, "% изменения цены для докупки и продажи", 0);

    AddGlobalVariable("inited", Types.Boolean, false);
    AddGlobalVariable("lastSignalId", Types.Int, 0);
    AddGlobalVariable("lastSignalProcessed", Types.Int, 0);
    AddGlobalVariable("xPosition", Types.Double, 0.0);
    AddGlobalVariable("LastPrice", Types.DoubleDictionary);
    AddGlobalVariable("LastPriceCount", Types.Int, 0);
    AddGlobalVariable("LongLimitStart", Types.Double, 0);
    AddGlobalVariable("StartPrice", Types.Double, 0);

    AddGlobalVariable("Last", Types.Double, 0);
    AddGlobalVariable("MinPrice", Types.Double, 0);
    AddGlobalVariable("Type", Types.Double, 1);

    AddChartIndicator("MY.str_Invest_Grid", new Dictionary <string, string>{{"Price", "MinPrice"},{"PL", "DeltaPercent"},{"Delta", "DeltaPercent"}, {"Type", "Type"}});
}

function OnUpdate()
{
      if(StartPrice == 0)
        StartPrice = Input1.Close[0];

    double pos = CurrentPosition();
    var signal = GetSignalInfo(lastSignalId);
    var activeOrder = GetActiveOrders().FirstOrDefault(ao => ao.SignalId == lastSignalId);
       // StartQ - позиция робота при старте
    // Правило 1. если первый запуск и робот не проинициализирован, покупаем  StartQ
    if (pos < StartQ && !inited)
    {
        if ( (Q%LotSize() != 0) || (StartQ%LotSize() != 0) )
        {
            ShowMessage("StartQ или Q не кратно лоту.Робот остановлен!");
            Stop();
        }

        if(LongLimitStart == 0)
        {
            LongLimitStart = LongLimit;
            SetLongLimit(StartQ);
        }

       // Покупка StartQ
       if (StartQ > 0)        
        {
          EnterLongLimit(Input1.Close[0]*(1.0 + 0.01 * OrderSlippage));
            var lastSignal = GetLastSignalInfo();
            if(lastSignal != null)
            {
                lastSignalId = lastSignal.SignalID;
                lastSignalProcessed = 0;
            }
            return;
        }
    }
   
    var lastPriceSorted = new SortedList<double, double>(LastPrice);

    if(pos >= StartQ && !inited)
    {
        inited = true;
        if(LongLimitStart != 0)
            SetLongLimit(LongLimitStart);

        var signals = GetSignalInfo(SignalType.Open, (int)pos);
        var initSum = signals.Where(s => s.ActionSuperType == AvailableActions.Initialization).Sum(s => s.OperationExecuted * Input.Close[0]);
        var boughtSum = signals.Where(s => s.ActionSuperType != AvailableActions.Initialization).Sum(s => s.OperationExecuted * s.PriceOfTrade);
        var avpStart = (initSum + boughtSum) / (pos);
        var avp = avpStart;

        double b = xPosition;
        while (pos - b > 0)
       {
          lastPriceSorted.Add(avp, Math.Min(Q, pos - b));
          avp += avpStart * 0.01* DeltaPercent;
            b = b + Q;
        }           
        xPosition = pos;
    }
      
   if(!inited)
   {
      CancelActiveOrders(true);
      return;
   }

    if(activeOrder != null && activeOrder.IsStatusFilled && pos == xPosition)
    {
        return;//ждём сделки
    }

   //корректировка уровней
   if(pos > xPosition)//позиция увеличилась
   {
      if(!lastPriceSorted.ContainsKey(signal.PriceOfTrade))
         lastPriceSorted.Add(signal.PriceOfTrade, signal.OperationExecuted - lastSignalProcessed);
      else
         lastPriceSorted[signal.PriceOfTrade] += (signal.OperationExecuted - lastSignalProcessed);

        lastSignalProcessed = signal.OperationExecuted;
   }
   else if(pos < xPosition && lastPriceSorted.Count >= 1)
   {
      var b = xPosition;
      while(b > pos)
      {
         if(lastPriceSorted.Count == 0) break;
         
         var firstKey = lastPriceSorted.First().Key;
         if(b - pos<lastPriceSorted[firstKey])
         {
            lastPriceSorted[firstKey] -= (b - pos);//Исполнили часть уровня
            b -= (b - pos);
         }
         else
         {
            b -= lastPriceSorted[firstKey];//Исполнили весь уровень
            lastPriceSorted.Remove(firstKey);
         }
      }
   }

   xPosition = pos;//позиция учтена выше
   
   var lastSignalFilled = GetLastSignalInfo();
   if(lastPriceSorted.Count <= 0)
   {
      MinPrice = lastSignalFilled != null ? lastSignalFilled.PriceOfTrade : StartPrice;
   }
   else
   {
      MinPrice = lastPriceSorted.First().Key;
   }

   //Правило 2. Если цена упала и кол-во меньше допустимого,
   //           то покупаем и добавляем цену покупки в начало списка
   if (Input1.Close[0] <= MinPrice* (1.0 - 0.01 * DeltaPercent) && pos + Q <= LongLimit )
   {
        if(activeOrder != null && !activeOrder.IsStatusTerminal)
        {
            if(activeOrder.OrderDirection != OrderDirection.Buy)
                CancelActiveOrders(true);
            return;//ждём исполнения уже выставленной заявки
        }

      EnterLongLimit(MinPrice* (1.0 - 0.01 * (DeltaPercent - OrderSlippage)), Q);
        var lastSignal = GetLastSignalInfo();
      if(lastSignal != null)
        {
         lastSignalId = lastSignal.SignalID;
            lastSignalProcessed = 0;
        }
     }

   //Правило 3. Если цена выше цены из начала списка, то продаем и удаляем 0-й элемент списка    
   if (Input1.Close[0] >= MinPrice* (1.0 + 0.01 * DeltaPercent) && pos > 0 )
    {
        if(activeOrder != null && !activeOrder.IsStatusTerminal)
        {
            if(activeOrder.OrderDirection != OrderDirection.Sell)
                CancelActiveOrders(true);
            return;//ждём исполнения уже выставленной заявки
        }

                var vSell = (int)lastPriceSorted.First().Value;
      CloseLongLimit(MinPrice* (1.0 + 0.01 * (DeltaPercent - OrderSlippage)), vSell);
        var lastSignal = GetLastSignalInfo();
      if(lastSignal != null)
        {
         lastSignalId = lastSignal.SignalID;
            lastSignalProcessed = 0;
        }
    }
     
   LastPrice = new Dictionary<double, double>(lastPriceSorted);
   LastPriceCount = LastPrice.Count;
}


//----------- Код, оказавшийся вне методов -----------//
//Правило 4. Если достигли указанной прибыли, закрываем всю позицию.
//    if (RealizedPL()) >= RPL)
//   {
//   Stop();
//   
//   }

Аватара пользователя
evge
Администратор
Сообщения: 1816
Зарегистрирован: 04 фев 2016, 09:46
Откуда: Млечный путь, планета Земля
Благодарил (а): 83 раза
Поблагодарили: 373 раза
Контактная информация:

Re: Остановка робота по достижению указанной прибыли

Непрочитанное сообщение evge » Вчера, 20:19

if (RealizedPL()) >= RPL)

Заменить на

if (RealizedPL() >= RPL)

Лишняя скобка была, выше поправил
никогда такого не было и вот опять

Аватара пользователя
ip851874
Сообщения: 50
Зарегистрирован: 21 ноя 2020, 22:56
Откуда: Москва
Благодарил (а): 19 раз
Контактная информация:

Re: Остановка робота по достижению указанной прибыли

Непрочитанное сообщение ip851874 » Вчера, 20:47

Да, работает сейчас! Благодарю :D


Вернуться в «Стратегии и роботы»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 11 гостей