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

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

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

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

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

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

function Initialize()
{
/////другие параметры
 AddParameter("NaprTrenda",0);      // Направление движения цены 0- нет; 1-лонг; 2-шорт;  (переменная для робота)
 AddParameter("PowerTrenda",0);      // Сила тренда, коррекция
 AddParameter("StopExst",0,0);      //Значение экстремума для выставления стопа (либо рассчетный или экстремум, что оптимальней?)
}

function Evaluate()
{
//-//-//создание массива и обработка данных
//-//-//
 //1 Сравниваем последние значения цены, колличество сравнений заданно переменной "NRepetition", определяем направление тренд переменная "NaprTrenda"
 //2 Определим последнее значение хай или лоу, поределяем силу тренда "PowerTrenda"
 //3 По данным направления и силе тренда - определяем точку входа (цена входа).
 //3.1 Смена направления в сторону тренда (данная свеча неявляется внутренней)
 //3.2 Процент коррекции составляет неболее %, задаём в переменной "CorrectionPercentage"
 //3.3 Значение экстремума для выставления стопа (либо рассчетный или экстремум, что оптимальней выставляем в //роботе) переменная "StopExst"
 
   int Repetition = (int)(NRepetition);
    if (Repetition>1)// Обязательная проверка, число повторов тренда больше 1 иначе воизбежании ошибки записываем 1
      { //NaprTrenda=0; //первоначальный сброс значения тренда
         for (var i=Repetition; i>0; i--)
          {
             var RepetitionHigh=0;
            var RepetitionLow=0;
            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];                                 //данные для вывода в робот
      }
   }
}

Возможно задавать надо переменные как

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

AddSeries();

Подскажите как правильней передать данные в робота.
Заранее спасибо!

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

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

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

Да, в стратегии прочитать можно только серии. т. е. AddSeries() - правильно.
никогда такого не было и вот опять

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

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

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

Спасибо!

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

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

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

Добрый день evge! Вы сможете сбросить пример вывода данных в робот, желательно простенький без лишних алгоритмов. Пробую уже два дня не получается. пример прогнал в Microsoft Visual Studio c#, всё работает, а робот позиции не открывает ни одной за период 20 000 баров, на 5 минутке? может конечно проблема в роботе.

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

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

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

}


в индикаторе поменял

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

 AddSeries("PointInput");   // Выводим значение предпологаемой переменной цены покупки (переменная для робота)
 AddSeries("NaprTrenda");      // Направление движения цены 0- нет; 1-лонг; 2-шорт;  (переменная для робота)
 AddSeries("PowerTrenda");      // Сила тренда, коррекция
 AddSeries("StopExst");      //Значение экстремума для выставления стопа (либо рассчетный или экстремум, что

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

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

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

если покажите мне индикатор (код стратегии уже есть), тогда поищу ошибку иначе смогу только догадываться :)
никогда такого не было и вот опять

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

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

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

Можно обращаться к серии и так

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

var ww = MY.WolfeWave(Input1, 326, 1);
var wwNT = ww["NaprTrenda"];


теперь в wwNT[0..x] можно получать значения со смещением

можно и сразу

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

var wwNT = MY.WolfeWave(Input1, 326, 1)["NaprTrenda"];


это вместо .GetValue("NaprTrenda", 1) - получить 1 значение со мщением 1 (или др.)
никогда такого не было и вот опять

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

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

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

Полностью код индикатора не закончен, он планировался как
1. Торговля по зигзагу "стратегия Рязвякова" ;
2. Определение волны по "Герчику" используя понятие внутренней свечи;
3. И дополнительно используя понятия волны Вулфа - определяя предположительно величину коррекции и завершения волны
Третья часть ещё не реализована
код на данный момент

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

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;
         }
 // Данные графика заданы
/////////////////////////////////
 
 //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 » 07 фев 2017, 14:31

У Вас 2 правила в стратегии (код которой разметили выше)

Первое правило открывает Long
Второе правило закрывает Short

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

может ошибка в этом?

В стратегии явно ошибка.
никогда такого не было и вот опять

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

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

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

Евгений просто код робота ещё не прописан полностью в робота планируется:
1.Открытие позиции по правилу:
1.1 Для лонга (шорт зеркально) - повышающихся максимумов и минимумов их число будет задаваться в стратеги робота (переменная NRepetition);
1.2 Величина коррекции по стратегии будет сравниваться (расчёты коррекции PowerTrenda в индикаторе)<(коррекции заданной переменной PowerTrenda в роботе). Переменные назвал одинакова в роботе и индикаторе, что бы не запутаться. считается, что сели коррекция больше 50% то сделку лучше не открывать.
2. Выставление стопа. Есть два вида стопа:
2.1 Расчётный по журналу Резвякова или не более 2% от стоимости контракта
2.2 Выставление стопа за экстремум
Правильней брать эти два стопа и сравнивать в пользоваться более наименьшим реализация будет сделана в роботе, пока её нет.
3. Перенос стопа будет реализован в двух вариантах:
3.1 Перенос в зону безубытка при увеличении счёта на 2-3% и выставлении защелки переноса в безубыток,а то первый мой робот переставлял безубыток каждые 5 минут на 5М ;
3.2 Перенос стопа при достижении цели (6-12% в зависимости от торгуемого инструмента ) под ближайший экстремум. Как показывает практика с роботами цель достигается,а цена летит дальше и теряется большая часть прибыли) это конечно не очень часто но бывает.
4. Закрытие позиции:
4.1 При развороте тренда
4.2 Закрытие позиции и останов робота.
Цел робота многодневная торговля!

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

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

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

Неработает из-за

CurrentIndex == MaxIndex в индикаторе.

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

А затем идёт смотреть значения для каждой точки ряда, а она заполнена только последняя, все предыдущие значения пусты, т.к. для каждого OnUpdate не производится отдельного вызова индикаторов.

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

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

    if (CurrentIndex == MaxIndex)


то стратегия будет работать, но при этом её надо поправить, у Вас там несколько ошибок.

Индикатор же будет отображаться некрасиво.
никогда такого не было и вот опять


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

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

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