Ваши вопросы по языку MQL4

vladradon

Программист
Всем спасибо за идеи. Счас буду пробовать. Какой код получится выложу.
Могу подсобить кодом проверки на доступную маржу по лотам:
PHP:
bool MarginEnoughCheck(double lot)
  {
   if(AccountFreeMargin()<1) return(false);
   if(AccountFreeMargin()<lot*MarketInfo(_Symbol,MODE_MARGINREQUIRED)) return(false);
   return(true);
  }
Просто весь остальной код скорее всего нужно с нуля писать...
Ну а если в чем-то будет загвоздка, мой скайп в правом верхнем углу - чем смогу помогу, если буду на связи. Там же можно еще дополнить код тралом и тралом мультиинструментным с учетом ручных ордеров - я дам бесплатно - лишь бы не продавали налево код.
 
Последнее редактирование:

Buldakov

Местный житель
Могу подсобить кодом проверки на доступную маржу по лотам:
PHP:
bool MarginEnoughCheck(double lot)  {   if(AccountFreeMargin()<1) return(false);   if(AccountFreeMargin()<lot*MarketInfo(_Symbol,MODE_MARGINREQUIRED)) return(false);   return(true);  }
Просто весь остальной код скорее всего нужно с нуля писать...
Ну а если в чем-то будет загвоздка, мой скайп в правом верхнем углу - чем смогу помогу, если буду на связи. Там же можно еще дополнить код тралом и тралом мультиинструментным с учетом ручных ордеров - я дам бесплатно - лишь бы не продавали налево код.

Спасибо у меня это уже вроде есть.
Проверка на уровень минимальной суммы на счете:
if(AccountFreeMargin()<Profit_min)return(0);

Проверка на уровень минимальной маржи в процентах:
Level=(100*AccountEquity())/(MathAbs(AccountEquity()-AccountFreeMargin())+0.1);
if (Level>min_Level) ... ;
 

vladradon

Программист
Спасибо у меня это уже вроде есть.
Проверка на уровень минимальной суммы на счете:
if(AccountFreeMargin()<Profit_min)return(0);

Проверка на уровень минимальной маржи в процентах:
Level=(100*AccountEquity())/(MathAbs(AccountEquity()-AccountFreeMargin())+0.1);
if (Level>min_Level) ... ;
Ну... исходя из кода, там нет проверки доступной маржи для открытия ордера определенной лотности. А это может повлиять на работу - сов будет в цикле пытаться открыть ордер, который по лотности не проходит и выдавать ошибки в журнал, на которые брокер может отреагировать блокировкой сова или счета. На чемпионате 2012-го года более 3000 участников из около 3500 не прошли предварительный отбор именно из-за неграмотных команд или даже предупреждений о том, что на открытие ордера тупо не хватает маржи. Сам смотри, короче...
 

Buldakov

Местный житель
Да в этом коде проверки на размерность лота нет. Это код писался для советника который торгует по нескольким валютным парам на конкурсе. И там надо было ограничить уровень минимальной маржи. А формула для проверки доступной маржи для открытия ордера определенной лотности в данном случае мне не нужна. Поскольку в советнике я задаю фиксированный лот. Примерно 0.01 на каждые 500 дол. депозита.
 

vladradon

Программист
Да в этом коде проверки на размерность лота нет. Это код писался для советника который торгует по нескольким валютным парам на конкурсе. И там надо было ограничить уровень минимальной маржи. А формула для проверки доступной маржи для открытия ордера определенной лотности в данном случае мне не нужна. Поскольку в советнике я задаю фиксированный лот. Примерно 0.01 на каждые 500 дол. депозита.
Это понятно. Когда такие минимальные риски, то особо можно не беспокоиться. Если только эти ордера в любой момент, как с падением евро или франка при большом их (ордеров) количестве в сумме не уведут маржу в глубокую просадку. У меня знакомый из Киева заказывал скрипт-закрывашку по профиту и в его управлении больше 200 000$, и он попал в такую ситуацию, не смотря на то, что ордера все были минимальными, но их одновременно могло перевалить за 400 (20 ордеров по 20-ти парам) - он несколько месяцев нервно курил, пока не вылез из просадки.
 

MaVaDo2014

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

for (int i=0; i<OrdersTotal(); i++)
{
if(OrderSelect(i,SELECT_BY_POS && OrderSymbol()==Symbol() && magic==OrderMagicNumber()))
{
OT = OrderType();
OOP = NormalizeDouble(OrderOpenPrice(),Digits);
Lot = OrderLots();
Profit1=OrderProfit()+OrderCommission()+OrderSwap();
Profit+=OrderProfit()+OrderCommission()+OrderSwap();
if (Profit1>0) ProfitPlus+=Profit1;
if (MaxLot<Lot) MaxLot=Lot;
if (OT==OP_BUY)
{
if (MaxOrderBuy < OOP || MaxOrderBuy==0) {MaxOrderBuy = OOP; TicketB=OrderTicket(); LossBuy=Profit1;}
n++;
}
if (OT==OP_SELL)
{
if (MinOrderSell > OOP || MinOrderSell==0) {MinOrderSell = OOP; TicketS=OrderTicket(); LossSell=Profit1;}
n++;
}
if (OT>1) oo++;
}

}

//---
if (n==0) DeleteAll(0);
if (ProfitPlus+LossSell>CloseProfit && (LossBuy>(LossSell<0)))
{
if (OrderSelect(TicketS, SELECT_BY_TICKET))
{
if (OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),30,Red))
{
CloseAll();
Text(Lime,Low[0],StringConcatenate(DoubleToStr(ProfitPlus,2),DoubleToStr(LossSell,2)),0);
}
}
}
if (Profit>=ProfitClose && ProfitClose!=0)
{
Alert("Закрываем, Profit = "+DoubleToStr(Profit,2));
CloseAllOrders();
}

if (n==0 && oo==0)
{
ticket = OrderSend(Symbol(),OP_SELL,lot,NormalizeDouble(Bid,Digits),slippage,0,0,"",magic,0,Red);
Sleep (1000);
}
if (n==2 && oo==0)
{
ticket = OrderSend(Symbol(),OP_SELLSTOP,MaxLot*2,NormalizeDouble(Bid-Distanciya*Point,Digits),slippage,0,0,"",magic,0,Red);
Sleep (1000);
}

if (n==1 && oo==0)
{
ticket = OrderSend(Symbol(),OP_BUYSTOP,MaxLot*2,NormalizeDouble(Ask+Step*Point,Digits),slippage,0,0,"",magic,0,Blue);
Sleep (1000);
}
Но не могу понять работает он у меня правильно или все же где-то идет сбой, так как гонял в тестере вроде работает правильно но по окончании проверки выдает вот такой результат:
469 2017.08.21 23:59 close at stop 200 0.40 1.1815 0.0000 0.0000 -4930.48 5589.07
470 2017.08.21 23:59 close at stop 199 0.20 1.1813 0.0000 0.0000 2333.38 7922.45
471 2017.08.21 23:59 close at stop 198 0.10 1.1815 0.0000 0.0000 -1231.62 6690.83
что по задумке работы кода не может быть, так как ордер 199 должен был закрыть ордер 198 при достижении плюса между ордерами в 5.00 центов, а тут получается разница между ними 1101.76 центов, подозреваю, что на алгоритм работы каким то образом влияет переменная MaxLot. Буду очень признателен если поможете с условием закрытия по CloseProfit, и наставите меня бесталкового на путь истины.
 
Последнее редактирование модератором:

eevviill2

Местный знаток
1) Перебирай всегда ордера с конца.
2) Это не ошибка. Это просто сообщение что закнчилось тестирование и закрылись откртые ордера.
 

mobidik

-----
Люди добрые помогите разобраться, уже месяц мучаюсь, так как у самого не хватает знаний в программировании, которых кот наплакал, информатика на бейсике более 20-ти лет назад, но тем не менее, методом научного тыка и логики вещей решил я написать себе код советника и получился он у меня вот такой:
for (int i=0; i<OrdersTotal(); i++)
{
if(OrderSelect(i,SELECT_BY_POS && OrderSymbol()==Symbol() && magic==OrderMagicNumber()))
{
OT = OrderType();
OOP = NormalizeDouble(OrderOpenPrice(),Digits);
Lot = OrderLots();
Profit1=OrderProfit()+OrderCommission()+OrderSwap();
Profit+=OrderProfit()+OrderCommission()+OrderSwap();
if (Profit1>0) ProfitPlus+=Profit1;
if (MaxLot<Lot) MaxLot=Lot;
if (OT==OP_BUY)
{
if (MaxOrderBuy < OOP || MaxOrderBuy==0) {MaxOrderBuy = OOP; TicketB=OrderTicket(); LossBuy=Profit1;}
n++;
}
if (OT==OP_SELL)
{
if (MinOrderSell > OOP || MinOrderSell==0) {MinOrderSell = OOP; TicketS=OrderTicket(); LossSell=Profit1;}
n++;
}
if (OT>1) oo++;
}

}

//---
if (n==0) DeleteAll(0);
if (ProfitPlus+LossSell>CloseProfit && (LossBuy>(LossSell<0)))
{
if (OrderSelect(TicketS, SELECT_BY_TICKET))
{
if (OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),30,Red))
{
CloseAll();
Text(Lime,Low[0],StringConcatenate(DoubleToStr(ProfitPlus,2),DoubleToStr(LossSell,2)),0);
}
}
}
if (Profit>=ProfitClose && ProfitClose!=0)
{
Alert("Закрываем, Profit = "+DoubleToStr(Profit,2));
CloseAllOrders();
}

if (n==0 && oo==0)
{
ticket = OrderSend(Symbol(),OP_SELL,lot,NormalizeDouble(Bid,Digits),slippage,0,0,"",magic,0,Red);
Sleep (1000);
}
if (n==2 && oo==0)
{
ticket = OrderSend(Symbol(),OP_SELLSTOP,MaxLot*2,NormalizeDouble(Bid-Distanciya*Point,Digits),slippage,0,0,"",magic,0,Red);
Sleep (1000);
}

if (n==1 && oo==0)
{
ticket = OrderSend(Symbol(),OP_BUYSTOP,MaxLot*2,NormalizeDouble(Ask+Step*Point,Digits),slippage,0,0,"",magic,0,Blue);
Sleep (1000);
}
Но не могу понять работает он у меня правильно или все же где-то идет сбой, так как гонял в тестере вроде работает правильно но по окончании проверки выдает вот такой результат:
469 2017.08.21 23:59 close at stop 200 0.40 1.1815 0.0000 0.0000 -4930.48 5589.07
470 2017.08.21 23:59 close at stop 199 0.20 1.1813 0.0000 0.0000 2333.38 7922.45
471 2017.08.21 23:59 close at stop 198 0.10 1.1815 0.0000 0.0000 -1231.62 6690.83
что по задумке работы кода не может быть, так как ордер 199 должен был закрыть ордер 198 при достижении плюса между ордерами в 5.00 центов, а тут получается разница между ними 1101.76 центов, подозреваю, что на алгоритм работы каким то образом влияет переменная MaxLot. Буду очень признателен если поможете с условием закрытия по CloseProfit, и наставите меня бесталкового на путь истины.

eevviill2 Вам правильно ответил, но по коду есть ошибки:
вот здесь, какой тикет ордера Вы используете для закрытия?
PHP:
if (ProfitPlus+LossSell>CloseProfit && (LossBuy>(LossSell<0))) 
{
if (OrderSelect(TicketS, SELECT_BY_TICKET))
{
if (OrderClose(OrderTicket(),OrderLots(),NormalizeDou ble(Ask,Digits),30,Red))
...........
}
тут попадает первый попавшийся "под руку" советнику.
Да и что это за часть условия: (LossBuy>(LossSell<0)) - если упростить, то получается: (double>(bool)) - меняйте логику условия.
 
Последнее редактирование:

MaVaDo2014

Прохожий
Спасибо всем за участие в оказании помощи по написанию кода, о том, что тестер закончил работу это было понятно, но он не мог по задумке закончить таким образом работу, но я уже разобрался, проблема была не в коде, а в заданных значениях шага и дистанции, их нельзя ставить одинаковыми, а на счет условия (LossBuy>(LossSell<0)), это единственное условие которое не даёт закрываться Sell ордерам отдельно от Buy, а так вроде все работает вроде как задумано, конечно надо еще додумать алгоритм работы можно попасть в просадку, но и можно получать хороший результат
Символ EURUSD (Euro vs US Dollar)
Период 1 Минута (M1) 2017.03.21 19:10 - 2017.08.21 23:59 (2002.01.01 - 2017.08.22)
Модель Все тики (наиболее точный метод на основе всех наименьших доступных таймфреймов)
Параметры Step=5; Distanciya=3; CloseProfit=5; ProfitClose=5; lot=0.1; slippage=3; magic=0;
Баров в истории 95457 Смоделировано тиков 428010 Качество моделирования 24.97%
Ошибки рассогласования графиков 0
Начальный депозит 10000.00 Спред Текущий (2)
Чистая прибыль 10812.03 Общая прибыль 103267.64 Общий убыток -92455.61
Прибыльность 1.12 Матожидание выигрыша 8.67
Абсолютная просадка 8579.25 Максимальная просадка 11046.77 (88.60%) Относительная просадка 88.60% (11046.77)
Всего сделок 1247 Короткие позиции (% выигравших) 837 (72.04%) Длинные позиции (% выигравших) 410 (41.95%)
Прибыльные сделки (% от всех) 775 (62.15%) Убыточные сделки (% от всех) 472 (37.85%)
Самая большая прибыльная сделка 22492.67 убыточная сделка -16366.34
Средняя прибыльная сделка 133.25 убыточная сделка -195.88
Максимальное количество непрерывных выигрышей (прибыль) 10 (77.00) непрерывных проигрышей (убыток) 3 (-220.67)
Макс. непрерывная прибыль (число выигрышей) 22492.67 (1) непрерывный убыток (число проигрышей) -16366.34 (1)
Средний непрерывный выигрыш 2 непрерывный проигрыш 1
Graph
Еще раз всем спасибо. Но конечно если бы еще предложили какой индикатор для входа использовать было бы совсем не плохо.
 

mobidik

-----
на счет условия (LossBuy>(LossSell<0))

Вы не поняли, условие не верно составлено, я Вам ранее показал, что получается: (double>(bool)) - т.е, в условии: (LossSell<0) - получаем ответ true/false = да/нет = 1/0. Т.е, Вы сравниваете: (LossBuy>(да/нет)) - LossBuy - это у Вас значение профита ордера/ов, с ответом: true/да = 1 или false/нет = 0. Для компилятора это выглядит как (текущий профит > (1 или 0)) - ошибки нет, но и логики, так же, нет. Вы сравниваете не сравнимые параметры.
 

eevviill2

Местный знаток
МетаКроты.
Сделайте для OBJ_ARROW_RIGHT_PRICE количество знаков после точки.
 

eevviill2

Местный знаток
МетаКроты.
При установке #property level_color clrGrey индикатор рисует уровень с цветом clrSilver
Исправте не пожалуйста.
 

AlexeyVik

Программист mql4 mql5
Однажды глубокой ночью меня остановил инспектор ГАИ и спрашивает:
- Почему Вы не включили поворотку при перестроении в другой ряд?
На мой ответ:
- Я считаю что лучше уметь пользоваться зеркалами заднего вида, чем уметь пользоваться поворотками.
он ничего ответить не смог...
И вот ещё один пример бездумного, дебильного умения пользоваться поворотками.

1) Перебирай всегда ордера с конца.
 

eevviill2

Местный знаток
Я могу зайти через VPN, но не охота опять регистрироватся.
Может заглянут.
А может кто то передаст.
Исправление косяков у них не долго проходит. 6-9 месяцев:D
 

vladradon

Программист
Коллеги и читатели, сегодня ДР у Мобидика и предлагаю поздравить этого завсегдатая, который пытается всеми средствами поддержать новичков, и поставим ему "лайк" за его участие - ведь иногда хороший совет дороже денег!;)
 

DomovenokBrest

♔♕♖♗♘♙
Коллеги и читатели, сегодня ДР у Мобидика и предлагаю поздравить этого завсегдатая, который пытается всеми средствами поддержать новичков, и поставим ему "лайк" за его участие - ведь иногда хороший совет дороже денег!;)

Саня, дружище - с Днюхой!

399140f361939ea15bc09d4efc05751b.jpg
 

panand

Местный знаток
добрый день!
пожалуйста помогите исправить ошибку,может и не критическая, но порядок в коде важнее всякой мелочи.

код_трала_исправление.png

сам кусок кода и исправьте ,пожалуйста

if(OrderType()==OP_BUY) {
if(NormalizeDouble(Bid-OrderOpenPrice(),Digits)>NormalizeDouble(TrailingStop_1*Point,Digits)) {
if(NormalizeDouble(OrderStopLoss(),Digits)<NormalizeDouble(Bid-(TrailingStop_1+TrailingStep_1-1)*Point,Digits))
OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(Bid-TrailingStop_1*Point,Digits), OrderTakeProfit(), 0, CLR_NONE);
}
}

if(OrderType()==OP_SELL) {
if(NormalizeDouble(OrderOpenPrice()-Ask,Digits)>NormalizeDouble(TrailingStop_1*Point,Digits)) {
if(NormalizeDouble(OrderStopLoss(),Digits)>NormalizeDouble(Ask+(TrailingStop_1+TrailingStep_1-1)*Point,Digits))
OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(Ask+TrailingStop_1*Point,Digits), OrderTakeProfit(), 0, CLR_NONE);
}
}
 
Верх