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

sergeysv

Активный участник
Приветствую--
Подскажите пожалуйста как подсчитать общий риск в % открытых ордеров?
Как бы какой уже будет убыток в % если снесёт стопы по открытым позам.
То есть один ордер с риском 0.15% от депо,второй 0.30%---=итого 0.45% на столе и так далее...
int i, nb = 0, ns = 0;
double buys_volume = 0.0, sells_volume = 0.0;
double Total_RISK = 0.0;
double buys_list[50][3];
double sells_list[50][3];
for(i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break;
if(OrderType() == OP_BUY)
{
buys_list[nb][0] = OrderTicket();
buys_list[nb][1] = OrderProfit();
buys_list[nb][2] = OrderLots();
buys_volume += buys_list[nb][2];
nb++;
}
if(OrderType() == OP_SELL)
{
sells_list[ns][0] = OrderTicket();
sells_list[ns][1] = OrderProfit();
sells_list[ns][2] = OrderLots();
sells_volume += sells_list[ns][2];
ns++;
}
}
// Total_RISK = ????? ;
 

sergeysv

Активный участник
В этом коде вроде правильно только не плюсует в кучу............
for(i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break;
if(OrderType() == OP_BUY)
{
buys_list[nb][0] = OrderTicket();
buys_list[nb][1] = OrderProfit();
buys_list[nb][2] = OrderLots();
buys_volume += buys_list[nb][2];

Total_RISK =NormalizeDouble ( (100*(((OrderStopLoss() - OrderOpenPrice())/Point)*MarketInfo(Symbol(),
MODE_TICKVALUE)*OrderLots()))/AccountBalance(),2);
nb++;
}
if(OrderType() == OP_SELL)
{
sells_list[ns][0] = OrderTicket();
sells_list[ns][1] = OrderProfit();
sells_list[ns][2] = OrderLots();
sells_volume += sells_list[ns][2];

Total_RISK = NormalizeDouble ( (100*(((OrderOpenPrice() - OrderStopLoss())/Point)*MarketInfo(Symbol(),
MODE_TICKVALUE)*OrderLots()))/AccountBalance(),2);

ns++;
}
}
 

vladradon

Программист
Rep Report
В этом коде вроде правильно только не плюсует в кучу............
Попробуй так:
в строке if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break; замени "break" на "continue" -
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) continue;
в строках Total_RISK = ... добавь "+" -
Total_RISK += ...
 

sergeysv

Активный участник
замени "break" на "continue"
С этим понятно:)

На это ругается....
А такое вообще возможно?
Часов надсать пытаюсь сделать...
for(i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) continue;
if(OrderType() == OP_BUY)
{
buys_list[nb][0] = OrderTicket();
buys_list[nb][1] = OrderProfit();
buys_list[nb][2] = OrderLots();
buys_volume += buys_list[nb][2];
Total_RISK = +NormalizeDouble ( (100*(((OrderStopLoss() - OrderOpenPrice())/Point)*MarketInfo(Symbol(),
MODE_TICKVALUE)*OrderLots()))/AccountBalance(),2);
nb++;
}
if(OrderType() == OP_SELL)
{
sells_list[ns][0] = OrderTicket();
sells_list[ns][1] = OrderProfit();
sells_list[ns][2] = OrderLots();
sells_volume += sells_list[ns][2];
Total_RISK = + NormalizeDouble ( (100*(((OrderOpenPrice() - OrderStopLoss())/Point)*MarketInfo(Symbol(),
MODE_TICKVALUE)*OrderLots()))/AccountBalance(),2);
ns++;
}
}
 

vladradon

Программист
это был третий заход тыкания.......
ругалось на + пробел =
не успел проверить....
Благодарю
Кстати, перед этими расчетами нужно все переменные обнулять:
PHP:
buys_volume=0.0;
sells_volume=0.0;
nb=0;
ns=0;
Total_RISK=0.0;
for(i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) continue; 
if(OrderType() == OP_BUY)
{
buys_list[nb][0] = OrderTicket();
buys_list[nb][1] = OrderProfit();
buys_list[nb][2] = OrderLots();
buys_volume += buys_list[nb][2];
Total_RISK += NormalizeDouble ( (100*(((OrderStopLoss() - OrderOpenPrice())/Point)*MarketInfo(Symbol(),
MODE_TICKVALUE)*OrderLots()))/AccountBalance(),2);
nb++;
} 
if(OrderType() == OP_SELL)
{
sells_list[ns][0] = OrderTicket();
sells_list[ns][1] = OrderProfit();
sells_list[ns][2] = OrderLots();
sells_volume += sells_list[ns][2];
Total_RISK +=  NormalizeDouble ( (100*(((OrderOpenPrice() - OrderStopLoss())/Point)*MarketInfo(Symbol(),
MODE_TICKVALUE)*OrderLots()))/AccountBalance(),2); 
ns++;
} 
}
Массивы buys_list и sells_list должны быть double, но тикеты buys_list[х][0] и sells_list[х][0] потом при использовании нужно преобразовывать в int типа int ticket=(int)buys_list[х][0]; где х- какой-то номер ордера по порядку.
 
Последнее редактирование:

vladradon

Программист
Хорошая новость для приверженцев mql4.
В следующем билде mql5 будут доступны такие функции из mql4 как iTime, iOpen, iHigh..., iHighest, iLowest, iBarShift
Привет! Слушай, ты не в курсе, почему 5-й терминал на оптимизации ядра и на половину не загружены, а память скачет от 30 до 100% периодически - че они там творят. Последние 2 обновления МТ5 - сначала пропал обзор проходов "Оптимизация" и стал появляться только при остановке оптимизатора, в последнем обновлении все восстановилось и проходы можно анализировать в процессе оптимизации. Терминал работает вообще непонятно как - пол часа что-то перелопачивает, загружая всю память (увеличил файл подкачки до 20Гб) и где-то через час освобождается основная память, процессор загружается меньше половины, но винт при этом не дает компу работать вообще... Ты писал, что перешел на 5-ку, поэтому и спрашиваю, если знаешь что-то по этому поводу. Я может быть завтра создам тему торговли по треугольникам - задолбался один оптимизировать на 5-ке))).
 
Последнее редактирование:

AlexeyVik

Программист mql4 mql5
Привет! Слушай, ты не в курсе, почему 5-й терминал на оптимизации ядра и на половину не загружены, а память скачет от 30 до 100% периодически - че они там творят. Последние 2 обновления МТ5 - сначала пропал обзор проходов "Оптимизация" и стал появляться только при остановке оптимизатора, в последнем обновлении все восстановилось и проходы можно анализировать в процессе оптимизации. Терминал работает вообще непонятно как - пол часа что-то перелопачивает, загружая всю память (увеличил файл подкачки до 20Гб) и где-то через час освобождается основная память, процессор загружается меньше половины, но винт при этом не дает компу работать вообще... Ты писал, что перешел на 5-ку, поэтому и спрашиваю, если знаешь что-то по этому поводу. Я может быть завтра создам тему торговли по треугольникам - задолбался один оптимизировать на 5-ке))).
-https://www.mql5.com/ru/forum/241285
Здесь 25 страниц обсуждения изменений режима оптимизации. Но я это читал совершенно невнимательно и выборочно только ответы разработчиков. Я не пользуюсь оптимизацией и поэтому меня это не касается, сам понимаешь что ничего из прочитанного не помню. Помню только что после повторного запуска оптимизация не сначала запускается, а продолжается с места остановки. И по результатам обсуждения были внесены какие-то исправления в новых билдах.


Для Milord, это можно считать доказательством того, что на нормальное обсуждение проблем разработчики реагируют.
И вот ещё.

-https://www.mql5.com/ru/forum/257552/page10#comment_7866159
Доказательства нужны железобетонные, а не на основе одиночного запуска. У вас разница в 4.5 секунды на 153 секундном промежутке, всего 3% и выглядит как погрешность.

Учтите, что в терминале и агентах огромнейшее влияние имеют кеши, накопленные данные и разные состояния горячести. Даже файловый кеш операционки запросто даст видимую разницу.


Чтобы результаты тестов были достоверными, нужно удовлетворить следующие условия:

  1. Убрать все лишние программы, вплоть до броузеров. Вне зависимости от того, что вы думаете о "да это не влияет, я же вижу что там 0-1% нагрузки".
  2. Перевести режим энергосбережения операционки в "Максимальная производительность" (а лучше выключить C-states в биосе), чтобы не скакала частота CPU и не чередовались режимы бустинга ядер.

    Это одна из самых частых ошибок в замерах производительности, когда люди вообще не обращают внимания, что у них частота процессора в рилтайме плавает от 1.5 до 3 ггц. Разброс это дает в десятки процентов иногда. У вас 3% разницы.

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

    Да, это обязательно.
  4. Провести 1 полное тестирование в обоих случаях, чтобы удостовериться, что все данные подкачаны на агента
  5. Выгрузить терминалы, чтобы не оставались в памяти горячие кеши и фоновой поднятый агент с кешами

    Терминал держит использованных агентов фоном в активном состоянии, что дает серьезное ускорение на повторных запусках за счет горячих кешей. Выгрузка терминала приводит к выгрузке фоновых агентов и сбросу кешей.
  6. Запустить терминал и провести 3 одиночные теста в каждом режиме, обязательно перезапуская терминал, чтобы был холодный тест
После этого публикация 6 отчетов с указанием, что выполнены 6 условий выше, может приниматься как минимально приемлемое тестирование.
 

sergeysv

Активный участник
Благодарю--почти нормально плюсует отнимает
Помогите пожалуйста объяснить что ему нужно учитывать чистый убыток по ордеру а то не добирает по убытку--не хватает +комисс +спрэд ну и своп...
OrderProfit() + OrderCommission() + OrderSwap() не работает....
if (Point == 0.00001) Poin = 0.0001; //5 digits
else if (Point == 0.001) Poin = 0.01; //3 digits
else Poin = Point; //Normal
double spreadtot, spreadtotoff;
spreadtot = MarketInfo(Symbol(), MODE_SPREAD);
if ((Poin > Point) && (normal_pips_Spred))
{ divider = 10.0;
n_digits = 1;
}
spreadtotoff=(OrderLots()*spreadtot/divider);
for(i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) continue;
if(OrderType() == OP_BUY)
{
buys_list[nb][0] = OrderTicket();
buys_list[nb][1] = OrderProfit();
buys_list[nb][2] = OrderLots();
buys_volume += buys_list[nb][2];
Total_RISK += NormalizeDouble ((((OrderStopLoss() - OrderOpenPrice())/Point)*MarketInfo(Symbol(),
MODE_TICKVALUE)*OrderLots() ) *100 /AccountBalance(),2);
nb++;
}
if(OrderType() == OP_SELL)
{
sells_list[ns][0] = OrderTicket();
sells_list[ns][1] = OrderProfit();
sells_list[ns][2] = OrderLots();
sells_volume += sells_list[ns][2];
Total_RISK += NormalizeDouble ((((OrderOpenPrice() - OrderStopLoss())/Point)*MarketInfo(Symbol(),
MODE_TICKVALUE)*OrderLots() ) *100 /AccountBalance(),2);
ns++;
}
}
 
Последнее редактирование:

vladradon

Программист
Помогите пожалуйста объяснить что ему нужно учитывать чистый убыток по ордеру а то не добирает по убытку--не хватает +комисс +спрэд ну и своп...
Если закладывать в расчет своп и комиссию, то это должно быть так (надеюсь, в скобках не ошибся):
PHP:
for(i=0; i<OrdersTotal(); i++)
     {
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if(OrderType()==OP_BUY)
        {
         buys_list[nb][0] = OrderTicket();
         buys_list[nb][1] = OrderProfit();
         buys_list[nb][2] = OrderLots();
         buys_volume+= buys_list[nb][2];
         Total_RISK += NormalizeDouble(((((OrderStopLoss() - OrderOpenPrice())/Point)*MarketInfo(Symbol(),MODE_TICKVALUE)*OrderLots())
+OrderSwap()+OrderCommission()) *100/AccountBalance(),2);
         nb++;
        }
      if(OrderType()==OP_SELL)
        {
         sells_list[ns][0] = OrderTicket();
         sells_list[ns][1] = OrderProfit();
         sells_list[ns][2] = OrderLots();
         sells_volume+=sells_list[ns][2];
         Total_RISK+=NormalizeDouble(((((OrderOpenPrice()-OrderStopLoss())/Point)*MarketInfo(Symbol(),MODE_TICKVALUE)*OrderLots())
+OrderSwap()+OrderCommission()) *100/AccountBalance(),2);
         ns++;
        }
     }

Не знаю, зачем там нужны вычисления знаков после запятой...
 
Последнее редактирование:

sergeysv

Активный участник
зачем там нужны вычисления знаков
Так это---стремимся чтоб как в аптеке...
По вашему пробовал- не сходится нетто с брутто...:)
А обязательно нужно ордера по типу разделять?
Задача ведь сложить риск на столе в % при сносе стопов.
Может есть пилюля универсальная? те массивы ордера и лоты считают и как бы в вопросе не участвуют..
Для продаж вроде сходится...
for(i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) continue;
if(OrderType() == OP_BUY)
{
/* Total_RISK += DoubleToStr ((((OrderStopLoss() -
OrderOpenPrice())/Point)*
MarketInfo(Symbol(),MODE_TICKVALUE)*OrderLots())
*100 /AccountBalance(),2); */
}

if(OrderType() == OP_SELL)
{
Total_RISK += NormalizeDouble ( ( (((OrderOpenPrice() - OrderStopLoss())/Point)*
MarketInfo(Symbol(), MODE_TICKVALUE)*OrderLots()) + ((OrderLots()*OrderCommission())+spreadtotoff) )
*100 /AccountBalance(),2);

}
}
 

vladradon

Программист
По вашему пробовал- не сходится нетто с брутто...
А обязательно нужно ордера по типу разделять?
Задача ведь сложить риск на столе в % при сносе стопов.
Тут вопрос... Для точности может быть стоит заменить AccountBalance() на AccountEquity(). У тебя прописываются данные по ордерам бай и селл в отдельные массивы - если это нужно, то разделение на бай и селл, конечно, обязательно. Или можно просто так сделать (можно даже вынести это отдельными строками):
PHP:
for(int i=0; i<OrdersTotal(); i++)
  if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
    Total_RISK += NormalizeDouble(((((MathAbs(OrderStopLoss()-OrderOpenPrice()))/Point)*MarketInfo(Symbol(),MODE_TICKVALUE)*OrderLots())+OrderSwap()+OrderCommission())*100/AccountBalance(),2);
Только в if стоит добавить проверку на инструмент и магик...
 
Последнее редактирование:

vladradon

Программист
еня от незнания смущает почему на селл
((OrderOpenPrice() - OrderStopLoss())/Point)
а на бай ((OrderStopLoss() - OrderOpenPrice())/Point)
поэтому и спрашивал за пилюлю универсальную...
Для баевского ордера стоплосс находится ниже цены открытия, для селовского выше (наоборот). Но это можно не учитывать, если использовать модуль разницы, который будет выдавать неотрицательное значение в любом случае. Есть нюанс в случае работы трала, который может стоплосс переместить в плюсовую зону и тогда расчеты будут не верны - это нужно отдельно учитывать. Для суммирования ордеров с разных по знакам после запятой инструментов можно сделать так:
PHP:
for(i=0; i<OrdersTotal(); i++)
  if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
    Total_RISK += NormalizeDouble(((((MathAbs(OrderStopLoss()-OrderOpenPrice()))/MarketInfo(OrderSymbol(),MODE_POINT))*MarketInfo(OrderSymbol(),MODE_TICKVALUE)*OrderLots())+OrderSwap()+OrderCommission())*100/AccountBalance(),2);
 

sergeysv

Активный участник
Благодарю :)
Всё равно 2-3% теряются в недрах.......
 
Последнее редактирование:

vladradon

Программист
Rep Report
Благодарю
Всё равно 2-3% теряются в недрах.......
Можешь мне на скайп звякнуть? Мне как раз сейчас скучно и онлайн все порешаем. Просто не зная всех мелочей, сложно запрограммировать все нюансы. Я еще час буду на связи в скайпе точно.
 
Верх