Аналог ObjectGetValueByTime может кто то реализовывал ? - страница 2

 
Ihor Herasko #:

Это коэффициенты из уравнения прямой. K - тангенс угла наклона прямой к оси абсцисс (в случае с ценовым графиком абсцисса - это время), B - цена пересечения прямой с осью ординат (для ценового графика B - это цена линии на текущем баре, т. к. x = 0). Зная эти коэффициенты, можно рассчитать цену для любого индекса бара и, соответственно, индекс бара для любой цены.

Покажите, как подставляли.

Я благодарен Вам, но мне трудно разобраться в приведенном Вами примере.

Я хочу отправить три времени и две цены что бы рассчитать цену для третьего времени.

 
Vladimir Pastushak #:
int indx2 = iBarShift(_Symbol, PERIOD_CURRENT, m_line.Time(1), true);

Принтуйте. Что вам может вернуть iBarShift, за пределами баровой истории? Вряд ли, что то отличное от -1. 

Я же вам написал, чтоб вы вставили время вместо индексов. 

 

Переписал иначе:

double PriceByTime(datetime t1, double p1, datetime t2, double p2, datetime t)
  {


// Индексы опорных точек
   int bar1 = iBarShift(_Symbol, _Period, t1);
   int bar2 = iBarShift(_Symbol, _Period, t2);
   if(bar1 == -1 || bar2 == -1)
     {
      Print("Ошибка: точки вне истории");
      return 0.0;
     }

// Границы истории на графике
   datetime firstTime = iTime(_Symbol, _Period, Bars(_Symbol, _Period) - 1);
   datetime lastTime  = iTime(_Symbol, _Period, 0);

// Если t внутри истории → интерполяция по индексам баров
   if(t >= firstTime && t <= lastTime)
     {
      int bar = iBarShift(_Symbol, _Period, t);
      if(bar == -1)
         return 0.0;
      if(bar1 == bar2)
         return p1;
     
      return p1 + (p2 - p1) * ((double)(bar - bar1) / (double)(bar2 - bar1));
     }
// Иначе (t вне истории) → экстраполяция по календарному времени
   else
     {
      if(t1 == t2)
         return p1;

      return p1 + (p2 - p1) * ((double)(t - t1) / (double)(t2 - t1));
     }
  }

Но все равно результат не верный даже на истории по барам есть баг



 
Vladimir Pastushak #:

Переписал иначе:

Но все равно результат не верный даже на истории по барам есть баг

Я не знаю, в чём у вас проблема, я знаю, что функция, что я вам скинул работает правильно.

Вероятнее всего проблема в использовании CHARTEVENT_OBJECT_DRAG. Оно не подходит для определения координат перетаскиваемого объекта, при использование события CHARTEVENT_OBJECT_DRAG корректные значения ваша функция получит только поле того как вы отпустите трендовую.

 
Aleksandr Slavskii #:

Я не знаю, в чём у вас проблема, я знаю, что функция, что я вам скинул работает правильно.

Вероятнее всего проблема в использовании CHARTEVENT_OBJECT_DRAG. Оно не подходит для определения координат перетаскиваемого объекта, при использование события CHARTEVENT_OBJECT_DRAG корректные значения ваша функция получит только поле того как вы отпустите трендовую.

CHARTEVENT_OBJECT_DRAG не используется. Благодарю за помощь.
 
Vladimir Pastushak #:

Переписал иначе:

Но все равно результат не верный даже на истории по барам есть баг



Как я понял, эта стрелка должна принадлежать прямой. Так? А почему нет кода рисования этой стрелки? 

В какой-то момент я вижу, что стрелка находится на продолжении прямой. И это правильно. Есть формула прямой по двум точкам и нет никакой разницы ищем точку на прямой между этими координатами или за пределами этих координат.

 
Alexey Viktorov #:

Как я понял, эта стрелка должна принадлежать прямой. Так? А почему нет кода рисования этой стрелки? 

В какой-то момент я вижу, что стрелка находится на продолжении прямой. И это правильно. Есть формула прямой по двум точкам и нет никакой разницы ищем точку на прямой между этими координатами или за пределами этих координат.

Если использовать ObjectGetValueByTime  то все верно рисует, и стрелка на своем месте.

Стрелка отображает результат вычислений.

Если я использую аналоги то стрелка показывает результат работы аналога.

 

Перепробовал массу формул и их вариаций, но рабочего результата не получил.

Цель сделать более дешёвый аналог ObjectGetValueByTime.

 
Vladimir Pastushak #:

Я хочу отправить три времени и две цены что бы рассчитать цену для третьего времени.

Вот демонстрационный скрипт того, что я описал:

void OnStart()
{
   // Исходные данные
   int nLeftBar = 20;
   int nRightBar = 10;
   datetime dtTime1 = iTime(NULL, PERIOD_CURRENT, nLeftBar);
   datetime dtTime2 = iTime(NULL, PERIOD_CURRENT, nRightBar);
   double fPrice1 = iHigh(NULL, PERIOD_CURRENT, nLeftBar);
   double fPrice2 = iHigh(NULL, PERIOD_CURRENT, nRightBar);
   
   ShowTrendLine("TRNDLN", dtTime1, fPrice1, dtTime2, fPrice2, "/n", clrBlue, 2);
   
   // Расчет коэффициентов прямой
   double fKKoef = 0;
   double fBKoef = CalculateBAndKKoefs(nLeftBar, fPrice1, nRightBar, fPrice2, fKKoef);
   
   // Расчет цены на заданном баре
   int nThirdBar = 5;
   double fPrice3 = fKKoef * nThirdBar + fBKoef;

   ShowTrendLine("TRNDLNNXT", dtTime2, fPrice2, iTime(NULL, PERIOD_CURRENT, nThirdBar), fPrice3, "/n", clrRed, 2);
}

void ShowTrendLine(string sName, datetime time1, double price1, datetime time2, double price2, string toolTip, color clr, const int nWidth)
{
   if (ObjectFind(0, sName) < 0)
   {
      ObjectCreate(0, sName, OBJ_TREND, 0, time1, price1, time2, price2);
      ObjectSetInteger(0, sName, OBJPROP_BACK, false);
      ObjectSetInteger(0, sName, OBJPROP_WIDTH, (int)nWidth);
      ObjectSetInteger(0, sName, OBJPROP_RAY, false);
      ObjectSetInteger(0, sName, OBJPROP_HIDDEN, true);
      ObjectSetInteger(0, sName, OBJPROP_SELECTABLE, false);
   }
   else
   {
      ObjectMove(0, sName, 0, time1, price1);
      ObjectMove(0, sName, 1, time2, price2);
   }
   
   ObjectSetInteger(0, sName, OBJPROP_COLOR, clr);
   ObjectSetString(0, sName, OBJPROP_TOOLTIP, toolTip);
}

double CalculateBAndKKoefs(const int nX1, const double fY1, const int nX2, const double fY2, double &fKKoef)
{
   if (nX1 == nX2)
      return DBL_MAX;
      
   fKKoef = (fY2 - fY1) / (nX2 - nX1);
   return fY1 - fKKoef * nX1;   
}

Синяя линия - это изначальная линия, а красная линия показывает расчетное продолжение синей линии, приводя ее в третью точку. Именно в ту точку, цену которой хотите найти.

 
Vladimir Pastushak #:

Перепробовал массу формул и их вариаций, но рабочего результата не получил.

Цель сделать более дешёвый аналог ObjectGetValueByTime.

Сделайте через тангенс угла. Это всего ДВЕ строки.

Одна из них

  double tang = double(tim_1-tim_0)/(pr_1-pr_0);            //  тангенс