Общие вопросы по разработке > Как получить данные из индикатора в робот

Общие вопросы по разработке в Альфа-Директ 4. Обсуждение разработки пользовательских индикаторов, стратегий.
Владимир
Сообщения: 84
Зарегистрирован: 14 ноя 2016, 02:17
Благодарил (а): 3 раза
Поблагодарили: 5 раз

Re: Как получить данные из индикатора в робот

Непрочитанное сообщение Владимир » 07 фев 2017, 15:21

Ошибок в индикаторе или в роботе?

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

Re: Как получить данные из индикатора в робот

Непрочитанное сообщение evge » 07 фев 2017, 15:27

Владимир писал(а):Ошибок в индикаторе или в роботе?


Ошибка 1. В индикаторе. Рисует только на последнем баре CurrentIndex == MaxIndex.
Ошибка 2. В стратегии: Правило 2. CloseShort(); Должно быть EnterShort();
Ошибка 3. В стратегии: Правило 1. StopLoss(0.1, SignalPriceType.Price); Должно быть StopLoss(0.1, SignalPriceType.DeltaInPercentFromAveragePrice);
Ошибка 4. В стратегии: Правило 1. MY.WolfeWave(Input1, 326, 2).GetValue("NaprTrenda", 0) >= PowerTrenda должно быть MY.WolfeWave(Input1, 326, 2).GetValue("PowerTrenda", 0) >= PowerTrenda
никогда такого не было и вот опять

Владимир
Сообщения: 84
Зарегистрирован: 14 ноя 2016, 02:17
Благодарил (а): 3 раза
Поблагодарили: 5 раз

Re: Как получить данные из индикатора в робот

Непрочитанное сообщение Владимир » 07 фев 2017, 15:40

Если я исправлю
Ошибка 1. В индикаторе. Рисует только на последнем баре CurrentIndex == MaxIndex.

то я столкнусь с проблемой рисования индикатора которую исправил пользуясь советом: viewtopic.php?f=27&t=193
Я думаю если этот код вынести за пределы

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

    if (CurrentIndex == MaxIndex){
    }

может вы и правы! Но одного раза, вызова при перерисовке индикатора, производить вычисления вполне достаточно для данной стратегии.
Вот другие ошибки да это надо исправлять немедленно. Спасибо! Буду думать дальше.

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

Re: Как получить данные из индикатора в робот

Непрочитанное сообщение evge » 07 фев 2017, 16:55

Вот так работают стратегии в АД4, на каждом OnUpdate() не выполняется повторно вызов индикаторов.
Стратегия просто читает значения в истории по рядам которые вы запрашиваете.
А индикатор у Вас рисует только на последнем баре свое значение для

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

 AddSeries("NaprTrenda");      // Направление движения цены 0- нет; 1-лонг; 2-шорт;  (переменная для робота)
 AddSeries("PowerTrenda");      // Сила тренда, коррекция


т.е. прочитать предыдущие значения для истории не сможет, поэтому тестирование и не работает. (проверял, сохраняя при тестировании стратегии значения ваших рядов в Log файл, где увидел что индикатор вызывался всего 4 раза вместо ожидаемых 2000*4)

Вот робот скорее всего работать будет (не проверял)
никогда такого не было и вот опять

Владимир
Сообщения: 84
Зарегистрирован: 14 ноя 2016, 02:17
Благодарил (а): 3 раза
Поблагодарили: 5 раз

Re: Как получить данные из индикатора в робот

Непрочитанное сообщение Владимир » 07 фев 2017, 17:13

Упростил задачу до минимума код робота

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

/**
Открытие позиции происходит по изгзагу
Developed by Владимир;
Algorithm = ТРЕНД;
Hash code 379EBD9768288E896EB42B93032447AE
**/
function Initialize()
{
   StrategyName = "IndTrenda";
   AddParameter("PowerTrenda", 5, "", 1);
   AddInput("Input1", Inputs.Candle, 5, true, "RIH7=ФОРТС");
   LongLimit = 1;
   ShortLimit = -1;
   //AddChartIndicator("MY.WolfeWave", new Dictionary <string, double>{{"Scan", 326},{"NRepetition", 1}});
}

function OnUpdate()
{
   /// ПРАВИЛО 1
   if ( (MY.Test(Input1, 163).GetValue("NaprTrenda", 0) == 1) && (MY.Test(Input1, 163).GetValue("PowerTrenda", 0) >= PowerTrenda) )
   {
      EnterLong();
      StopLoss(0.1, SignalPriceType.DeltaInPercentFromAveragePrice);
   }

   /// ПРАВИЛО 2
   if ( (MY.Test(Input1, 163).GetValue("NaprTrenda", 0) == 2) && (MY.Test(Input1, 163).GetValue("PowerTrenda", 0) >= PowerTrenda) )
   {
      EnterShort();
      StopLoss(0.1, SignalPriceType.DeltaInPercentFromAveragePrice);
   }
}

код индикатора

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

function Initialize()
{
// Область определения параметров индикатора
// Обязательные параметры:
   IndicatorName = "Test";   // Задайте название индикатора и сохраните с данным именем
   PriceStudy = true;   // Рисовать в области цены (true – да, false – нет)
   AddInput("Input", Inputs.Candle);   // Input - входной ряд (Inputs.Price) или свечи (Inputs.Candle)
// Дополнительные параметры:
 AddParameter("Scan", 163, 1); // сканируемый период
 AddSeries("NaprTrenda");      // Направление движения цены 0- нет; 1-лонг; 2-шорт;  (переменная для робота)
 AddSeries("PowerTrenda");      // Сила тренда, коррекция
 }

function Evaluate()
{
if (Input.Open[0]<Input.Close[2])
   {
   NaprTrenda=2;
   PowerTrenda=60;
   }
else
   {
   NaprTrenda=1;
   PowerTrenda=60;
   }

 }

работает открывает позицию и в лонг и шорт
может просто условия по рынку без тренда не подходят?
А может косяк в индикаторе буду индикатор ещё раз пересматривать.
А также искать трендовые движения на других инструментах.

Владимир
Сообщения: 84
Зарегистрирован: 14 ноя 2016, 02:17
Благодарил (а): 3 раза
Поблагодарили: 5 раз

Re: Как получить данные из индикатора в робот

Непрочитанное сообщение Владимир » 07 фев 2017, 17:17

Данный пример просто для понятия правильности направления передаются данные или нет.
Вложения
test робота.jpg
test робота.jpg (102.53 КБ) 20661 просмотр

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

Re: Как получить данные из индикатора в робот

Непрочитанное сообщение evge » 07 фев 2017, 17:20

Владимир писал(а):работает открывает позицию и в лонг и шорт


Это говорит что стратегия исправлена и работает, индикатор test работает, а индикатор WolfeWave нет.

В индикаторе test значения в серии подставляются на всей истории, в WolfeWave только в последней точке.

Убрав if (CurrentIndex == MaxIndex) в WolfeWave тоже заработает. Но сам индикатор на графике будет смотреться некрасиво.
никогда такого не было и вот опять

Владимир
Сообщения: 84
Зарегистрирован: 14 ноя 2016, 02:17
Благодарил (а): 3 раза
Поблагодарили: 5 раз

Re: Как получить данные из индикатора в робот

Непрочитанное сообщение Владимир » 07 фев 2017, 17:51

В индикаторе вынес за пределы if (CurrentIndex == MaxIndex){}

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

function Initialize()
{
// Область определения параметров индикатора
// Обязательные параметры:
   IndicatorName = "WolfeWave";   // Задайте название индикатора и сохраните с данным именем
   PriceStudy = true;   // Рисовать в области цены (true – да, false – нет)
   AddInput("Input", Inputs.Candle);   // Input - входной ряд (Inputs.Price) или свечи (Inputs.Candle)
   AddSeries("LineHigh", DrawAs.Custom, Color.Green);      // Задаем вид линии индикатора с именем LineHigh
   AddSeries("LineLow", DrawAs.Custom, Color.Red);         // Задаем вид линии индикатора с именем LineLow
   AddSeries("MarkerUp", DrawAs.Custom, Color.Red);         // Метим экстремум
   AddSeries("MarkerLow", DrawAs.Custom, Color.Yellow);      // Метим экстремум
  AddSeries("ChHigh", DrawAs.Custom, Color.Red, true, Axes.Parent);   //Рисуем канал внешней свечки для выделения внутренних свечей
  AddSeries("ChLow", DrawAs.Custom, Color.Red, true, Axes.Parent);   //ChHigh- верхняя линия, ChLow- нижняя линия канала

// Дополнительные параметры:
 AddParameter("Scan", 326, 1);      // Сканируемый период
 //AddParameter("имя переменной", период, множитель),  требующий размер истории 163 баров ( т.е. 163*1)
 AddParameter("NRepetition", 2);   // Колличество повторений тренда
 //AddParameter("NTeste", 2);         // Колличество повторных входов
 // Вывод данных
 AddSeries("PointInput");   // Выводим значение предпологаемой переменной цены покупки (переменная для робота)
 AddSeries("NaprTrenda");      // Направление движения цены 0- нет; 1-лонг; 2-шорт;  (переменная для робота)
 AddSeries("PowerTrenda");      // Сила тренда, коррекция
 AddSeries("StopExst");      //Значение экстремума для выставления стопа (либо рассчетный или экстремум, что оптимальней?)
}

function Evaluate()
{
int ExstremaNumber = (int)(Scan/5);  //Задаём колличество экстремумов
double [] Buf_High = new double[ExstremaNumber];   // Объявление массивов цен (под буферы индикатора)
double [] Buf_Low = new double[ExstremaNumber];      // Объявление массивов цен (под буферы индикатора)
int [] Buf_time_High = new int[ExstremaNumber];      // Объявление массивов время цены (под буферы индикатора)
int [] Buf_time_Low = new int[ExstremaNumber];      // Объявление массивов время цены (под буферы индикатора)

   if ((MaxIndex - CurrentIndex) > Scan) return;
   {
    if (CurrentIndex == MaxIndex)
{
    int IzNapr=0;      // Изменение направления  0- нет; 1-лонг; 2-шорт;
    int NaprHelp=1;      // Вспомогательный маркер изменения направления
    int Xx=Scan-1;      // переменная сравнения номер свечи
    int XHighN=Scan-1;   // Переменная хранения номера свечи хая для сравнения
    int XLowN=Scan-1;   // Переменная хранения номера свечи лоу для сравнения
    int XhiPostr=0;      // Переменная начало данных в массиве для обработки и построения хай
    int XloPostr=0;      // Переменная начало данных в массиве для обработки и построения лоу
    double HighX= Input.High[Scan];      // Переменная хранения значения хая для сравнения
    double LowX=Input.Low[Scan];      // Переменная хранения значения лоу для сравнения
    double High = Input.High[Scan];      // Переменная сравнения хая
    double Low = Input.Low[Scan];      // Переменная сравнения лоу
     
  for (var x= Scan-1; x>0; x--)
   {
 ///// При нормальных свечах
     if (Input.Open[x]<Input.Close[x]) // Проверяем закрытие свечи лонг шорт
        {// Лонг
          if (High<Input.Close[x])
          {   // Считаем, что произошло обновление High. Поэтому переписываея значения хая и лоу
          IzNapr=1;   //лонг
          High=Input.High[x];
          Low=Input.Low[x];
         Xx=x;      // Сохраняем значение для построения канала
          HighX=High;   // Сохраняем значение хая в памяти
          XHighN=x;      // Сохраняем значение в памяти
          }
      }
      else
          {// Шорт
           if (Low>Input.Close[x])
            { // Считаем, что произошло обновление low. Поэтому переписываея значения хая и лоу
             IzNapr=2;  //шорт
             High=Input.High[x];
             Low=Input.Low[x];
           Xx=x;      // Сохраняем значение для построения канала
             LowX=Low;   // Сохраняем значение лоу в памяти
             XLowN=x;   // Сохраняем значение в памяти
            }
           }
 ///// При формировании свечей с гепами
     if (Input.Open[x]>Input.Close[x]) //Проверяем закрытие свечи лонг шорт
        {// Лонг
          if (High<Input.Open[x])
          {   // Считаем, что произошло обновление High. Поэтому переписываея значения хая и лоу
          IzNapr=1;   //лонг
          High=Input.High[x];
          Low=Input.Low[x];
           Xx=x;      //Сохраняем значение для построения канала
          HighX=High;   //Сохраняем значение хая в памяти
          XHighN=x;      //Сохраняем значение в памяти
          }
      }
      else
          {// Шорт
           if (Low>Input.Open[x])
            { // Считаем, что произошло обновление low. Поэтому переписываея значения хая и лоу
             IzNapr=2;  //шорт
             High=Input.High[x];
             Low=Input.Low[x];
             Xx=x;      //Сохраняем значение для построения канала
              LowX=Low;   //Сохраняем значение лоу в памяти
              XLowN=x;   //Сохраняем значение в памяти
              }
           }

    // Заполняем буфер хаёв
            if (IzNapr==NaprHelp && IzNapr==2)    // Смена направления с лонга в шорт
            {
              for (var ch=ExstremaNumber-1; ch>0; ch--)
              {
               Buf_High[ch]=Buf_High[ch-1];
               Buf_time_High[ch]=Buf_time_High[ch-1];
               }
              Buf_High[0]=HighX;
              Buf_time_High[0]=XHighN;
              NaprHelp=1;
             }
   // Заполняем буфер лоёв
            if (IzNapr==NaprHelp && IzNapr==1)    // Смена направления с шорта в лонг
            {
              for (var Lo=ExstremaNumber-1; Lo>0; Lo--) 
              {
               Buf_Low[Lo]=Buf_Low[Lo-1];
                Buf_time_Low[Lo]=Buf_time_Low[Lo-1];
               }
              Buf_Low[0]=LowX;
              Buf_time_Low[0]=XLowN;
              NaprHelp=2;
             }
// Строим канал внешней свечи, для выделения внутренних свечей
  ChLow[Xx]= Low;
  ChLow[0]= Low;
  ChHigh[Xx]= High;
  ChHigh[0]= High;
ChLow.DrawChannel(ChHigh);
////////
   } // Закрытие цикла for

      //////// Ищем в массивах начало данных для обработки
        for(var a=ExstremaNumber-1; a>0; a--)
           {
           if (Buf_Low[a]>0 &&  XloPostr==0)
            {XloPostr= a;}
            if (Buf_High[a]>0 &&  XhiPostr==0)
           { XhiPostr= a;}
           }

     //////// Задаём данные для построения меток на графике  MarkerUp.DrawArrowDown(),MarkerLow.DrawArrowUp()
           for (var b=0; b<XloPostr+1; b++)
           { if (Buf_Low[b]>0)
             MarkerLow[Buf_time_Low[b]]=Buf_Low[b];
           }      // Данные для построения меток хаёв
           for (var c=0; c<XhiPostr+1; c++)
           {
            if(Buf_High[c]>0)
            MarkerUp[Buf_time_High[c]]=Buf_High[c];
           }   // Данные для построения меток лоёв

   ///////// Линия тренда        
         for(var i=0; i<ExstremaNumber-1; i++)
           {
         if ( Buf_Low[i]>0 &&  Buf_High[i]>0)
              {
            LineHigh[Buf_time_Low[i]]=Buf_Low[i];
            LineHigh[Buf_time_High[i]]=Buf_High[i];
              }
            }
   ///// Построение временной линии - предварительные хай и лоу!!!!!!!!
         if (IzNapr==1)// Задаём данные на построение предварительной вершины
         {LineLow[Buf_time_Low[0]]=Buf_Low[0];
          LineLow[Xx]=High;
         }
         if (IzNapr==2)// Задаём данные на построение предварительной впадины
         {LineLow[Buf_time_High[0]]=Buf_High[0];
          LineLow[Xx]=Low;
         }
 // Данные графика заданы
   }// Скобка (CurrentIndex == MaxIndex)
} // Скобка if ((MaxIndex - CurrentIndex) > Scan) return;
/////////////////////////////////
 
 //1 Сравниваем последние значения цены, колличество сравнений заданно переменной "NRepetition", определяем направление тренд переменная "NaprTrenda"
 //2 Определим последнее значение хай или лоу, поределяем силу тренда "PowerTrenda"
 //3 По данным направления и силе тренда - определяем точку входа (цена входа).
 //3.1 Смена направления в сторону тренда (данная свеча неявляется внутренней)
 //3.2 Процент коррекции составляет неболее %, задаём в переменной "CorrectionPercentage"
 //3.3 Значение экстремума для выставления стопа (либо рассчетный или экстремум, что оптимальней выставляем в //роботе) переменная "StopExst"
    NaprTrenda=0; //первоначальный сброс значения тренда
   int Repetition = (int)(NRepetition);
    if (Repetition>1)// Обязательная проверка, число повторов тренда больше 1 иначе воизбежании ошибки записываем 1
      { //NaprTrenda=0; //первоначальный сброс значения тренда
             var RepetitionHigh=0;
            var RepetitionLow=0;
            for (var i=Repetition; i>0; i--)
          {
            if ((Buf_High[i-1]>Buf_High[i]) && (Buf_Low[i-1]>Buf_Low[i]))
                {RepetitionHigh++;
               if (RepetitionHigh==Repetition)
               {NaprTrenda=1;}}
            if ((Buf_High[i-1]<Buf_High[i]) && (Buf_Low[i-1]<Buf_Low[i]))
                {RepetitionLow++;
               if (RepetitionLow==Repetition)
               {NaprTrenda=2;}}
          }
      }
      else
      { Repetition=1;}
 
   if (Buf_time_Low[0]>Buf_time_High[0])
   {   //последний хай //PowerTrenda
      if (NaprTrenda==2)
      {
      PowerTrenda=(1-((Buf_High[0]-Buf_Low[0])/(Buf_High[1]-Buf_Low[0])))*100;
      StopExst=Buf_High[0];
      }
   }
   else
   {   //последний лоу
       if (NaprTrenda==1)
      {
      PowerTrenda=(1-((Buf_High[0]-Buf_Low[0])/(Buf_High[0]-Buf_Low[1])))*100;
      StopExst=Buf_Low[0];
      }
   }
 ///////////////////////////////

// Выводим данные на график
MarkerUp.DrawArrowDown();
MarkerLow.DrawArrowUp();
LineHigh.DrawLine(Color.Green, Line.Solid, 2);
LineLow.DrawLine(Color.Red, Line.Solid, 2);
}



все равно не работает возможно данные из массивов теряются при выходе из if (CurrentIndex == MaxIndex)
буду побывать глобальные переменные вводить.

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

Re: Как получить данные из индикатора в робот

Непрочитанное сообщение evge » 07 фев 2017, 18:09

Не вижу.
Достаточно было закомментировать строку в индикаторе и всё

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

    if (CurrentIndex == MaxIndex)


так

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

    // if (CurrentIndex == MaxIndex)
никогда такого не было и вот опять

Владимир
Сообщения: 84
Зарегистрирован: 14 ноя 2016, 02:17
Благодарил (а): 3 раза
Поблагодарили: 5 раз

Re: Как получить данные из индикатора в робот

Непрочитанное сообщение Владимир » 07 фев 2017, 18:45

Закомментировал не получается только на графике результат поменялся. всего скорей в массив данные нулевые попадают
Вложения
test робота2.jpg


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

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

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