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

Общие вопросы по разработке в Альфа-Директ 4. Обсуждение разработки пользовательских индикаторов, стратегий.
Аватара пользователя
evge
Администратор
Сообщения: 1652
Зарегистрирован: 04 фев 2016, 09:46
Откуда: Млечный путь, планета Земля
Благодарил (а): 64 раза
Поблагодарили: 303 раза
Контактная информация:

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

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

Владимир писал(а):Закомментировал не получается только на графике результат поменялся. всего скорей в массив данные нулевые попадают


У меня исправленная стратегия + индикатор с комментарием выдавала 3 сделки на 2000 барах.
никогда такого не было и вот опять

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

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

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

Добрый день! А на каком инструменте и таймфрейме?

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

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

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

Владимир писал(а):Добрый день! А на каком инструменте и таймфрейме?


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

   AddInput("Input1", Inputs.Candle, 5, true, "RIH7=ФОРТС");


т.е. я ничего не менял, инструмент RIH7, M5
никогда такого не было и вот опять

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

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

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

Добрый день! Евгений сбросьте пожалуйста свой вариант исправлений, а то как не пробую все равно не получается!

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

/**
Открытие позиции происходит по изгзагу
Developed by Владимир;
Algorithm = ТРЕНД;
Hash code 6504115CF5A6D848004B9BFB42169CE8
**/
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.WolfeWave(Input1, 326, 1).GetValue("NaprTrenda", 0) == 1) )
   {
      EnterLong();
      StopLoss(0.1, SignalPriceType.DeltaInPercentFromAveragePrice);
   }

   /// ПРАВИЛО 2
   if ( (MY.WolfeWave(Input1, 326, 1).GetValue("NaprTrenda", 0) == 2) )
   {
      EnterShort();
      StopLoss(0.1, SignalPriceType.DeltaInPercentFromAveragePrice);
   }

}

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

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");      //Значение экстремума для выставления стопа (либо рассчетный или экстремум, что оптимальней?)
 //пробуем хранить данные в глобальных переменных
 //AddGlobalVariable("NaprTrendaGlobalVariable", Types.Int, 0);
// AddGlobalVariable("PowerTrendaGlobalVariable", Types.Int, 0);
// AddGlobalVariable("High0GlobalVariable", Types.Double, 0.0);
// AddGlobalVariable("High1GlobalVariable", Types.Double, 0.0);
// AddGlobalVariable("Low0GlobalVariable", Types.Double, 0.0);
// AddGlobalVariable("Low1GlobalVariable", Types.Double, 0.0);
 
}

function Evaluate()
{
    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;      // Переменная начало данных в массиве для обработки и построения лоу

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)
{
    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 && HighX>0)    // Смена направления с лонга в шорт
            {
              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 && XLowN>0)    // Смена направления с шорта в лонг
            {
              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);
}



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

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

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

Код индикатора не изменен кроме комментария в строке

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

 //   if (CurrentIndex == MaxIndex)


стратегия

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

/**
Открытие позиции происходит по изгзагу
Developed by Владимир;
Algorithm = ТРЕНД;
Hash code C5EED5CD61D05F06DDE42A62A31EE3DA
**/
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.WolfeWave(Input1, 326, 1).GetValue("NaprTrenda", 0) == 1) && (MY.WolfeWave(Input1, 326, 2).GetValue("PowerTrenda", 0) >= PowerTrenda) )
   {
      EnterLong();
      StopLoss(0.1, SignalPriceType.DeltaInPercentFromAveragePrice);
   }

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

}


после тестирования в сигналах

IndTrenda-01.png
IndTrenda-01.png (17.11 КБ) 7524 просмотра
никогда такого не было и вот опять

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

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

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

Добрый день Евгений! Я просто думал у меня ошибка компилятора, оказалось ошибка всё таки в роботе, это хорошо! Большое спасибо!

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

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

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

НЕ хватало строки

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

AddChartIndicator("MY.WolfeWave", new Dictionary <string, double>{{"Scan", 326},{"NRepetition", 1}});

:lol:

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

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

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

Добрый день Евгений! Воспользовался вашим советом используя лог файл

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

LogData ("NaprTrenda - " + Convert.ToString(NaprTrenda) + "PowerTrenda - " + Convert.ToString(PowerTrenda) + "// StopExst - " + Convert.ToString(StopExst) , IndicatorName);

нашёл несколько ошибк в индикаторе, исправил заработало вот часть лога
2017.02.15 10:15:05.483 NaprTrenda=2
2017.02.15 10:15:05.483 NaprTrenda - 2PowerTrenda - 1,67652859960579// StopExst - 2151,6
2017.02.15 10:19:59.673 NaprTrenda=2
2017.02.15 10:19:59.673 NaprTrenda - 2PowerTrenda - 1,67652859960579// StopExst - 2151,6
2017.02.15 11:24:59.670 NaprTrenda=2

Только возник другой вопрос по роботам?
Робот открывает позицию с опаданием на 2 свечки (то есть сигнал поступает по закрытию свечи, попадает в робот, в роботе ждёт закрытия следующей следующей свечи и открывает позицию только на следующей) привожу скрин
1. Вопрос какими методами можно открыть позицию в любое время?
2. Работает ли эта функция и как? (UseClosedBar=false; //разрешение на открывание позиции внутри бара)
Вложения
14022017 10_35.jpg

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

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

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

Владимир писал(а): 1. Вопрос какими методами можно открыть позицию в любое время?

Он открывает позицию в тот момент, когда сработало условие. Индикатор просто рисует сигнал в истории (назад). Поэтому и кажется запаздывание робота, на самом деле он определил правильно момент.
Владимир писал(а): 2. Работает ли эта функция и как? (UseClosedBar=false; //разрешение на открывание позиции внутри бара)


Нет, открывать внутри бара можно по командам EnterLongLimit, EnterShortLimit, EnterLongStop, EnterShortStop. Но это всё равно произойдёт после сигнала, на следующем баре или на последующих барах (если цена не дошла на следующем до заданного уровня входа)
никогда такого не было и вот опять

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

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

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

Спасибо!


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

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

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