Страница 1 из 4
Как получить данные из индикатора в робот
Добавлено: 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]; //данные для вывода в робот
}
}
}
Возможно задавать надо переменные как
Подскажите как правильней передать данные в робота.
Заранее спасибо!
Re: Как получить данные из индикатора в робот
Добавлено: 06 фев 2017, 03:30
evge
Да, в стратегии прочитать можно только серии. т. е. AddSeries() - правильно.
Re: Как получить данные из индикатора в робот
Добавлено: 06 фев 2017, 09:12
Владимир
Спасибо!
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"); //Значение экстремума для выставления стопа (либо рассчетный или экстремум, что
Re: Как получить данные из индикатора в робот
Добавлено: 07 фев 2017, 14:19
evge
если покажите мне индикатор (код стратегии уже есть),
тогда поищу ошибку
иначе смогу только догадываться

Re: Как получить данные из индикатора в робот
Добавлено: 07 фев 2017, 14:24
evge
Можно обращаться к серии и так
Код: Выделить всё
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 (или др.)
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);
}
Re: Как получить данные из индикатора в робот
Добавлено: 07 фев 2017, 14:31
evge
У Вас 2 правила в стратегии (код которой разметили выше)
Первое правило открывает Long
Второе правило закрывает Short
т.е. открытый лонг, никогда не закроется в прибыль (только по стопу).
может ошибка в этом?
В стратегии явно ошибка.
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 Закрытие позиции и останов робота.
Цел робота многодневная торговля!
Re: Как получить данные из индикатора в робот
Добавлено: 07 фев 2017, 15:16
evge
Неработает из-за
CurrentIndex == MaxIndex в индикаторе.
Стратегии это не нравится, т.к. вызывает она индикатор один раз для всех своих итераций (по каждому вызову его в коде стратегии, итого 4) и использует результаты полученные от индикатора во всех точках истории.
А затем идёт смотреть значения для каждой точки ряда, а она заполнена только последняя, все предыдущие значения пусты, т.к. для каждого OnUpdate не производится отдельного вызова индикаторов.
Если закомментировать условие
то стратегия будет работать, но при этом её надо поправить, у Вас там несколько ошибок.
Индикатор же будет отображаться некрасиво.