нашел, не обнулялся сигнал.
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Добрый день.
изучаю компьютерный анализ. взял шаблон советника и добавил индикатор rsi if(iRSI(NULL,0,14,PRICE_CLOSE,1)<48 && iRSI(NULL,0,14,PRICE_CLOSE,0)>48)Signal=1;
т.е. покупка при пересечении rsi снизу вверх 48. но покупки происходят по иной логике, что исправить?
#property copyright "Scritong"
#property link "http://autograf.dp.ua"
//---- input parameters
extern string A1 = "Объем сделки. Если Lots = 0, то считается в процентах";
extern double Lots = 0.1;
extern double PercentOfDepo = 5;
extern string A2 = "Параметры индикатора";
// Сюда скопировать перечень входных..
// ..параметров индикатора
extern string A3 = "== Настройка расчета стоп-приказа ===";
extern string A4 = "True - стоп в пунктах, false - в волатильности";
extern bool UseSLInPoints = false;
extern string A5 = "Величина стопа (пункты или волатильности)";
extern double StopLoss = 5;
extern string A6 = "Период ATR, если стоп выражен в волатильностях";
extern int SLATR = 24;
extern string A7 = "== Настройка расчета профита ===";
extern string A8 = "True - профит в пунктах, false - в волатильности";
extern bool UseTPInPoints = false;
extern string A9 = "Величина профита (пункты или волатильности)";
extern double TakeProfit = 1;
extern string A10 = "Период ATR, если профит выражен в волатильностях";
extern int TPATR = 24;
extern string A11 = "=== Прочие настройки ===";
extern int TrailingStop1 = 0; // Безубыток
extern int TrailingStop2 = 0; // Классический трейлинг-стоп
extern string OpenOrderSound = "ok.wav";
extern int MagicNumber = 100345;
int Signal, // Направление сигнала
Ticket, // Тикет текущей позиции
Type; // Тип текущей позиции
bool Activate, FreeMarginAlert, FatalError;
double Tick, Spread, StopLevel, MinLot, MaxLot, LotStep, FreezeLevel;
datetime LastBar, LastSignal;
//+-------------------------------------------------------------------------------------+
//| Функция инициализации эксперта |
//+-------------------------------------------------------------------------------------+
int init()
{
FatalError = False;
// - 1 - == Сбор информации об условиях торговли ========================================
Tick = MarketInfo(Symbol(), MODE_TICKSIZE); // минимальный тик
Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point); // текущий спрэд
StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point); // текущий уровень стопов
FreezeLevel = ND(MarketInfo(Symbol(), MODE_FREEZELEVEL)*Point); // уровень заморозки
MinLot = MarketInfo(Symbol(), MODE_MINLOT); // минимальный разрешенный объем сделки
MaxLot = MarketInfo(Symbol(), MODE_MAXLOT); // максимальный разрешенный объем сделки
LotStep = MarketInfo(Symbol(), MODE_LOTSTEP); // шаг приращения объема сделки
// - 1 - == Окончание блока =============================================================
// - 3 - ================= Проверка корректности входных параметров =====================
if (StopLoss < 0)
{
Alert("Значение StopLoss не может быть отрицательным. Эксперт не работает.");
return(0);
}
if (TakeProfit < 0)
{
Alert("Значение TakeProfit не может быть отрицательным. Эксперт не работает.");
return(0);
}
if (SLATR < 2)
{
Alert("Значение SLATR не может быть меньше 2. Эксперт не работает.");
return(0);
}
if (TPATR < 2)
{
Alert("Значение TPATR не может быть меньше 2. Эксперт не работает.");
return(0);
}
// - 3 - =========================== Окончание блока ====================================
LastBar = 0;
LastSignal = 0;
Activate = True; // Все проверки успешно завершены, возводим флаг активизации эксперта
//----
return(0);
}
//+-------------------------------------------------------------------------------------+
//| Функция деинициализации эксперта |
//+-------------------------------------------------------------------------------------+
int deinit()
{
return(0);
}
//+--------------------------------------------------------------------------------------+
//| Двухуровневый трейлинг-стоп |
//| TrailingStop1 - выставляется один раз после достижения нужного кол-ва пунктов прибыли|
//| TrailingStop2 - движущийся. Включается после отработки трейлинг-стопа первого уровня |
//+--------------------------------------------------------------------------------------+
void TrailingStopDoubleLevel()
{
for (int i = 0; i < OrdersTotal(); i++)
if (OrderSelect(i, SELECT_BY_POS))
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() < 2)
{
if (!WaitForTradeContext()) break;
// Блок 1. Нормализация основных характеристик позиции -----------------------------------
RefreshRates();
double OpPrice = ND(OrderOpenPrice()); // Приведение цены открытия к нужной точности
double SL = ND(OrderStopLoss()); // Приведение стоп-приказа к нужной точности
double NBid = ND(Bid);
double NAsk = ND(Ask);
// Блок 1. -------------------------------------------------------------------------------
// Блок 2. Классический трейлинг длинной позиции -----------------------------------------
if(OrderType() == OP_BUY)
if(SL >= OpPrice && TrailingStop2 != 0) // Если стоп перенесен в безубыток
{
if(NBid > ND(Tick*TrailingStop2+SL) && // Если BID больше стопа на TrailingStop2
TrailingStop2 > StopLevel/Point) // И TrailingStop2 больше уровня стопов
if(WaitForTradeContext()) // Ждем освобождение торгового потока
if(!OrderModify(OrderTicket(), 0,
ND(NBid-TrailingStop2*Tick), OrderTakeProfit(), 0)) // Модификация
Print("Не удалось изменить ордер BUY. Второй трал. Ошибка №",
GetLastError(), ", Старый: ", SL, ", Новый: ",
NBid-TrailingStop2*Tick); // Развернутое сообщение об ошибке
}
// Блок 2. -------------------------------------------------------------------------------
// Блок 3. Перенос стопа в безубыток длинной позиции -------------------------------------
else
{
if(ND(OpPrice+TrailingStop1*Tick) < NBid && // Если BID больше цены открытия
TrailingStop1 > StopLevel/Point) // на TrailingStop1 пунктов и дальше, чем
if(WaitForTradeContext()) // уровень стопов
if(!OrderModify(OrderTicket(), 0, OpPrice,
OrderTakeProfit(), 0)) // модификация
Print("Не удалось изменить ордер BUY. Первый трал. Ошибка №", // сообщение
GetLastError(), ", Старый: ", SL, ", Новый: ", OpPrice);// в журнал
}
// Блок 3. -------------------------------------------------------------------------------
// Блок 4. Классический трейлинг короткой позиции ----------------------------------------
if(OrderType()==OP_SELL) // Для короткой позиции
if(OpPrice >= SL && SL != 0 && TrailingStop2 != 0) // Если стоп перенесен в безубыток
{
if(TrailingStop2 > StopLevel/Point && // TrailingStop2 больше уровня стопов
SL > ND(Tick*TrailingStop2+NAsk)) // и ASK ниже стопа на TrailingStop2 пунктов
if(WaitForTradeContext()) // Ожидаем освобождения торгового потока
if(!OrderModify(OrderTicket(), 0, ND(NAsk+TrailingStop2*Tick),
OrderTakeProfit(), 0)) // модификация
Print("Не удалось изменить ордер SELL. Второй трал. Ошибка №",
GetLastError(), ", Старый: ", SL, ", Новый: ", NAsk+TrailingStop2*Tick);
}
// Блок 4. -------------------------------------------------------------------------------
// Блок 5. Перенос стопа в безубыток короткой позиции ------------------------------------
else
{
if(OpPrice > ND(NAsk+Tick*TrailingStop1) && //ASK ниже открытия на TrailingStop1
TrailingStop1 > StopLevel/Point) // и на StopLevel пунктов
if(WaitForTradeContext()) // Ожидаем торговый поток
if(!OrderModify(OrderTicket(), 0, OpPrice, OrderTakeProfit(), 0))//модификация
Print("Не удалось изменить ордер SELL. Первый трал. Ошибка №",
GetLastError(), ", Старый: ", SL, ", Новый: ", OpPrice);
}
// Блок 5. -------------------------------------------------------------------------------
}
return(0);
}
//+-------------------------------------------------------------------------------------+
//| Расчет объема сделки, исходя из свободных средств. |
//+-------------------------------------------------------------------------------------+
double GetLots()
{
if (Lots == 0) // Если значение Lots равно нулю, то
{ // ..рассчитаем объем по имеющимся..
// ..свободным средствам
double lot = (PercentOfDepo/100)*AccountFreeMargin()/
MarketInfo(Symbol(), MODE_MARGINREQUIRED);
return(LotRound(lot));
}
else // Если параметр не равен нулю, то..
return(LotRound(Lots)); // ..просто вернем его значение
}
//+-------------------------------------------------------------------------------------+
//| Проверка объема на корректность и округление |
//+-------------------------------------------------------------------------------------+
double LotRound(double L)
{
return(MathRound(MathMin(MathMax(L, MinLot), MaxLot)/LotStep)*LotStep);
}
//+-------------------------------------------------------------------------------------+
//| Приведение значений к точности одного пункта |
//+-------------------------------------------------------------------------------------+
double ND(double A)
{
return(NormalizeDouble(A, Digits));
}
//+-------------------------------------------------------------------------------------+
//| Расшифровка сообщения об ошибке |
//+-------------------------------------------------------------------------------------+
string ErrorToString(int Error)
{
switch(Error)
{
case 2: return("зафиксирована общая ошибка, обратитесь в техподдержку.");
case 5: return("у вас старая версия терминала, обновите ее.");
case 6: return("нет связи с сервером, попробуйте перезагрузить терминал.");
case 64: return("счет заблокирован, обратитесь в техподдержку.");
case 132: return("рынок закрыт.");
case 133: return("торговля запрещена.");
case 149: return("запрещено локирование.");
}
}
//+-------------------------------------------------------------------------------------+
//| Ожидание торгового потока. Если поток свободен, то результат True, иначе - False |
//+-------------------------------------------------------------------------------------+
bool WaitForTradeContext()
{
int P = 0;
while(IsTradeContextBusy() && P < 5)
{
P++;
Sleep(1000);
}
if (P == 5)
return(False);
return(True);
}
//+-------------------------------------------------------------------------------------+
//| "Правильное" открытие позиции |
//| В отличие от OpenOrder проверяет соотношение текущих уровней и устанавливаемых |
//| Возвращает: |
//| 0 - нет ошибок |
//| 1 - Ошибка открытия |
//| 2 - Ошибка значения Price |
//| 3 - Ошибка значения SL |
//| 4 - Ошибка значения TP |
//| 5 - Ошибка значения Lot |
//+-------------------------------------------------------------------------------------+
int OpenOrderCorrect(int Type, double Lot, double Price, double SL, double TP,
bool Redefinition = True)
// Redefinition - при True доопределять параметры до минимально допустимых
// при False - возвращать ошибку
{
// - 1 - == Проверка достаточности свободных средств ====================================
if(AccountFreeMarginCheck(Symbol(), OP_BUY, Lot) <= 0 || GetLastError() == 134)
{
if(!FreeMarginAlert)
{
Print("Недостаточно средств для открытия позиции. Free Margin = ",
AccountFreeMargin());
FreeMarginAlert = True;
}
return(5);
}
FreeMarginAlert = False;
// - 1 - == Окончание блока =============================================================
// - 2 - == Корректировка значений Price, SL и TP или возврат ошибки ====================
RefreshRates();
switch (Type)
{
case OP_BUY:
string S = "BUY";
if (MathAbs(Price-Ask)/Point > 3)
if (Redefinition) Price = ND(Ask);
else return(2);
if (ND(TP-Bid) <= StopLevel && TP != 0)
if (Redefinition) TP = ND(Bid+StopLevel+Tick);
else return(4);
if (ND(Bid-SL) <= StopLevel)
if (Redefinition) SL = ND(Bid-StopLevel-Tick);
else return(3);
break;
case OP_SELL:
S = "SELL";
if (MathAbs(Price-Bid)/Point > 3)
if (Redefinition) Price = ND(Bid);
else return(2);
if (ND(Ask-TP) <= StopLevel)
if (Redefinition) TP = ND(Ask-StopLevel-Tick);
else return(4);
if (ND(SL-Ask) <= StopLevel && SL != 0)
if (Redefinition) SL = ND(Ask+StopLevel+Tick);
else return(3);
break;
case OP_BUYSTOP:
S = "BUYSTOP";
if (ND(Price-Ask) <= StopLevel)
if (Redefinition) Price = ND(Ask+StopLevel+Tick);
else return(2);
if (ND(TP-Price) <= StopLevel && TP != 0)
if (Redefinition) TP = ND(Price+StopLevel+Tick);
else return(4);
if (ND(Price-SL) <= StopLevel)
if (Redefinition) SL = ND(Price-StopLevel-Tick);
else return(3);
break;
case OP_SELLSTOP:
S = "SELLSTOP";
if (ND(Bid-Price) <= StopLevel)
if (Redefinition) Price = ND(Bid-StopLevel-Tick);
else return(2);
if (ND(Price-TP) <= StopLevel)
if (Redefinition) TP = ND(Price-StopLevel-Tick);
else return(4);
if (ND(SL-Price) <= StopLevel && SL != 0)
if (Redefinition) SL = ND(Price+StopLevel+Tick);
else return(3);
break;
case OP_BUYLIMIT:
S = "BUYLIMIT";
if (ND(Ask-Price) <= StopLevel)
if (Redefinition) Price = ND(Ask-StopLevel-Tick);
else return(2);
if (ND(TP-Price) <= StopLevel && TP != 0)
if (Redefinition) TP = ND(Price+StopLevel+Tick);
else return(4);
if (ND(Price-SL) <= StopLevel)
if (Redefinition) SL = ND(Price-StopLevel-Tick);
else return(3);
break;
case OP_SELLLIMIT:
S = "SELLLIMIT";
if (ND(Price - Bid) <= StopLevel)
if (Redefinition) Price = ND(Bid+StopLevel+Tick);
else return(2);
if (ND(Price-TP) <= StopLevel)
if (Redefinition) TP = ND(Price-StopLevel-Tick);
else return(4);
if (ND(SL-Price) <= StopLevel && SL != 0)
if (Redefinition) SL = ND(Price+StopLevel+Tick);
else return(3);
break;
}
// - 2 - == Окончание блока =============================================================
// - 3 - == Открытие ордера с ожидание торгового потока =================================
if(WaitForTradeContext()) // ожидание освобождения торгового потока
{
Comment("Отправлен запрос на открытие ордера ", S, " ...");
int ticket=OrderSend(Symbol(), Type, Lot, Price, 3,
SL, TP, NULL, MagicNumber, 0);// открытие позиции
// Попытка открытия позиции завершилась неудачей
if(ticket<0)
{
int Error = GetLastError();
if(Error == 2 || Error == 5 || Error == 6 || Error == 64
|| Error == 132 || Error == 133 || Error == 149) // список фатальных ошибок
{
Comment("Фатальная ошибка при открытии позиции т. к. "+
ErrorToString(Error)+" Советник отключен!");
FatalError = True;
}
else
Comment("Ошибка открытия позиции ", S, ": ", Error); // нефатальная ошибка
return(1);
}
// ---------------------------------------------
// Удачное открытие позиции
Comment("Позиция ", S, " открыта успешно!");
PlaySound(OpenOrderSound);
return(0);
// ------------------------
}
else
{
Comment("Время ожидания освобождения торгового потока истекло!");
return(1);
}
// - 3 - == Окончание блока =============================================================
}
//+-------------------------------------------------------------------------------------+
//| Приведение значений к точности одного тика |
//+-------------------------------------------------------------------------------------+
double NP(double A)
{
return(MathRound(A/Tick)*Tick);
}
//+-------------------------------------------------------------------------------------+
//| Генерация сигналов покупки и продажи по значениям двух стохастиков |
//+-------------------------------------------------------------------------------------+
void GetSignal()
{
// Signal = 0;
// - 1 - == Получение показаний индикатора ==============================================
// Сюда вставить получение значений..
// ..индикатора - функция iCustom
// - 1 - == Окончание блока =============================================================
// - 2 - == Генерация сигнала покупки ===================================================
// Сюда вставить условие генерации..
// ..сигнала покупки
// Signal = 1;
// - 2 - == Окончание блока =============================================================
// - 3 - ======================== Генерация сигнала продажи =============================
// Сюда вставить условие генерации..
// ..сигнала продажи
// Signal = -1;
// - 3 - == Окончание блока =============================================================
if(iRSI(NULL,0,14,PRICE_CLOSE,1)<48 && iRSI(NULL,0,14,PRICE_CLOSE,0)>48)Signal=1;
}
//+-------------------------------------------------------------------------------------+
//| Функция поиска своих ордеров. |
//+-------------------------------------------------------------------------------------+
void FindOrders()
{
// - 1 - == Инициализация переменных перед поиском ======================================
int total = OrdersTotal() - 1;
Ticket = -1;
Type = -1;
// - 1 - == Окончание блока =============================================================
// - 2 - == Непосредственно поиск =======================================================
for (int i = total; i >= 0; i--) // Используется весь список ордеров
if (OrderSelect(i, SELECT_BY_POS)) // Убедимся, что ордер выбран
if (OrderMagicNumber() == MagicNumber && // Позиция открыта экспертом, который
OrderSymbol() == Symbol() && // ..прикреплен к текущей паре
OrderType() < 2)
{
Ticket = OrderTicket(); // Запишем данные позиции
Type = OrderType();
}
// - 2 - == Окончание блока =============================================================
}
//+-------------------------------------------------------------------------------------+
//| Закрытие заданного рыночного ордера |
//+-------------------------------------------------------------------------------------+
bool CloseDeal(int ticket)
{
if (OrderSelect(ticket, SELECT_BY_TICKET) && // Существует ордер с заданным..
OrderCloseTime() == 0) // ..тикетом и ордер не закрыт
if (WaitForTradeContext()) // Свободен ли торговый поток?
{
if (OrderType() == OP_BUY) // Если следует закрыть длинную..
double Price = MarketInfo(Symbol(), MODE_BID);// ..сделку, то применяется..
// ..цена BID
else // Если следует закрыть короткую..
Price = MarketInfo(Symbol(), MODE_ASK);// ..сделку, то применяется цена ASK
if (!OrderClose(OrderTicket(), OrderLots(), NP(Price), 3))// Если сделку не..
return(False); // ..удалось закрыть, то результат..
// функции - False
}
else
return(false);
return(True); // Можно открывать следующую сделку
}
//+-------------------------------------------------------------------------------------+
//| Вычисление уровня на основании исходной цены |
//+-------------------------------------------------------------------------------------+
double GetLevel(bool in_points, double value, int atr_period, double price, int koef)
{
if (value == 0) // Если исходная величина равна нулю,
return(0); // ..то ноль и вернем
if (in_points) // Исходная величина задана в пунктах
return(NP(price + koef*value)); // Вернем уровень, который отстоит от
// ..цены на value пунктов в..
// ..направлении koef
return(NP(price + koef*value* // Исходная величина задана в..
iATR(NULL, 0, atr_period, 1))); // ..волатильностях. Поэтому вернем..
// ..уровень, который отстоит от цены
// ..price на value волатильностей в
// ..направлении koef
}
//+-------------------------------------------------------------------------------------+
//| Открытие позиций |
//+-------------------------------------------------------------------------------------+
bool Trade()
{
FindOrders(); // Найдем свои позиции
// - 1 - == Открытие длинной позиции ====================================================
if (Signal > 0 && Type != OP_BUY) // Активен сигнал покупки и..
{ // ..отсутствует длинная позиция
if (Type == OP_SELL) // Существует короткая позиция
if (!CloseDeal(Ticket)) // Закроем позицию
return(false); // При неудаче вернем false
double sl = GetLevel(UseSLInPoints, StopLoss,// Формируем значения стоп-приказа и..
SLATR, Ask, -1);
double tp = GetLevel(UseSLInPoints, StopLoss, SLATR, Ask, 1); // ..профита
if (OpenOrderCorrect(OP_BUY, GetLots(), NP(Ask), sl, tp) != 0)
return(False);
}
// - 1 - == Окончание блока =============================================================
// - 2 - == Открытие короткой позиции ===================================================
if (Signal < 0 && Type != OP_SELL) // Активен сигнал продажи и..
{ // ..отсутствует короткая позиция
if (Type == OP_BUY) // Существует длинная позиция
if (!CloseDeal(Ticket)) // Закроем позицию
return(false); // При неудаче вернем false
sl = GetLevel(UseSLInPoints, StopLoss, SLATR,// Формируем значения стоп-приказа и..
Bid, 1);
tp = GetLevel(UseSLInPoints, StopLoss, SLATR, Bid, -1);// ..профита
if (OpenOrderCorrect(OP_SELL, GetLots(), NP(Bid), sl, tp) != 0)
return(False);
}
// - 2 - == Окончание блока =============================================================
return(True);
}
//+-------------------------------------------------------------------------------------+
//| Функция start эксперта |
//+-------------------------------------------------------------------------------------+
int start()
{
// - 1 - == Можно ли работать эксперту? =================================================
if (!Activate || FatalError) return(0);
// - 1 - == Окончание блока =============================================================
// - 2 - == Контроль открытия нового бара ===============================================
if (LastBar == Time[0]) // Если на текущем баре уже были..
return(0); // ..произведены необходимые действия,
// ..то прерываем работу до..
// ..следующего тика
// - 2 - == Окончание блока =============================================================
// - 3 - == Слежение за изменением рыночного окружения ==================================
if (!IsTesting())
{
Tick = MarketInfo(Symbol(), MODE_TICKSIZE); // минимальный тик
Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point);// текущий спред
StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point);//текущий уровень стопов
FreezeLevel = ND(MarketInfo(Symbol(), MODE_FREEZELEVEL)*Point);// уровень заморозки
}
// - 3 - == Окончание блока =============================================================
// - 4 - == Расчет сигналов =============================================================
if (LastSignal != Time[0]) // На текущем баре еще не был..
{ // ..произведен расчет сигнала
GetSignal(); // Определяем наличие сигнала
LastSignal = Time[0]; // Определение сигнала на текущем баре
} // ..произведено
// - 4 - == Окончание блока =============================================================
// - 5 - == Выполнение торговых операций ================================================
if (Signal != 0) // Если есть сигнал
if (!Trade()) return(0); // Открытие/закрытие позиций
// - 5 - == Окончание блока =============================================================
// - 6 - == трал =============================================================
TrailingStopDoubleLevel();
// - 6 - == Окончание блока =============================================================
LastBar = Time[0];
return(0);
}