Общие вопросы по разработке > Узнать дату/время открытия позиции

Общие вопросы по разработке в Альфа-Директ 4. Обсуждение разработки пользовательских индикаторов, стратегий.
BugsDigger
Сообщения: 535
Зарегистрирован: 11 ноя 2018, 17:11
Благодарил (а): 21 раз
Поблагодарили: 92 раза

Узнать дату/время открытия позиции

Непрочитанное сообщение BugsDigger » 16 янв 2019, 19:00

Привет всем.

Как узнать дату/время открытия позиции (в том числе в тестировании, если есть разница)?
GetPosition, currentPosition даты/времени не дают...

AP_Bor
Сообщения: 170
Зарегистрирован: 18 дек 2017, 08:18
Благодарил (а): 12 раз
Поблагодарили: 8 раз

Re: Узнать дату/время открытия позиции

Непрочитанное сообщение AP_Bor » 16 янв 2019, 23:04

Доброго времени суток, BugsDigger
GetActiveOrders(), в помощь.
► Показать
С наилучшими пожеланиями

BugsDigger
Сообщения: 535
Зарегистрирован: 11 ноя 2018, 17:11
Благодарил (а): 21 раз
Поблагодарили: 92 раза

Re: Узнать дату/время открытия позиции

Непрочитанное сообщение BugsDigger » 17 янв 2019, 06:32

Привет, AP_Bor, спасибо за отклик.

> AP_Bor() в помощь

Умм... Там тоже ничего о времени, разве что есть № документа, поможет ли который, пока не знаю ...

Вообще-то я немного неправильно сформулировал вопрос. На самом деле мне хотелось бы знать время последнего изменения учетной цены позиции в индикаторе (не стратегии), т.е. метку времени (хотя бы примерную) либо открытия позиции (это первое изменение учетной цены), либо её изменения (после сделок с частью позиции).

Зачем. Ну вот накорябал график текущего профита в %. Всё вроде прекрасно при отладке, где вместо взятия позиции просто время от времени генерятся цена и количество. Но при существовании реальной позиции в случае пересчета графика (по любой внутренней причине терминала), он начинает рисоваться от времен царя гороха, ведь позиция-то есть, В результате график не стартует в точке открытия/изменения позиции, а рисуется из "минус бесконечности". Та же самая засада в попытке сделать индикатор StopLossTakeProfit, т.к. при пересчете графика информация о времени сделки (которую я всё же могу засечь по изменению объема позиции ДО пересчета графика) теряется.

AP_Bor
Сообщения: 170
Зарегистрирован: 18 дек 2017, 08:18
Благодарил (а): 12 раз
Поблагодарили: 8 раз

Re: Узнать дату/время открытия позиции

Непрочитанное сообщение AP_Bor » 17 янв 2019, 10:27

Доброго времени суток, BugsDigger
BugsDigger писал(а):... Там тоже ничего о времени, разве что есть № документа, ...
Я предполагал в GetActiveOrders() брать ID сигнала и по нему смотреть сигнал.
BugsDigger писал(а):... Вообще-то я немного неправильно сформулировал вопрос. ...
Уже понял.
BugsDigger писал(а):... учетной цены позиции ...
По моему "позиции", "профита" и так далее в индикаторе просто быть не может, если это не производный график портфеля, например, робота, а в роботе ... ;)
► Показать
С наилучшими пожеланиями

BugsDigger
Сообщения: 535
Зарегистрирован: 11 ноя 2018, 17:11
Благодарил (а): 21 раз
Поблагодарили: 92 раза

Re: Узнать дату/время открытия позиции

Непрочитанное сообщение BugsDigger » 17 янв 2019, 14:48

> "позиции", "профита" и так далее в индикаторе просто быть не может

Ну почему же. Как раз индикатор профита или пользовательского алгоритма StopLoss/TakeProfit и т.п. вполне мог бы отдавать готовые сигналы роботу, почему нет?

В частности, имею желание организовать свой SL/TP, т.е. не по выставленным заявкам, а отслеживать в "ручном" режиме, чтобы на длинных таймфреймах не ловить мгновенные броски цен. Конечно, всё это могу написать в роботе, но это каждый раз тащить в него весь код, что, по понятным причинам, отвратно.

Кроме того, серию, сформированную в роботе нельзя визуализировать стандартными средствами (а, как известно, лучше один раз увидеть, чем сто раз просмотреть какой-нибудь лог), хочешь - не хочешь, а приходится делегировать формирование серии индикатору.

А вообще я не вижу особых препятствий к тому, чтобы разработчики добавили в поля, возвращаемые GetPosition, еще и timestamp момента (пере)расчета (или получения из внешнего источника первоначальной/новой величины, не знаю точно, откуда она берется) учетной цены.

AP_Bor
Сообщения: 170
Зарегистрирован: 18 дек 2017, 08:18
Благодарил (а): 12 раз
Поблагодарили: 8 раз

Re: Узнать дату/время открытия позиции

Непрочитанное сообщение AP_Bor » 17 янв 2019, 15:27

Доброго времени суток, BugsDigger
BugsDigger писал(а):Ну почему же. ...
Пока пропустим.
BugsDigger писал(а):А вообще я не вижу особых препятствий к тому, чтобы разработчики ...
добавили в поля, возвращаемые GetPosition, еще и timestamp момента (пере)расчета (или получения из внешнего источника первоначальной/новой величины, не знаю точно, откуда она берется) учетной цены.
График с параметром например start и
► Показать
► Показать
С наилучшими пожеланиями

High Profit Trader
Сообщения: 80
Зарегистрирован: 23 мар 2018, 10:54
Поблагодарили: 2 раза

Re: Узнать дату/время открытия позиции

Непрочитанное сообщение High Profit Trader » 10 сен 2019, 13:39

Вроде бы никак.

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

Re: Узнать дату/время открытия позиции

Непрочитанное сообщение evge » 27 сен 2019, 12:34

Функции работы с сигналами

GetSignalInfo(int id) – возврат сигнала по номеру
GetLastSignalInfo() – возврат информации по последнему сигналу
GetSignalInfo(SignalType signalType, int quantityFromEnd = 0) – возврат сигналов заданного типа, суммарный объем которых не превышает заданное количество (если quantityFromEnd отлично от нуля)

SignalType.All – любое направление сигнала
SignalType.Close – сигналы закрытия позиции
SignalType.Open – сигналы открытия позиции

Результат исполнения – объект или список объектов, содержащих следующие поля

• SignalID – номер сигнала
• OrderType – тип заявки (купить/продать). (enumOrderType.Buy, enumOrderType.Sell)
• ActionType – название действия (команды)
• ActionSuperType – название сигнала
• OperationSize - объём
• OperationExecuted – исполненный объём
• OperationRest – объём оставшийся для исполнения
• PriceOfSignal – цена сигнала
• PriceOfOrder – цена заявки
• PriceOfTrade – цена исполнения
• PriceAdditional – второй ценовой уровень (если предусмотрен. Напр. В заявке типа BRS)
• DateTime – время сигнала
• CurrentPosition – позиция по роботу после обработки сигнала
• IsStatusFilled – исполнена ли заявка по сигналу
• IsStatusTerminal – в конечном ли статусе заяка по сигналу (исполнена, отменена, отклонена)

Для тестирования нет понятия частичного исполнения, скорее всего, будет картина чуть красивее чем в жизни :)

Подсмотреть пример работы с сигналами можно в коде StepByStep_V2 из библиотеки стратегий.

На всякий случай, копия кода здесь:

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

function Initialize()
{
    StrategyName = "StepByStep_v2";
    AddInput("Input1", Inputs.Candle, 5, true, "GAZP=МБ ЦК");
   
    AddParameter("StartQ", 100, "Стартовое кол-во", 0);
    AddParameter("Q", 10, "Кол-во докупки", 0);
    AddParameter("DeltaPercent", 1, "% изменения цены для докупки и продажи", 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("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()
{
   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 : Input1.Close[0];
   }
   else
   {
      MinPrice = lastPriceSorted.First().Key;
   }

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

      CloseLongLimit(MinPrice* (1.0 + 0.01 * (DeltaPercent - OrderSlippage)), Q);
        var lastSignal = GetLastSignalInfo();
      if(lastSignal != null)
         lastSignalId = lastSignal.SignalID;
    }
     
   LastPrice = new Dictionary<double, double>(lastPriceSorted);
   LastPriceCount = LastPrice.Count;
}
никогда такого не было и вот опять

BugsDigger
Сообщения: 535
Зарегистрирован: 11 ноя 2018, 17:11
Благодарил (а): 21 раз
Поблагодарили: 92 раза

Re: Узнать дату/время открытия позиции

Непрочитанное сообщение BugsDigger » 28 сен 2019, 07:58

Это какая-то новая функция? Если да, то есть ли обновленная документация?

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

Re: Узнать дату/время открытия позиции

Непрочитанное сообщение evge » 28 сен 2019, 09:43

Да, новая, которую Дмитрий (oxi) анонсировал

- Функция доступ к списку сигналов (смотрите позже описание скриптов на сайте)


но не было в документации. Теперь есть. Копипаст выше из документации.
никогда такого не было и вот опять


Вернуться в «Общие вопросы по разработке»

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

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