Индикатор на основе индикатора tradingview.com "Кривая линейной регрессии"

Работа завершена

Время выполнения 3 дня
Отзыв от заказчика
Блестящая работа, точно по спецификации!
Отзыв от исполнителя
Понятное ТЗ - отличный результат, всё закономерно. Приятно было поработать с Артёмом. Надеюсь на дальнейшее сотрудничество.

Техническое задание




Есть вот такой индикатор "Кривая линейной регрессии" для сайта tradingview.com:


Его исходный код:

//@version=4

study("LR Breakthrough Alert", shorttitle="LR Br. Alert", overlay=true)


upperMult = input(title="Upper Deviation", defval=2)

lowerMult = input(title="Lower Deviation", defval=-2)


useUpperDev = input(title="Use Upper Deviation", defval=true)

useLowerDev = input(title="Use Lower Deviation", defval=true)

showPearson = input(title="Show Pearson's R", defval=true)

extendLines = input(title="Extend Lines", defval=false)


len = input(title="Count", defval=100)

src = input(title="Source", defval=close)


extend = extendLines ? extend.right : extend.none


calcSlope(src, len) =>

    if not barstate.islast or len <= 1

        [float(na), float(na), float(na)]

    else

        sumX = 0.0

        sumY = 0.0

        sumXSqr = 0.0

        sumXY = 0.0

        for i = 0 to len - 1

            val = src[i]

            per = i + 1.0

            sumX := sumX + per

            sumY := sumY + val

            sumXSqr := sumXSqr + per * per

            sumXY := sumXY + val * per

        slope = (len * sumXY - sumX * sumY) / (len * sumXSqr - sumX * sumX)

        average = sumY / len

        intercept = average - slope * sumX / len + slope

        [slope, average, intercept]


[s, a, i] = calcSlope(src, len)


startPrice = i + s * (len - 1)

endPrice = i

var line baseLine = na


if na(baseLine) and not na(startPrice)

    baseLine := line.new(bar_index - len + 1, startPrice, bar_index, endPrice, width=1, extend=extend, color=color.red)

else

    line.set_xy1(baseLine, bar_index - len + 1, startPrice)

    line.set_xy2(baseLine, bar_index, endPrice)

    na


calcDev(src, len, slope, average, intercept) =>

    upDev = 0.0

    dnDev = 0.0

    stdDevAcc = 0.0

    dsxx = 0.0

    dsyy = 0.0

    dsxy = 0.0

    

    periods = len - 1


    daY = intercept + (slope * periods) / 2

    val = intercept

    

    for i = 0 to periods

        price = high[i] - val

        if (price > upDev)

            upDev := price


        price := val - low[i]

        if (price > dnDev)

            dnDev := price


        price := src[i]

        dxt = price - average

        dyt = val - daY

        

        price := price - val

        stdDevAcc := stdDevAcc + price * price

        dsxx := dsxx + dxt * dxt

        dsyy := dsyy + dyt * dyt

        dsxy := dsxy + dxt * dyt

        val := val + slope

    

    stdDev = sqrt(stdDevAcc / (periods == 0 ? 1 : periods))

    pearsonR = dsxx == 0 or dsyy == 0 ? 0 : dsxy / sqrt(dsxx * dsyy)

    [stdDev, pearsonR, upDev, dnDev]


[stdDev, pearsonR, upDev, dnDev] = calcDev(src, len, s, a, i)


upperStartPrice = startPrice + (useUpperDev ? upperMult * stdDev : upDev)

upperEndPrice = endPrice + (useUpperDev ? upperMult * stdDev : upDev)

var line upper = na


lowerStartPrice = startPrice + (useLowerDev ? lowerMult * stdDev : -dnDev)

lowerEndPrice = endPrice + (useLowerDev ? lowerMult * stdDev : -dnDev)

var line lower = na


if na(upper) and not na(upperStartPrice)

    upper := line.new(bar_index - len + 1, upperStartPrice, bar_index, upperEndPrice, width=1, extend=extend, color=#0000ff)

else

    line.set_xy1(upper, bar_index - len + 1, upperStartPrice)

    line.set_xy2(upper, bar_index, upperEndPrice)

    na


if na(lower) and not na(lowerStartPrice)

    lower := line.new(bar_index - len + 1, lowerStartPrice, bar_index, lowerEndPrice, width=1, extend=extend, color=#0000ff)

else

    line.set_xy1(lower, bar_index - len + 1, lowerStartPrice)

    line.set_xy2(lower, bar_index, lowerEndPrice)

    na


Нужно написать такой же для MQ4.

Вот есть текущие наработки по нему на языке MQ4, но неправильно рисует:

#property strict

//--- input parameters

input int      len=100;

input bool     useUpperDev=true;

input bool     useLowerDev=true;

input bool     showPearson=true;

input bool     extendLines=false;

//--- indicator buffers

double         Label1Buffer[];


int OnInit() {

//--- indicator buffers mapping

   SetIndexBuffer(0,Label1Buffer);

   return(INIT_SUCCEEDED);

}


void calcDev(double &src[], int len, double slope, double average, double intercept, double &result[]) {

   double upDev = 0.0;

   double dnDev = 0.0;

   double stdDevAcc = 0.0;

   double dsxx = 0.0;

   double dsyy = 0.0;

   double dsxy = 0.0;

   

   int periods = len - 1;

   

   double daY = intercept + (slope * periods) / 2;

   double val = intercept;

   

   for (int i = 0; i <= periods; i++) {

      double price = iHigh(NULL, 0, i) - val;

      if (price > upDev) {

         upDev = price;

      }

   

      price = val - iLow(NULL, 0, i);

      if (price > dnDev) {

         dnDev = price;

      }

   

      price = iClose(NULL, 0, i);

      double dxt = price - average;

      double dyt = val - daY;

     

      price = price - val;

      stdDevAcc = stdDevAcc + price * price;

      dsxx = dsxx + dxt * dxt;

      dsyy = dsyy + dyt * dyt;

      dsxy = dsxy + dxt * dyt;

      val = val + slope;

   }

   

   double stdDev = sqrt(stdDevAcc / (periods == 0 ? 1 : periods));

   double pearsonR = (dsxx == 0 || dsyy == 0 ? 0 : dsxy / sqrt(dsxx * dsyy));

   

   result[0] = stdDev;

   result[1] = pearsonR;

   result[2] = upDev;

   result[3] = dnDev;

}


void calcSlope(int len, double &result[]) {

   double sumX = 0.0;

   double sumY = 0.0;

   double sumXSqr = 0.0;

   double sumXY = 0.0;

   //for (int i = 0; i < len-1; i++) {

   for (int i = len-1; i > 0; i--) {

      double val = iClose(NULL, 0, i);

      double per = i + 1.0;

      sumX = sumX + per;

      sumY = sumY + val;

      sumXSqr = sumXSqr + per * per;

      sumXY = sumXY + val * per;

   }

   double slope = (len * sumXY - sumX * sumY) / (len * sumXSqr - sumX * sumX);

   double average = sumY / (len);

   double intercept = average - slope * sumX / len + slope;

   

   result[0] = slope;

   result[1] = average;

   result[2] = intercept;

}


int OnCalculate(const int rates_total,

                const int prev_calculated,

                const datetime &time[],

                const double &open[],

                const double &high[],

                const double &low[],

                const double &close[],

                const long &tick_volume[],

                const long &volume[],

                const int &spread[]) {

   double calcSlopeResults[3];

   double calcDevResults[4];

   

   calcSlope(len, calcSlopeResults);

   double s = calcSlopeResults[0];

   double a = calcSlopeResults[1];

   double i = calcSlopeResults[2];

   

   double startPrice = i + s * (len - 1);

   double endPrice = i;

   

   //baseLine := line.new(bar_index - len + 1, startPrice, bar_index, endPrice, width=1, extend=extend, color=color.red)

   ObjectDelete(0, "LR Base Line");

   datetime time1 = iTime(NULL, NULL, 1);

   datetime time2 = iTime(NULL, NULL, len);

   // Рисуем base line (должна быть посередине канала):

   if (!ObjectCreate(0, "LR Base Line", OBJ_TREND, 0, time1, startPrice, time2, endPrice)) { 

      Print(__FUNCTION__, ": не удалось создать линию. Код ошибки = ", GetLastError());

      return(false);

   }

   ObjectSetInteger(0, "LR Base Line", OBJPROP_RAY_RIGHT, false); 

   Print("time1: " + time1 + "; time2: " + time2 + "; startPrice: " + startPrice + "; endPrice: " + endPrice);


   return(rates_total);

}



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

Чтобы проверить правильность работы индикатора, нужно в tradingview.com открыть график любой валютной пары, нажать кнопку «индикаторы» и добавить индикатор «Кривая линейной регрессии».


Откликнулись

1
Разработчик 1
Оценка
(172)
Проекты
186
32%
Арбитраж
5
60% / 20%
Просрочено
3
2%
Свободен
Опубликовал: 3 примера
Похожие заказы
Начало с двойного (считается нулевым), на следующем шаге сетки в любую сторону закрывается профитный ордер и открывается новая пара; таким образом: либо с одного края сетки, либо с двух всегда остаётся двойной ордер; при перевороте позиций открывается тройной ордер одинакового объёма (два ордера в сторону тренда и один в обратную) : расстояние профитов рассчитывается от крайнего двойного (против тренда), а после
Нужно создать торговый советник для МТ5 для автоматической торговли золотом, серебром и нефти, газа. Торговля будет происходить на основании данных индикаторов, корреляции данных инструментов. Должна быть панель управления с настройками на английском языке

Информация о проекте

Бюджет
30 - 56 USD