PDA

View Full Version : Прошу дать совет



palmira27
09-09-2009, 18:28
Здравствуйте! Хотелось бы посоветоваться с более опытными пользователями MQL4 насчёт возможности создания советника по следующей стратегии:

Покупка:
1. Отложенный ордер на покупку выставляется на 1 пункт выше последнего фрактала, находящегося выше аллигатора, количество лотов= 5%*депозит/SL.
2. SL=цена открытия ордера-минимальная цена бара, на котором открылся ордер
3. TP=5*SL
4. После открытия ордера в случае преодоления следующего фрактала вверх - SL=0.
5. Ордер закрывается в случае образования сигнала на продажу и открывается соответвенно сигнал на продажу.

Продажа: аналогично покупке только наоборот.

Scriptong
10-09-2009, 09:27
Здравствуйте. Никаких сложностей с реализацией данного алгоритма не вижу. Если вы готовы немного потратиться на получение советника, работающего по данному описанию, то обращайтесь.

E-mail: мой_ник@mail.ru
ICQ: 482 тире 255 тире 876

carat
14-09-2009, 20:32
Здравствуйте!

У меня возникла проблема.

Некоторые ордена у меня отслеживаются скриптом, который должен определенным образом реагировать. А именно в этом случае автоматически выставить дополнительные ордена через дилинговую фирму. Однако этого не произошло. (Срабатывает определенный отложенный орден. Противоположный отложенный орден удаляется и выставляются дополнительные отложенные ордена. При этом, если компьютер был в этот момент выключен, то при включении должен после все сделать. Этого однако не было).
Орден: 4665442, 2009.08.27, 19:13, buy, eur/chf, закрыт 2009.08.31, 01:54. Это тот, который сработал, но при его срабатывании и после не было реакции скрипта.

Также хотел бы спросить, если при выходе из MetaTrader 4, а после его включении системы обнулила режим, чтобы скрипты работали (исчезает сама галочка напротив "Включить советники"), то что нужно сделать.

Жду обратной связи.

Александр

Scriptong
14-09-2009, 22:05
Вы, наверное, имели в виду ордеРа...

Трудно что-либо говорить, не видя кода скрипта. Ведь, скорее всего проблема в нем. Если же в скрипте уверены на 100%, то попробуйте проанализировать логи (закладка "Эксперты" в окне терминала). Может скрипт пишет там о каких-то ошибках.
Насчет галки "Включить советники" - ну как что делать? Включить ее да и все. Непонятно только, что обозначает "обнулила режим".

SK_
15-09-2009, 11:44
Есть галочки ещё в одном месте МТ4:
Меню Сервис-Настройки-Советники-
- Включить советники
- Разрешить советнику торговать
При таких настройках, возможно, не будет выключаться галочка, о которой идёт речь.

carat
16-09-2009, 11:53
2009.09.16 12:21:36 EURCHF,H1: uninit reason 6
2009.09.16 12:21:36 EURCHF,H1: deinitialized
2009.09.16 12:21:09 EURCHF,H1: initialized

Это в закладке "Эксперты" в окне терминала пишет каждый день.
Что означает reason 6?

carat
16-09-2009, 12:05
Вы, наверное, имели в виду ордеРа...

Трудно что-либо говорить, не видя кода скрипта. Ведь, скорее всего проблема в нем. Если же в скрипте уверены на 100%, то попробуйте проанализировать логи (закладка "Эксперты" в окне терминала). Может скрипт пишет там о каких-то ошибках.
Насчет галки "Включить советники" - ну как что делать? Включить ее да и все. Непонятно только, что обозначает "обнулила режим".

Уверен в скрипте.
А так как им уже неделю не пользуюсь, то в той закладке в окне терминала уже нет записей за те дни, когда возникли проблемы.

SK_
16-09-2009, 18:18
2009.09.16 12:21:36 EURCHF,H1: uninit reason 6
2009.09.16 12:21:36 EURCHF,H1: deinitialized
2009.09.16 12:21:09 EURCHF,H1: initialized

Это в закладке "Эксперты" в окне терминала пишет каждый день.
Что означает reason 6?
Это код причины деинициализации, которая выполняется при различных условиях.

6 - это переключение на другой счёт.
http://docs.mql4.com/ru/constants/uninit

carat
17-09-2009, 12:45
Это код причины деинициализации, которая выполняется при различных условиях.

6 - это переключение на другой счёт.
http://docs.mql4.com/ru/constants/uninit

А нигде в другом месте не сохраняются сообщения, которые отражаются в разделе "Эксперты" в Метатрейдере?

SK_
17-09-2009, 14:20
Сохраняются в логах.
Есть логи терминала (в основном каталоге, logs), есть логи экспертов (в experts/logs).

carat
17-09-2009, 21:30
У меня сегодня на Демо счете было так:
gbp/chf валюта. Ордер был на продажу открыт. Текущая цена на графике 1.6895, а внизу в ордере текущая цена 1.6905. Тейк-профит поставлен на 1.6900. Так он в 10 пунктов разницу постоянно держал.
В чем может быть причина?
Спасибо!

SK_
17-09-2009, 22:40
У меня сегодня на Демо счете было так:
gbp/chf валюта. Ордер был на продажу открыт. Текущая цена на графике 1.6895, а внизу в ордере текущая цена 1.6905. Тейк-профит поставлен на 1.6900. Так он в 10 пунктов разницу постоянно держал.
В чем может быть причина?
Спасибо!
На мой взгляд, это явный глюк терминала. Подобные неприятности иногда случаются. В подобных случаях лучше всего перегрузить ПК.

Scriptong
18-09-2009, 18:12
У меня сегодня на Демо счете было так:
gbp/chf валюта. Ордер был на продажу открыт. Текущая цена на графике 1.6895, а внизу в ордере текущая цена 1.6905. Тейк-профит поставлен на 1.6900. Так он в 10 пунктов разницу постоянно держал.
В чем может быть причина?
Спасибо!
Тут нужно уточнить: текущая цена какая - Bid или Ask? По описанной ситуации складывается впечатление, что вы наблюдали цену Bid, в то время как Ask был на 10 пунктов выше. Выходит, что спрэд по указанной валютной паре - 10 пунктов. Почему вы его не учитываете при открытии сделки?

carat
18-09-2009, 18:39
Не могли бы дать ссылку, где было бы подробно и доступно рассказано про это? Спасибо!

SK_
21-09-2009, 12:40
Не могли бы дать ссылку, где было бы подробно и доступно рассказано про это? Спасибо!
http://book.mql4.com/ru/trading/orders

palmira27
24-09-2009, 14:03
Здравствуйте.

Помогите разобраться! Никак не могу понять, почему действуя по коду написанному ниже у меня на одном баре одновременно не действует принцип - закрыть текущий ордер и открыть противоположный. Если закрывает на текущем баре, то по идее он должен на нем же открыть противоположный, а он открывает его только на следующем. Почему так?

//-----------------------------------------------------------------------
//Закрытие ордеров
while(tr

ue) // Цикл закрытия орд.
{
if (Tip==0 && Cls_B==true) // Открыт ордер Buy..
{ //и есть критерий закр
Alert("Попытка закрыть Buy ",Ticket,". Ожидание ответа..");
RefreshRates(); // Обновление данных
Ans=OrderClose(Ticket,Lot,Bid,2); // Закрытие Buy
if (Ans==true) // Получилось :)
{
Alert ("Закрыт ордер Buy ",Ticket);
break; // Выход из цикла закр
}
if (Fun_Error(GetLastError())==1) // Обработка ошибок
continue; // Повторная попытка
return; // Выход из start()
}

if (Tip==1 && Cls_S==true) // Открыт ордер Sell..
{ // и есть критерий закр
Alert("Попытка закрыть Sell ",Ticket,". Ожидание ответа..");
RefreshRates(); // Обновление данных
Ans=OrderClose(Ticket,Lot,Ask,2); // Закрытие Sell
if (Ans==true) // Получилось :)
{
Alert ("Закрыт ордер Sell ",Ticket);
break; // Выход из цикла закр
}
if (Fun_Error(GetLastError())==1) // Обработка ошибок
continue; // Повторная попытка
return; // Выход из start()
}
break; // Выход из while
}
//---------------------------------------------------------------
// Открытие ордеров

while(true) // Цикл закрытия орд.
{
if (Total==0 && Opn_B==true) // Открытых орд. нет +
{ // критерий откр. Buy
RefreshRates(); // Обновление данных
SL=Bid - New_Stop(StopLoss)*Point; // Вычисление SL откр.
TP=Bid + New_Stop(TakeProfit)*Point; // Вычисление TP откр.
Alert("Попытка открыть Buy. Ожидание ответа..");
Ticket=OrderSend(Symb,OP_BUY,Lts,Ask,2,SL,TP);//Открытие Buy
if (Ticket > 0) // Получилось :)
{
Alert ("Открыт ордер Buy ",Ticket);
return; // Выход из start()
}
if (Fun_Error(GetLastError())==1) // Обработка ошибок
continue; // Повторная попытка
return; // Выход из start()
}
if (Total==0 && Opn_S==true) // Открытых орд. нет +
{ // критерий откр. Sell
RefreshRates(); // Обновление данных
SL=Ask + New_Stop(StopLoss)*Point; // Вычисление SL откр.
TP=Ask - New_Stop(TakeProfit)*Point; // Вычисление TP откр.
Alert("Попытка открыть Sell. Ожидание ответа..");
Ticket=OrderSend(Symb,OP_SELL,Lts,Bid,2,SL,TP);//Открытие Sel
if (Ticket > 0) // Получилось :)
{
Alert ("Открыт ордер Sell ",Ticket);
return; // Выход из start()
}
if (Fun_Error(GetLastError())==1) // Обработка ошибок
continue; // Повторная попытка
return; // Выход из start()
}
break; // Выход из while
}

Scriptong
24-09-2009, 15:53
Из приведенного кода озвученную проблему найти невозможно. Нужен полный код, а не его кусочек. Единственное, что можно предположить - вы проверяете эксперта не онлайн, а в тестере. При этом используетет метод тестирования "По ценам открытия". Тогда для советника на каждый бар приходится только один тик. А у вас после закрытия позиции информация в переменной Total не обновляется. Видимо, обновление происходит в непоказанной части кода. Но в любом случае новое значение Total получает только с новым тиком, что в тестере уже соответствует новому бару.

Если же вы тестируете по "Всем тикам", то проблема может возникать, если в советнике заложен принцип контроля нового бара, причем заложен не совсем корректно. Тогда, опять же, срабатывает алгоритм, описанный выше.

Но это всего лишь догадки. Без полного кода трудно о чем-то однозначно судить.

P. S. Пожалуйста, в следующий раз для вставки кода используйте BB-код CODE (в расширенном режиме пиктограмма #):

return(0);
или просто прикрепляйте файл mq4

palmira27
24-09-2009, 18:23
Спасибо большое за подсказку! Разобралась! Действительно, всё дело было в том, что Total не обновлялся.

palmira27
24-09-2009, 18:54
Была бы очень признательна, если бы Вы мне ещё посоветовали, как правильно модифицировать ордер, чтобы SL рыночного ордера становился равным 0 при условии, что минимум последнего бара выше цены ордера - если ордер на покупку, и максимум последнего бара ниже цены ордера - если ордер на продажу.
Я модифицирую следующим способом:

// Учёт ордеров
Symb=Symbol(); // Название фин.инстр.
Total=0; // Количество ордеров
for(int i=1; i<=OrdersTotal(); i++) // Цикл перебора ордер
{
if (OrderSelect(i-1,SELECT_BY_POS)==true) // Если есть следующий
{ // Анализ ордеров:
if (OrderSymbol()!=Symb)continue; // Не наш фин. инструм
if (OrderType()>1) // Попался отложенный
{
Alert("Обнаружен отложенный ордер. Эксперт не работает.");
return; // Выход из start()
}
Total++; // Счётчик рыночн. орд
if (Total>1) // Не более одного орд
{
Alert("Несколько рыночных ордеров. Эксперт не работает.");
return; // Выход из start()
}
Ticket=OrderTicket(); // Номер выбранн. орд.
Tip =OrderType(); // Тип выбранного орд.
Price =OrderOpenPrice(); // Цена выбранн. орд.
SL =OrderStopLoss(); // SL выбранного орд.
TP =OrderTakeProfit(); // TP выбранного орд.
Lot =OrderLots(); // Количество лотов
}
}
//------------------------------------------------------------------
//Модификация
int Min_Dist=MarketInfo(Symb,MODE_STOPLEVEL);//Миним. Дист
bool Modify=false; // Не назначен к модифи
switch(Tip) // По типу ордера
{
case 0 : // Ордер Buy
minmax=iLow(0,0,1);
if(minmax>Price&&Bid>Price+Min_Dist)
{
SL=Price;
string Text="Buy "; // Текст для Buy
Modify=true; // Назначен к модифи.
}
break; // Выход из switch
case 1 : // Ордер Sell
minmax=iHigh(0,0,1);
if(minmax<Price&&Ask<Price-Min_Dist)
{
SL=Price;
Text="Sell "; // Текст для Buy
Modify=true; // Назначен к модифи.
}
break; // Выход из switch
}



Alert ("Модификация ",Text,Ticket,". Ждём ответ..");
Ans=OrderModify(Ticket,Price,SL,TP,0);//Модифи


Но выдает ошибку 4051 и пишет - "invalid ticket for OrderModify function".
Не могу понять, что не так?

Bagama
05-10-2010, 09:24
Добрый день!
Готов компенсировать затраты Вашего времени на решение моей задачки :)
Я новичок в МQL4 и может мой вопрос показаться Вам банальным но я над ним уже третий день бьюсь... (
Пишу советник для торговли по мувингу.
При тестировании Советник работает, однако при попытке изменить стоп лосс в журнале высвечивается сообщение "ordermodify error 4051" и затем "invalid ticket for ordermodify function".
Вот код:
//+------------------------------------------------------------------+
#define MAGICMA 20050610

extern double Lots = 0.1;
extern double SL = 0.0025;
extern double TP = 0.0040;
extern double TrailingStop = 150;
extern double MovingPeriod = 90;
extern double MovingShift = 0;

//+------------------------------------------------------------------+
//| Calculate open positions |
//+------------------------------------------------------------------+
double ma;
bool res;
bool resm;
int err;
int CalculateCurrentOrders(string symbol)
{
int buys=0,sells=0;
//----
for(int i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
{
if(OrderType()==OP_BUY) buys++;
if(OrderType()==OP_SELL) sells++;
}
}
//---- return orders volume
if(buys>0) return(buys);
else return(-sells);
}
//+------------------------------------------------------------------+
//| Check for open order conditions |
//+------------------------------------------------------------------+
void CheckForOpen()
{
double ma;
//---- go trading only for first tiks of new bar
if(Volume[0]>1) return;
//---- get Moving Average
ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_EMA,PRICE_CLOSE,0);
//---- sell conditions
if(Open[1]>ma && Close[1]<ma)
{
res=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,MarketInfo(Symbol(),MODE_BID)+SL,MarketInfo(Symbol(),MODE_ASK)-TP,"",MAGICMA,0,Red);
return;
}
//---- buy conditions
if(Open[1]<ma && Close[1]>ma)
{
res=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,MarketInfo(Symbol(),MODE_BID)-SL,MarketInfo(Symbol(),MODE_ASK)+TP,"",MAGICMA,0,Blue);
return;
}
//----
}
//+-------------------------------------------------+
//| Calculating trailing Stop |
//+-------------------------------------------------+
void TraStop()
{
//---- go trading only for first tiks of new bar
if(Volume[0]>1) return;
//-----------------------------------------------------------------------------------------------
if(OrderType()==OP_BUY)
{
OrderSelect(MAGICMA,SELECT_BY_TICKET);
if(Bid-TrailingStop*Point>OrderStopLoss( ))
{
resm=OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(Bid-TrailingStop*Point, Digits),0,0,Yellow);

if (resm==true) Print ("Succesfully modified", OrderStopLoss())
;else Print ("Error modifying # ", GetLastError());
return;
}
}
//------------------------------------------------------------------------------------------------
if(OrderType()==OP_SELL)
{
OrderSelect(MAGICMA,SELECT_BY_TICKET);
if(Ask+TrailingStop*Point>OrderStopLoss( ))
{
OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(Ask+TrailingStop*Point,Digits),0,0,Green);
return;
}
}
}
//+------------------------------------------------------------------+
//| Start function |
//+------------------------------------------------------------------+
void start()
{
//---- check for history and trading
if(Bars<100 || IsTradeAllowed()==false) return;
//---- calculate open orders by current symbol
if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
else TraStop();
//----
}
//+------------------------------------------------------------------+

Scriptong
05-10-2010, 16:50
Но выдает ошибку 4051 и пишет - "invalid ticket for OrderModify function".
Не могу понять, что не так?

Дело в том, что нумерация элементов списка ордеров начинается с 0, а не с 1. Поэтому цикл нужно начинать не с 1 и до OrdersTotal(), а с 0 и до OrdersTotal()-1:

for (i = 0; i < OrdersTotal(); i++)

В случае присутствия всего одного ордера ваш советник просто не находил его и переходил к модификации.

Кстати, именно этот вариант вообще не учтен в вашем коде. Прежде чем модифицировать ордер нужно проверить, что ордер найден. Для вашего кода хотя бы так:

if (Total == 1)
{
// модификация
}

Scriptong
05-10-2010, 17:03
Добрый день!
Готов компенсировать затраты Вашего времени на решение моей задачки :)
Я новичок в МQL4 и может мой вопрос показаться Вам банальным но я над ним уже третий день бьюсь... (
Пишу советник для торговли по мувингу.
При тестировании Советник работает, однако при попытке изменить стоп лосс в журнале высвечивается сообщение "ordermodify error 4051" и затем "invalid ticket for ordermodify function".
Вот код:


Эту ошибку вы получаете при попытке модификации ордера в теле функции TraStop. Случается это из-за того, что вы просто не выбрали ордер. Сначала вы узнаете тип ордера:

if (OrderType() == OP_BUY)
Уже здесь непонятно: тип какого ордера вы узнаете, если ордер еще не был выбран? А затем вы выбираете ордер:

OrderSelect(MAGICMA, SELECT_BY_TICKET)
что также не даст результата, т.к. MAGICMA - это магик вашего советника, а не тикет ордера.

Итак, перед модификацией ордера произведите его выбор. Простейший способ - перебрать все имеющиеся ордера и в момент нахождения своего ордера модифицировать:

for(int i=0;i<OrdersTotal();i++)
if (OrderSelect(i, SELECT_BY_POS))
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MAGICMA)
{
if (OrderType()==OP_BUY)
{
// модификация Buy
}
if (OrderType() == OP_SELL)
{
// модификация Sell
}
}

Но более оптимальным способом было бы сохранение тикетов всех найденных "своих" ордеров в специальных переменных в уже имеющейся функции CalculateCurrentOrders.