Вобщем после долгих раздумий, нашел по принципу похожий на мой и немного подправил его. Не не могу разобраться в одно вещи.Каждую неделю в понедельник ставит отложенные ордера BuyStop и SellStop на расстоянии 50п. от цены открытия недели. После того как одна из сделак открывается, вторую удалет. В открытой сделке ТР=180п, SL=60п. Если стопы не срабатывают до конца недели, то закрывет открытые сделку в понедельник примерно по цене открытия. А вот если не один отложенник не сработал, то почему-ьто эти ордера в понедельник не удаляет. Я пробовал вписывать функцию OrderDelete(), но почему-то не получается у меня с ней ничего.
Подскажите пожалуйста как можно это исправить.Я красным выделил, в какой блок я пытался это вставить.
#property copyright "Gyry"
#property link ""
extern int TimeFrame = 60;
int slippage = 0; //проскальзование
extern double lot = 0.5;
extern double EnterRatio = 0.0001;
extern double StopRatio = 0.0001;
double spread, point; //point- размер пункта текущего финансового инструмента в валюте котировки
double Ballance = 0.0;
string symbol;
int digits;
int init() //специальная функция, до return
{
symbol = Symbol();//название инструмента
spread = MarketInfo(symbol,MODE_SPREAD);//информация о финансовом инструменте (спрэд в пунктах)
point = MarketInfo(symbol,MODE_POINT);//информация о финансовом инструменте (Размер пункта в валюте котировки. Для текущего инструмента хранится в предопределенной переменной Point)
digits = MarketInfo(symbol,MODE_DIGITS);//информация о финансовом инструменте (Количество цифр после десятичного точки в цене инструмента. Для текущего инструмента хранится в предопределенной переменной Digits)
return(0);//используется для передачи значения функции
}
int deinit(){return(0);}
int start()
{
double OpenLevel, Range, BuyStop, SellStop, SL_for_Buy, TP_for_Buy, SL_for_Sell, TP_for_Sell, price, SL, TP;
int i, a, k, buy_ticket, sell_ticket;
// условие: понедельник, закончен первый торговый час новой недели
// основной блок - расстоновка/закрытие ордеров
if(TimeDayOfWeek(iTime(symbol,TimeFrame,1)) == 1 && TimeDayOfWeek(iTime(symbol,TimeFrame,2)) != 1) //если день недели 1 т.е. понедельник(значение времени открытия бара(инстр., таймфрейм, понед.)=1
{
// определили данные, необходимые для расчета уровней ордеров
OpenLevel = iOpen(symbol,10080,0); //значение цены открытия бара(инстр.,таймфрейм,сдвиг относительно текущего бара на указанное количество баров назад)
Range = iHigh(symbol,10080,1) - iLow(symbol,10080,1); //диапозон = значение максимальной цены бара(символ,таймф.,сдвиг относительно текущего бара на указанное количество баров назад)
// Рассчитываем уровни расстановки новых ордеров
BuyStop = NormalizeDouble(OpenLevel + 50*EnterRatio, digits); //Округление числа с плавающей точкой до указанной точности(величина с плав.точкой, кол-во знаков после запятой)
SL_for_Buy = NormalizeDouble(OpenLevel + 10*StopRatio, digits);
TP_for_Buy = NormalizeDouble(OpenLevel - 230*StopRatio, digits);
SellStop = NormalizeDouble(OpenLevel - 50*EnterRatio, digits);
SL_for_Sell = NormalizeDouble(OpenLevel - 10*StopRatio, digits);
TP_for_Sell = NormalizeDouble(OpenLevel + 230*StopRatio, digits);
RefreshRates();
// Проводим работу с имеющимися ордерами
if(OrdersTotal() > 0) // если есть ордера и открытые позиции
{
for(i = 1; i <= OrdersTotal(); i++) // перебираем ордера
{
// рассматриваем бай-позиции:
if (OrderSelect(i-1,SELECT_BY_POS) == true && OrderSymbol() == symbol && OrderType() == OP_BUY)
{
// если выбранная позиция в плюсе - закрываем ее
if(OrderOpenPrice() < Bid) OrderClose(OrderTicket(),OrderLots(),Bid,slippage,Red);
// если выбранная позиция в минусе - изменяем ее СтопЛосс в соответствии с новыми данными
if(OrderOpenPrice() > Bid) OrderClose(OrderTicket(),OrderLots(),Bid,slippage,Red);
}
// рассматриваем селл-позиции:
if (OrderSelect(i-1,SELECT_BY_POS) == true && OrderSymbol() == symbol && OrderType() == OP_SELL)
{
// если выбранная позиция в плюсе - закрываем ее
if(OrderOpenPrice() > Ask) OrderClose(OrderTicket(),OrderLots(),Ask,slippage,Red);
// если выбранная позиция в минисе - изменяем ее СтопЛосс в соответствии с новыми данными
if(OrderOpenPrice() < Ask) OrderClose(OrderTicket(),OrderLots(),Ask,slippage,Red);
}
}
}
// Если нет открытых позиций - расставим новые ордера
if(OpenPositions(symbol) == 0)
{
buy_ticket = OrderSend(symbol,OP_BUYSTOP, lot, BuyStop, slippage, SL_for_Buy, TP_for_Buy, NULL, 0, 0, Red); //Здесь исправить. Основная функция, используемая для совершения торговых операций или установки отложенного ордера
if(buy_ticket == -1) Alert("Ошибка установки бай-ордера ", GetLastError());
sell_ticket = OrderSend(symbol,OP_SELLSTOP, lot, SellStop, slippage, SL_for_Sell, TP_for_Sell, NULL, 0, 0, Red);
if(sell_ticket == -1) Alert("Ошибка установки селл-ордера ", GetLastError());
}
Sleep(60000*TimeFrame); // выполнили задачи и спать
}
// блок выше - выполняется один раз с началом новой недели, ниже проверка:
// если в наличии всего ОДИН отложенный ордер - значит второй сработал и ордер должен быть удален;
// другими словами - убираем за собой не сработавшие ордера
if(OrdersNumber(symbol) == 1) DeleteOrders(symbol);
Sleep(60000*TimeFrame); // выполнили задачи и спать
return(0);
}
int OpenPositions(string symbol)
{
int k = 0;
if(OrdersTotal() > 0)
{
for(int i = 1; i <= OrdersTotal(); i++)
{
if(OrderSelect(i-1,SELECT_BY_POS)==true && OrderSymbol() == symbol)
k = k + 1;
}
}
return(k);
}
int OrdersNumber(string symbol)
{
int k = 0;
if(OrdersTotal() > 0)
{
for(int i = 1; i <= OrdersTotal(); i++)
{
if(OrderSelect(i-1,SELECT_BY_POS)==true && OrderSymbol() == symbol && OrderType() > 1)
k = k + 1;
}
}
return(k);
}
void DeleteOrders(string symbol)
{
for(int i = 1; i <= OrdersTotal(); i++)
{
if(OrderSelect(i-1,SELECT_BY_POS)==true && OrderSymbol() == symbol && OrderType() > 1)
bool Ans = OrderDelete(OrderTicket());
}
return(0);
}
#property copyright "Gyry" #property link "" extern int TimeFrame = 60; int slippage = 0; //проскальзование extern double lot = 0.5; extern double EnterRatio = 0.0001; extern double StopRatio = 0.0001; double spread, point; //point- размер пункта текущего финансового инструмента в валюте котировки double Ballance = 0.0; string symbol; int digits; int init() //специальная функция, до return { symbol = Symbol();//название инструмента spread = MarketInfo(symbol,MODE_SPREAD);//информация о финансовом инструменте (спрэд в пунктах) point = MarketInfo(symbol,MODE_POINT);//информация о финансовом инструменте (Размер пункта в валюте котировки. Для текущего инструмента хранится в предопределенной переменной Point) digits = MarketInfo(symbol,MODE_DIGITS);//информация о финансовом инструменте (Количество цифр после десятичного точки в цене инструмента. Для текущего инструмента хранится в предопределенной переменной Digits) return(0);//используется для передачи значения функции } int deinit(){return(0);} int start() { double OpenLevel, Range, BuyStop, SellStop, SL_for_Buy, TP_for_Buy, SL_for_Sell, TP_for_Sell, price, SL, TP; int i, a, k, buy_ticket, sell_ticket; // условие: понедельник, закончен первый торговый час новой недели // основной блок - расстоновка/закрытие ордеров if(TimeDayOfWeek(iTime(symbol,TimeFrame,1)) == 1 && TimeDayOfWeek(iTime(symbol,TimeFrame,2)) != 1) //если день недели 1 т.е. понедельник(значение времени открытия бара(инстр., таймфрейм, понед.)=1 { // определили данные, необходимые для расчета уровней ордеров OpenLevel = iOpen(symbol,10080,0); //значение цены открытия бара(инстр.,таймфрейм,сдвиг относительно текущего бара на указанное количество баров назад) Range = iHigh(symbol,10080,1) - iLow(symbol,10080,1); //диапозон = значение максимальной цены бара(символ,таймф.,сдвиг относительно текущего бара на указанное количество баров назад) // Рассчитываем уровни расстановки новых ордеров BuyStop = NormalizeDouble(OpenLevel + 50*EnterRatio, digits); //Округление числа с плавающей точкой до указанной точности(величина с плав.точкой, кол-во знаков после запятой) SL_for_Buy = NormalizeDouble(OpenLevel + 10*StopRatio, digits); TP_for_Buy = NormalizeDouble(OpenLevel - 230*StopRatio, digits); SellStop = NormalizeDouble(OpenLevel - 50*EnterRatio, digits); SL_for_Sell = NormalizeDouble(OpenLevel - 10*StopRatio, digits); TP_for_Sell = NormalizeDouble(OpenLevel + 230*StopRatio, digits); RefreshRates(); // Проводим работу с имеющимися ордерами if(OrdersTotal() > 0) // если есть ордера и открытые позиции { for(i = 1; i <= OrdersTotal(); i++) // перебираем ордера { // рассматриваем бай-позиции: if (OrderSelect(i-1,SELECT_BY_POS) == true && OrderSymbol() == symbol && OrderType() == OP_BUY) { // если выбранная позиция в плюсе - закрываем ее if(OrderOpenPrice() < Bid) OrderClose(OrderTicket(),OrderLots(),Bid,slippage,Red); // если выбранная позиция в минусе - изменяем ее СтопЛосс в соответствии с новыми данными if(OrderOpenPrice() > Bid) OrderClose(OrderTicket(),OrderLots(),Bid,slippage,Red); } // рассматриваем селл-позиции: if (OrderSelect(i-1,SELECT_BY_POS) == true && OrderSymbol() == symbol && OrderType() == OP_SELL) { // если выбранная позиция в плюсе - закрываем ее if(OrderOpenPrice() > Ask) OrderClose(OrderTicket(),OrderLots(),Ask,slippage,Red); // если выбранная позиция в минисе - изменяем ее СтопЛосс в соответствии с новыми данными if(OrderOpenPrice() < Ask) OrderClose(OrderTicket(),OrderLots(),Ask,slippage,Red); } } } // Если есть 2 отложенных ордера, удаляем их if(OrdersNumber(symbol) == 2) DeleteOrders(symbol); // Если нет открытых позиций - расставим новые ордера if(OpenPositions(symbol) == 0) { buy_ticket = OrderSend(symbol,OP_BUYSTOP, lot, BuyStop, slippage, SL_for_Buy, TP_for_Buy, NULL, 0, 0, Red); //Здесь исправить. Основная функция, используемая для совершения торговых операций или установки отложенного ордера if(buy_ticket == -1) Alert("Ошибка установки бай-ордера ", GetLastError()); sell_ticket = OrderSend(symbol,OP_SELLSTOP, lot, SellStop, slippage, SL_for_Sell, TP_for_Sell, NULL, 0, 0, Red); if(sell_ticket == -1) Alert("Ошибка установки селл-ордера ", GetLastError()); } Sleep(60000*TimeFrame); // выполнили задачи и спать } // блок выше - выполняется один раз с началом новой недели, ниже проверка: // если в наличии всего ОДИН отложенный ордер - значит второй сработал и ордер должен быть удален; // другими словами - убираем за собой не сработавшие ордера if(OrdersNumber(symbol) == 1) DeleteOrders(symbol); Sleep(60000*TimeFrame); // выполнили задачи и спать return(0); } int OpenPositions(string symbol) { int k = 0; if(OrdersTotal() > 0) { for(int i = 1; i <= OrdersTotal(); i++) { if(OrderSelect(i-1,SELECT_BY_POS)==true && OrderSymbol() == symbol) k = k + 1; } } return(k); } int OrdersNumber(string symbol) { int k = 0; if(OrdersTotal() > 0) { for(int i = 1; i <= OrdersTotal(); i++) { if(OrderSelect(i-1,SELECT_BY_POS)==true && OrderSymbol() == symbol && OrderType() > 1) k = k + 1; } } return(k); } void DeleteOrders(string symbol) { for(int i = 1; i <= OrdersTotal(); i++) { if(OrderSelect(i-1,SELECT_BY_POS)==true && OrderSymbol() == symbol && OrderType() > 1) bool Ans = OrderDelete(OrderTicket()); } return(0); }
Но этим советником на реале торговать не безопасно, он только для тестера.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Попытался создать свой первый советник, а он чего-то не хочет работать. Стратегия такая: Каждую неделю в понедельник ставлю отложенные ордера BuyStop и SellStop на расстоянии 50п. от цены открытия недели. После того как одна из сделак открывается, вторую удаляю. В открытой сделке ТР=180п, SL=60п. Если стопы не срабатывают до конца недели, то закрываю сделку вручную в понедельник по цене открытия. Работа на дневном таймфрейме. Вот что у меня получилось:
Но почему-то не хочет работать, когда в тестет включаю выдает ошибки:
Подскажите пожалуйста что это значит. Что подправить надо? И сильно не ругайте, я только начал)