Страница 1 из 1

TrailingStop и StepByStep

Добавлено: 21 сен 2020, 15:35
Kozjkov
Здравствуйте! Как сделать в стратегии StepByStep не продажу на указанный процент, а чтобы он выставлял к купленному лоту трелингстоп на указанный процент.
Пример робот при покупке лота на минус 2% от первоначальной цены ставит лот на продажу на +2% и выставляет трелингстоп на +1%.

Re: TrailingStop и StepByStep

Добавлено: 23 сен 2020, 22:40
E_V_N
Не понятно, по вашему описанию вы хотите купить один лот, и 2 раза продать его с +2% и через трейлингстоп?

Re: TrailingStop и StepByStep

Добавлено: 24 сен 2020, 19:14
Kozjkov
Продажа докупленных лотов через трейлингстоп

Re: TrailingStop и StepByStep

Добавлено: 27 сен 2020, 15:01
Kozjkov
Как сделать чтобы продавались по трейлингстоп не все лоты сразу а последний купленный?
[

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

function Initialize()
{
    StrategyName = "StepBaytreling";
    AddInput("Input1", Inputs.Candle, 5, true, "CHMF=МБ ЦК");
    AddParameter("StartQ", 6, "Стартовое кол-во", 0);
    AddParameter("Q", 2, "Кол-во докупки", 0);

    AddParameter("DeltaPercent", 2.5, "% изменения цены для докупки и продажи", 0);

    AddGlobalVariable("inited", Types.Boolean, false);
    AddGlobalVariable("lastSignalId", 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;
         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);
      else
         lastPriceSorted[signal.PriceOfTrade] += 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;
     }

   //Правило 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;//ждём исполнения уже выставленной заявки
        }

      TrailingStopLoss ((0.7, SignalPriceType.DeltaInPercentFromAveragePrice),Q);
        var lastSignal = GetLastSignalInfo();
      if(lastSignal != null)
         lastSignalId = lastSignal.SignalID;
    }
     
   LastPrice = new Dictionary<double, double>(lastPriceSorted);
   LastPriceCount = LastPrice.Count;
}


 

Re: TrailingStop и StepByStep

Добавлено: 30 сен 2020, 23:46
E_V_N

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

if (Input1.Close[0] >= MinPrice* (1.0 + 0.01 * DeltaPercent) && pos > 0 )
 
      TrailingStopLoss ((0.7, SignalPriceType.DeltaInPercentFromAveragePrice),Q);


Как у вас написано, в принципе и будет продана последняя покупка, нужно только что бы DeltaPercent был больше 0,7 заданного в TrailingStopLoss. Или TrailingStopLoss вычислять и выставлять от MinPrice* (1.0 + 0.01 * DeltaPercent) .

Re: TrailingStop и StepByStep

Добавлено: 01 окт 2020, 17:00
Maks
Выберите еще метод расчета отчета и уч.цены = LIFO чтобы ПУ/НПУ правильно считались)

Re: TrailingStop и StepByStep

Добавлено: 08 май 2021, 13:26
ip851874
E_V_N писал(а):

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

if (Input1.Close[0] >= MinPrice* (1.0 + 0.01 * DeltaPercent) && pos > 0 )
 
      TrailingStopLoss ((0.7, SignalPriceType.DeltaInPercentFromAveragePrice),Q);


Как у вас написано, в принципе и будет продана последняя покупка, нужно только что бы DeltaPercent был больше 0,7 заданного в TrailingStopLoss. Или TrailingStopLoss вычислять и выставлять от MinPrice* (1.0 + 0.01 * DeltaPercent) .



После добавления данного элемента выдает ошибку, это изменение относится к 3 правилу?

Re: TrailingStop и StepByStep

Добавлено: 07 дек 2021, 10:52
ip851874
E_V_N Доброго дня!
Подскажите, как в StepByStep 2 сделать StartQ по заданному уровню цены?