Код: Выделить всё
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);
}
}