//+-------------------------------------------------------------------------------------+ //| Lighting.mq4 | //| Scriptong | //| scriptong@mail.ru | //+-------------------------------------------------------------------------------------+ #property copyright "Scriptong" #property link "scriptong@mail.ru" #property indicator_chart_window // индикатор отображается в окне котировок extern double TPPercent = 80; // Прибыль в процентах от разницы начала первой волны и // конца второй волны int FN, // Номер бара, на котором зафиксирован первый (считается справа налево) фрактал SN, // Номер бара, на котором зафиксирован второй фрактал TN, // Номер бара, на котором зафиксирован третий фрактал FT, // Тип первого фрактала: 0 - нижний, 1 - верхний ST, // Тип второго фрактала TT; // Тип третьего фрактала double FV, // Значение цены первого фрактала SV, // Значение цены второго фрактала TV; // Значение цены третьего фрактала string prefix = "LT_"; //+-------------------------------------------------------------------------------------+ //| Custom indicator initialization function | //+-------------------------------------------------------------------------------------+ int init() { return(0); } //+-------------------------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+-------------------------------------------------------------------------------------+ int deinit() { for (int i = ObjectsTotal()-1; i >= 0; i--) if (StringSubstr(ObjectName(i), 0, StringLen(prefix)) == prefix) ObjectDelete(ObjectName(i)); return(0); } //+-------------------------------------------------------------------------------------+ //| Отображение канала | //+-------------------------------------------------------------------------------------+ void SetChannel(string Name, datetime Time1, double Price1, datetime Time2, double Price2, datetime Time3, double Price3, color Color, int Style) { string name = prefix + Name; if (ObjectFind(name) < 0) { ObjectCreate(name, OBJ_CHANNEL, 0, Time1, Price1, Time2, Price2, Time3, Price3); ObjectSet(name, OBJPROP_COLOR, Color); ObjectSet(name, OBJPROP_STYLE, Style); } else { ObjectMove(name, 0, Time1, Price1); ObjectMove(name, 1, Time2, Price2); ObjectMove(name, 2, Time3, Price3); ObjectSet(name, OBJPROP_COLOR, Color); } } //+-------------------------------------------------------------------------------------+ //| Отображение горизонтальной линии | //+-------------------------------------------------------------------------------------+ void SetHLine(string Name, double Price, color Color) { string name = prefix + Name; if (ObjectFind(name) < 0) { ObjectCreate(name, OBJ_HLINE, 0, 1, Price); ObjectSet(name, OBJPROP_COLOR, Color); ObjectSet(name, OBJPROP_STYLE, STYLE_SOLID); } else ObjectMove(name, 0, 1, Price); } //+-------------------------------------------------------------------------------------+ //| Поиск трех последних фракталов и проверка соответствия условиям канала | //+-------------------------------------------------------------------------------------+ bool FindChannel() { // - 1 - ================================ Инициализация перменных ======================= FN = 0; SN = 0; TN = 0; // - 1 - ==================================== Окончание блока =========================== for (int i = 3; i < Bars && TN == 0; i++) { // - 2 - ================================ Поиск "верхних" фракталов ===================== double Fr = iFractals(NULL, 0, MODE_UPPER, i); // Получение значения "верхнего" // фрактала на свече №i if (Fr != 0)// Если фрактал найден, то необходимо найти место для записи его значений if (FN == 0) // Является ли найденный фрактал первым? { // Если является, то FN = i; // запоминается номер бара, FV = Fr; // значение цены FT = 1; // и тип фрактала continue; // если на этом баре существует "нижний" фрактал, он игнорируется } else // Найденный фрактал уже не первый if (SN == 0) // Может быть этот фрактал второй? { // Если этот фрактал второй, то if (FT == 0) // согласно стратегии нужно проверить, был ли первый фрактал { // "нижним". Если это действительно так, то все в порядке и можно SN = i; // запомнить номер бара SV = Fr; // цену формирования ST = 1; // и тип фрактала continue; // если на этом баре существует "нижний" фрактал, он игнорируется } else // первый фрактал был "верхним", что не вписывается в правила стратегии return(False); // подается сигнал о том, что канал не сформирован } else // Найденный фрактал даже не второй if (TN == 0) // Тогда может это третий фрактал? { // Если этот фрактал третий, то if (FT == 1 && ST == 0) // Первый - должен был быть "верхним", второй - { // "нижним". Только в таком случае производится запись фрактала TN = i; // Сохранение номере бара, TV = Fr; // цены формирования фрактала и TT = 1; // его типа continue;//если на этом баре существует "нижний" фрактал, он игнорируется } else // Третий фрактал не соответствует стратегии return(False); // подается сигнал о том, что канал не сформирован } else break; // Все фракталы найдены, следует прервать цикл поиска // - 2 - ==================================== Окончание блока =========================== // - 3 - ================================ Поиск "нижних" фракталов ====================== Fr = iFractals(NULL, 0, MODE_LOWER, i); // Получение значения "нижнего" // фрактала на свече №i if (Fr != 0)// Если фрактал найден, то необходимо найти место для записи его значений if (FN == 0) // Является ли найденный фрактал первым? { // Если является, то FN = i; // запоминается номер бара, FV = Fr; // значение цены FT = 0; // и тип фрактала } else // Найденный фрактал уже не первый if (SN == 0) // Может быть этот фрактал второй? { // Если этот фрактал второй, то if (FT == 1 && FN != i) // согласно стратегии нужно проверить, был ли первый { // фрактал "верхним". Если это действительно так, то все в порядке и можно SN = i; // запомнить номер бара SV = Fr; // цену формирования ST = 0; // и тип фрактала } else // первый фрактал был "нижним", что не вписывается в правила стратегии return(False); // Не выполнено условие чередования фракталов, канал не } // сформирован else // Найденный фрактал даже не второй if (TN == 0) // Тогда может это третий фрактал? { // Если этот фрактал третий, то if (FT == 0 && ST == 1) // Первый - должен был быть "нижним", второй - { // "верхним". Только в таком случае производится запись фрактала TN = i; // Сохранение номере бара, TV = Fr; // цены формирования фрактала и TT = 0; // его типа } else // Третий фрактал не соответствует стратегии return(False); // подается сигнал о том, что канал не сформирован } else break; // Все фракталы найдены, следует прервать цикл поиска } // - 3 - ==================================== Окончание блока =========================== // - 4 - ================================ Условия для молнии вниз ======================= if (FT == 1) // Если первый фрактал - "верхний", то молния вниз, сигнал в ту же сторону { if (FV > (TV + SV)/2) // Первый фрактал не должен быть выше середины первой волны return(False); // иначе это не соответствует правилам стратегии if (Close[FN-1] >= Close[FN]) // Свеча после формирования второй волны не должна return(False); // закрыться выше закрытия свечи второй волны for (i = TT-1; i >= ST; i--) // Проверка всех баров первой волны // средняя на протяжении первой волны должна быть нисходящей if (iMA(NULL, 0, 2, 0, MODE_EMA, PRICE_CLOSE, i) > iMA(NULL, 0, 2, 0, MODE_EMA, PRICE_CLOSE, i+1)) return(False); // Если замечен рост - молния не подходит } // - 4 - ==================================== Окончание блока =========================== // - 5 - ================================ Условия для молнии вверх ====================== else // Если первый фрактал - "нижний", то молния вверх, сигнал в ту же сторону { if (FV < (TV + SV)/2) // Первый фрактал не должен быть ниже середины первой волны return(False); if (Close[FN-1] <= Close[FN]) // Свеча после формирования второй волны не должна return(False); // закрыться ниже закрытия свечи второй волны for (i = TT-1; i >= ST; i--) // Проверка всех баров первой волны // средняя на протяжении первой волны должна быть восходящей if (iMA(NULL, 0, 2, 0, MODE_EMA, PRICE_CLOSE, i) < iMA(NULL, 0, 2, 0, MODE_EMA, PRICE_CLOSE, i+1)) return(False); // Если замечен спад - молния не подходит } // - 5 - ==================================== Окончание блока =========================== return(True); // Канал найден } //+-------------------------------------------------------------------------------------+ //| Custom indicator iteration function | //+-------------------------------------------------------------------------------------+ int start() { if (FindChannel()) // если канал найден { // необходимо определить в какую сторону он направлен - вверх или вниз if (FT == 0) // Канал направлен вверх { SetChannel("MainChannel", Time[TN], TV, // Отображение канала синим цветом Time[SN], SV, Time[FN], FV, Blue, STYLE_SOLID); SetHLine("ExPrice", SV, Lime); // Отображение цены открытия ордера SetHLine("TPPrice", // Отображение уровня цели SV + (FV - TV)*TPPercent/100, Blue); SetHLine("SLPrice", FV, Red); // Отображение уровня стопа } else // Канал направлен вниз { SetChannel("MainChannel", Time[TN], TV, // Отображение канала красным цветом Time[SN], SV, Time[FN], FV, Red, STYLE_SOLID); SetHLine("ExPrice", SV, Lime); // Отображение цены открытия ордера SetHLine("TPPrice", // Отображение уровня цели SV - (TV - FV)*TPPercent/100, Blue); SetHLine("SLPrice", FV, Red); // Отображение уровня стопа } } return(0); }