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

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

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

Непрочитанное сообщение Владимир » 19 мар 2017, 21:28

Последний вариант индикатора, хотел написать индикатор совмещённый с Вульфа но появилось сомнение в его необходимости!

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

function Initialize()
{
//Indicator V2.4
//Владимир
// Область определения параметров индикатора
// Обязательные параметры:
   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", 1);   // Колличество повторений тренда
 //AddParameter("NTeste", 2);         // Колличество повторных входов
 AddSeries("PointInput");   // Выводим значение предпологаемой переменной цены покупки (переменная для робота) //AddParameter("PointInput",  0.0);
 AddSeries("NaprTrenda");      // Направление движения цены 0- нет; 1-лонг; 2-шорт;  (переменная для робота)//AddParameter("NaprTrenda",0);
 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; b++)
           { if (Buf_Low[b]>0)
             MarkerLow[Buf_time_Low[b]]=Buf_Low[b];
           }      // Данные для построения меток хаёв
           for (var c=0; c<XhiPostr; 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;
         }
 // Данные графика заданы
/////////////////////////////////
 
   }// OFF if ((MaxIndex - CurrentIndex) > Scan) return;
}//  OFF if (CurrentIndex == MaxIndex)
 //1 Сравниваем последние значения цены, колличество сравнений заданно переменной "NRepetition", определяем направление тренд переменная "NaprTrenda"
 //2 Определим последнее значение хай или лоу, поределяем силу тренда "PowerTrenda"
 //3 По данным направления и силе тренда - определяем точку входа (цена входа).
 //3.1 Смена направления в сторону тренда (данная свеча неявляется внутренней)
 //3.2 Процент коррекции составляет неболее %, задаём в переменной "CorrectionPercentage"
 //3.3 Значение экстремума для выставления стопа (либо рассчетный или экстремум, что оптимальней выставляем в //роботе) переменная "StopExst"
 
                             
    NaprTrenda=0; //первоначальный сброс значения тренда
   int Repetition = (int)(NRepetition);
   if (Repetition>1)// Обязательная проверка, число повторов тренда больше 2 иначе воизбежании ошибки записываем 2
      {
         for (var i=Repetition-1; 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-1)
                  {
               //   LogData ("-1-  high[0] "  + Convert.ToString(Buf_High[i-1]) + " >  high[1] "   + Convert.ToString(Buf_High[i]) + "// low[0] " + Convert.ToString(Buf_Low[i-1]) + "> low[1] " + Convert.ToString(Buf_Low[i]) , IndicatorName);
                     if (Buf_Low[0]< Input.Close[0] ) //проверка нарушения патерна, цена ушла ниже лоу
                     {
                        if ((Buf_time_Low[0]<Buf_time_High[0]) && (Buf_time_Low[0]<4))
                        {   //последний лоу //направление лонг
                         NaprTrenda=1;
                        PowerTrenda=(1-((Buf_High[0]-Buf_Low[0])/(Buf_High[0]-Buf_Low[1])))*100;
                        StopExst=Buf_Low[0];
                        }
                     }
                     else
                     {if (NaprTrenda==1)//заглушка повторов
                     {NaprTrenda=0; //патерн нарушен
                     LogData ("Патерн лонговой модели нарушен, сброс тренда //PowerTrenda=0)" , IndicatorName);
                     }}
                  }   
               }
               
            if (Buf_High[i-1]<Buf_High[i] && Buf_Low[i-1]<Buf_Low[i])
                {RepetitionLow++;
               if (RepetitionLow==Repetition-1)
                  {
                  //LogData ("-2-  high[0] "  + Convert.ToString(Buf_High[i-1]) + " <  high[i] "   + Convert.ToString(Buf_High[i]) + "// low[0] " + Convert.ToString(Buf_Low[i-1]) + "< low[1] " + Convert.ToString(Buf_Low[i]) , IndicatorName);
                  if (Buf_High[0]>Input.Close[0])  //проверка нарушения патерна, цена ушла выше хая
                     {
                        if ((Buf_time_Low[0]>Buf_time_High[0]) && (Buf_time_High[0]<4))
                        {   //последний хай //направление шорт
                        NaprTrenda=2;
                        PowerTrenda=(1-((Buf_High[0]-Buf_Low[0])/(Buf_High[1]-Buf_Low[0])))*100;
                        StopExst=Buf_High[0];
                        }
                     }
                     else
                     {if (NaprTrenda==2)//заглушка повторов
                     {NaprTrenda=0; //патерн нарушен
                     LogData ("Патерн шартовой модели нарушен, сброс тренда //PowerTrenda=0)" , IndicatorName);
                     }}
                  
                  }
                }
         } //закрытие for (var i=Repetition-1; i>0; i--)
      }
      else
      { Repetition=2;}
//выводим общий отчёт         
if (NaprTrenda!=0)
   {   LogData ("О//NaprTrenda - " + Convert.ToString(NaprTrenda) + "// PowerTrenda - " + Convert.ToString(PowerTrenda) + "// StopExst - " + Convert.ToString(StopExst) , IndicatorName);
   }

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

Код одного из роботов (У него выставление стопа происходит на следующей свече после открытия позиции. Причина такого выставления определение какой стоп использовать из индикатора или расчетный)

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

/**Версия робота IndTrenda_v2.3
Создаём переменные как в индикаторе
1 - в переменной "NRepetition" задаём число повторяющихся экстремумов (передаём в индикатор)
2 - в переменной "PowerTrenda" задаём минимальное значение коррекции волни в %
3 - в переменная "StopExst" выводит значение экстремума для выставление стопа технического или рассчётного стопа
4 - переменная "NaprTrenda" задаёт направление входа: 0- нет направления, 1 -  лонг, 2 - шорт
5 - переменная "Rstop" значение стопа
6 - переменная "RPbu"  размер при котором разрешён перенос в безубыток
7 - переменная "Tp", 0.6, "Тейк профи %"
8 - переменная "Maxub", -90, максимальная просадка счёта в рублях
9 - переменная "Istop" разрешение выставления заявки на перенос стопа в безубыток
   (0 - безубыток (stop loss + take profit), 1 - стоп)
10 - в переменной "AccelerationSlowdown" задаём минимальное значение ускорения замедления
Открытие позиции:
Лонг/Шорт
1. Переменная:
    "NaprTrenda"= 1 -  лонг последние максимумы и минимумы повышающихся
    "NaprTrenda"= 2 -  шорт последние максимумы и минимумы понижаются
2. Сила тренда по индикатору переменная "PowerTrenda">=50% (характер тренда по Рязвякову)
3. Определяем динамику рынка ускоряется или замедляется (размах волны) "AccelerationSlowdown"
Developed by Владимир;
Algorithm = ТРЕНД;**/

function Initialize()
{
   StrategyName = "IndTrenda_v2.3";
   AddParameter("NRepetition", 2, "", 1);
   AddParameter("PowerTrenda", 50, "", 1);
   AddParameter("StopExst", 0, "", 1);
   AddParameter("Rstop", 0.12, "Размер стопа", 1);
   AddParameter("RPbu", 0.15, "Разрешение переноса в безубыток", 1);
   AddParameter("stop_lossl", -0.01, "Размер безубытка, сдвиг учётной цены %", 1);
   AddParameter("Tp", 1.0, "Тейк профи %", 1);
   AddParameter("Maxub", -90, "Максимальная просадка счёта в рублях", 1);
   AddGlobalVariable("Istop", Types.Int, 0);
   /* Выставление заявки:
    0 - нет позиции или выставили stop loss + take profit
    1 - открыта позиция в лонг;
    2 - открыта позиция в шорт;
    3 - стоп заявка выставленна
     */
   AddInput("Input1", Inputs.Candle, 5, true, "MMH7=ФОРТС");
   LongLimit = 1;
   ShortLimit = -1;
   AddChartIndicator("MY.WolfeWave", new Dictionary <string, double>{{"Scan", 326},{"NRepetition", 2}});
   AddChartIndicator("SMA", new Dictionary <string, double>{{"Period", 163}});
}

function OnUpdate()
{
   /// Лонг
   if ( (MY.WolfeWave(Input1, 326, NRepetition).GetValue("NaprTrenda", 0) == 1) && (MY.WolfeWave(Input1, 326, NRepetition).GetValue("PowerTrenda", 0) >= PowerTrenda) && Input1.Close[0]>StopExst )
   {
      //Выставляю лимитную заявку на 5 пунктов выше чем лучшая заявка   
   EnterLongLimit(GetBid()+ 5* GetPriceStep());
   //   StopLoss(0.1, SignalPriceType.DeltaInPercentFromAveragePrice);
      Istop=1;  //выставление стоп заявки
      LogData ("EnterLong = "  + Convert.ToString(GetBid()+ 5* GetPriceStep()),Name);
      
   }

   /// Шорт
   if ( (MY.WolfeWave(Input1, 326, NRepetition).GetValue("NaprTrenda", 0) == 2) && (MY.WolfeWave(Input1, 326, NRepetition).GetValue("PowerTrenda", 0) >= PowerTrenda) && Input1.Close[0]<StopExst)
   {
      //выставляю лимитную заявку на 5 пунктов выше чем лучшая заявка EnterShortLimit(GetAsk())
   EnterShortLimit(GetAsk()+ 5* GetPriceStep());
   //   StopLoss(0.1, SignalPriceType.DeltaInPercentFromAveragePrice);
      Istop=2;  //выставление стоп заявки
      LogData ("EnterShort = "  + Convert.ToString(GetAsk()- 5* GetPriceStep()),Name);
   }
if (CurrentPosition()>0) //если позиция лонг открыта выставляем стопы
 {   
   //Выставляем стоп по лонг
   if (StopExst>(AverPrice()-AverPrice()/100*Rstop) && (Istop==1))
      {Istop=3;  //выставление стоп заявки
      StopLoss((AverPrice()-StopExst), SignalPriceType.DeltaFromAveragePrice);
      LogData ("EnterLong = "  + Convert.ToString(AverPrice()) + " стоп по лоу = "  + Convert.ToString(StopExst),Name);
      }
      else
      {
      Istop=3;  //выставление стоп заявки
      StopLoss(Rstop, SignalPriceType.DeltaInPercentFromAveragePrice);
      LogData ("EnterLong = "  + Convert.ToString(AverPrice()) + " стоп по % = "  + Convert.ToString(AverPrice()-AverPrice()/100*Rstop),Name);
      }
} // закрыли скобку if (CurrentPosition()>0) //если позиция лонг открыта выставляем стопы

if (CurrentPosition()<0) //если позиция шорт открыта выставляем стопы
      //Выставляем стоп по шорт
   if (StopExst<(AverPrice()+AverPrice()/100*Rstop) && (Istop==2))
      {Istop=3;  //выставление стоп заявки
      StopLoss((StopExst-AverPrice()), SignalPriceType.DeltaFromAveragePrice);
      LogData ("EnterShort = "  + Convert.ToString(AverPrice()) + " стоп по хай = "  + Convert.ToString(StopExst),Name);
      }
      else
      {Istop=3;  //выставление стоп заявки
      StopLoss(Rstop, SignalPriceType.DeltaInPercentFromAveragePrice);
      LogData ("EnterShort = "  + Convert.ToString(AverPrice()) + " стоп по % = "  + Convert.ToString(AverPrice()+AverPrice()/100*Rstop),Name);
      }
   
   /// Перенос в безубыток + Тейк профи
   if ( (CurrentPLper() > RPbu) && (CurrentPosition() != 0) && (Istop==3))
   {
      CancelStopLoss();
      //StopLoss(stop_lossl, SignalPriceType.DeltaFromAveragePrice);
      BreakingStop(stop_lossl, Tp, SignalPriceType.DeltaInPercentFromAveragePrice);
   Istop=0; //Выставили stop loss + take profit
   }

   /// Тейк профи
   //if ( (CurrentPLper() > Tp) )
   //{
   //   ClosePosition();
   //}

   /// Закрытие по максимальному убытку
   if ( (RealizedPL() < Maxub) && (CurrentPosition() != 0) )
   {
      ClosePosition();
      Stop();
      PlaySound(InnerSystemSounds.Exclamation);
   }
}




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

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

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