Нужна помошь с графикой (не могу отвязать 0 бар)

 

Нужна помощь. Хочу параллельно поставить пунктиры к уровням. При перемещении пунктир не идёт за 0 бар.

ширина регулируется внешним параметром

вот как хочу, хорошо, что пайнт есть

вот, что хотел сделать 

у меня сейчас получается

задумка была такая с внешней функции хотел взять координаты уровней и поставить параллельно им пунктиры

вот что у меня во внешний функции по уровням

// 2. ЗЕЛЕНАЯ горизонтальная линия: от последней зеленой точки вправо
   string upperHorizName = "ZZ_TL3_UpperHoriz";
   CreateTrendLine(upperHorizName, 
                   zzHighTimes[ArraySize(zzHighTimes)-1], zzHighValues[ArraySize(zzHighValues)-1],
                   currentTime, zzHighValues[ArraySize(zzHighValues)-1],
                   myUpperTrendLine3Color, myUpperTrendLine3Style, myUpperTrendLine3Width);

   // 4. КРАСНАЯ горизонтальная линия: от последней красной точки вправо
   string lowerHorizName = "ZZ_TL3_LowerHoriz";
   CreateTrendLine(lowerHorizName, 
                   zzLowTimes[ArraySize(zzLowTimes)-1], zzLowValues[ArraySize(zzLowValues)-1],
                   currentTime, zzLowValues[ArraySize(zzLowValues)-1],
                   myLowerTrendLine3Color, myLowerTrendLine3Style, myLowerTrendLine3Width);

а вот полностью внешняя функция уровней отката

void DrawRetraceLines()
{
    // Если флаг Retracelines выключен - удаляем линии и выходим
    if(!Show_Retracelines) 
    {
        ObjectDelete(0, "Retrace_Upper");
        ObjectDelete(0, "Retrace_Lower");
        return;
    }
    
    // ВАЖНО: Retracelines работают ТОЛЬКО если включены Trendlines
    if(!Show_Trendlines)
    {
        ObjectDelete(0, "Retrace_Upper");
        ObjectDelete(0, "Retrace_Lower");
        return;
    }
    
    // Получаем имена горизонтальных трендовых линий
    string upperHorizName = "ZZ_TL_UpperHoriz";
    string lowerHorizName = "ZZ_TL_LowerHoriz";
    
    // Проверяем, существуют ли горизонтальные линии
    if(ObjectFind(0, upperHorizName) < 0 || ObjectFind(0, lowerHorizName) < 0)
    {
        Print("DrawRetraceLines: горизонтальные трендовые линии не найдены");
        return;
    }
    
    // Получаем координаты верхней горизонтальной линии
    datetime upperTime1 = (datetime)ObjectGetInteger(0, upperHorizName, OBJPROP_TIME, 0);
    datetime upperTime2 = (datetime)ObjectGetInteger(0, upperHorizName, OBJPROP_TIME, 1);
    double upperPrice = ObjectGetDouble(0, upperHorizName, OBJPROP_PRICE, 0);
    
    // Получаем координаты нижней горизонтальной линии
    datetime lowerTime1 = (datetime)ObjectGetInteger(0, lowerHorizName, OBJPROP_TIME, 0);
    datetime lowerTime2 = (datetime)ObjectGetInteger(0, lowerHorizName, OBJPROP_TIME, 1);
    double lowerPrice = ObjectGetDouble(0, lowerHorizName, OBJPROP_PRICE, 0);
    
    // РАССЧИТЫВАЕМ ШИРИНУ (то, что нам нужно сейчас)
    double shift = myRetracePips * _Point;
    Print("myRetracePips = ", myRetracePips);
    Print("_Point = ", _Point);
    Print("shift = ", DoubleToString(shift, _Digits));
    
    // Правильное направление: ВНУТРЬ канала
    double upperRetracePrice = upperPrice - shift;  // ВНИЗ от верхней линии
    double lowerRetracePrice = lowerPrice + shift;  // ВВЕРХ от нижней линии
    
    Print("upperPrice = ", DoubleToString(upperPrice, _Digits));
    Print("upperRetracePrice = ", DoubleToString(upperRetracePrice, _Digits));
    Print("lowerPrice = ", DoubleToString(lowerPrice, _Digits));
    Print("lowerRetracePrice = ", DoubleToString(lowerRetracePrice, _Digits));
    
    // Имена объектов
    string upperRetraceName = "Retrace_Upper";
    string lowerRetraceName = "Retrace_Lower";
    
    // Удаляем старые линии
    ObjectDelete(0, upperRetraceName);
    ObjectDelete(0, lowerRetraceName);
    
    // ВРЕМЕННО используем простые координаты для теста ширины
    datetime startTime = TimeCurrent() - 30 * 86400; // 30 дней назад
    datetime endTime = TimeCurrent();                 // сейчас
    
    // СОЗДАЕМ ВЕРХНЮЮ ЛИНИЮ
    if(ObjectCreate(0, upperRetraceName, OBJ_TREND, 0, startTime, upperRetracePrice, endTime, upperRetracePrice))
    {
        ObjectSetInteger(0, upperRetraceName, OBJPROP_COLOR, myRetraceLineColor);
        ObjectSetInteger(0, upperRetraceName, OBJPROP_STYLE, myRetraceLineStyle);
        ObjectSetInteger(0, upperRetraceName, OBJPROP_WIDTH, myRetraceLineWidth);
        ObjectSetInteger(0, upperRetraceName, OBJPROP_RAY_RIGHT, false);
        Print("✓ Верхняя линия создана с ценой ", DoubleToString(upperRetracePrice, _Digits));
    }
    else
    {
        Print("✗ Ошибка создания верхней линии: ", GetLastError());
    }
    
    // СОЗДАЕМ НИЖНЮЮ ЛИНИЮ
    if(ObjectCreate(0, lowerRetraceName, OBJ_TREND, 0, startTime, lowerRetracePrice, endTime, lowerRetracePrice))
    {
        ObjectSetInteger(0, lowerRetraceName, OBJPROP_COLOR, myRetraceLineColor);
        ObjectSetInteger(0, lowerRetraceName, OBJPROP_STYLE, myRetraceLineStyle);
        ObjectSetInteger(0, lowerRetraceName, OBJPROP_WIDTH, myRetraceLineWidth);
        ObjectSetInteger(0, lowerRetraceName, OBJPROP_RAY_RIGHT, false);
        Print("✓ Нижняя линия создана с ценой ", DoubleToString(lowerRetracePrice, _Digits));
    }
    else
    {
        Print("✗ Ошибка создания нижней линии: ", GetLastError());
    }
    
    // ПРОВЕРКА
    double testDistance = MathAbs(upperPrice - upperRetracePrice);
    Print("Расстояние от верхней линии до отката: ", DoubleToString(testDistance, _Digits), " (", testDistance / _Point, " пипс)");
    
    testDistance = MathAbs(lowerPrice - lowerRetracePrice);
    Print("Расстояние от нижней линии до отката: ", DoubleToString(testDistance, _Digits), " (", testDistance / _Point, " пипс)");
}