В данную библиотеку вложено очень много функций, которые ускорят разработку на языке MQL4, избавив от отвлечения на механику и сосредоточив внимание на логике. Например, чтобы открыть ордер на 0.4 лота, достаточно вызвать функцию OpenBuy(0.4). Естественно, что в подобных функциях не один параметр, остальные параметры заданы по умолчанию, но по необходимости можно заполнить и их.
В библиотеке есть обработчики RAD_onTick(), RAD_onInit(), RAD_onDeinit(). Они должны вызываться в советниках и индикаторах в соответствующих функциях и располагаться в самом их начале. Также предусмотрена конфигурация значений по умолчанию, например задание магического числа RAD_setMagic(...), символа RAD_setSymbol(...) и задание проскальзывания RAD_setSlippage(...). Также добавлен расширенный функционал работы со строками, массивами и дополнительные мат. операции. Для отладки приложения включается режим отладки RAD_DebugEnable(), и вставленный макрос RAD_DEBUG_ASSERT(...) в участки кода будет выводить в консоль заданные строки, макрос RAD_DEBUG_SECTION{....} будет запускать код в скобках при включении режима отладки, а при включенной функции логирования RAD_LogEnabled() выводить в лог-файл. Посмотреть описание остального множества функций можно в самом файле.
Вот пример кода некоторого абстрактного торгового советника:
//+------------------------------------------------------------------+
//| ProjectName |
//| Copyright 2012, CompanyName |
//| http://www.companyname.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#include <RAD_lib.mqh>
input int Magic=2143658709;
input int FastPeriod = 14;
input int SlowPeriod = 20;
input double Risk=10;
input int Stoploss=60;
input int Takeprofit=30;
//====================================================
int OnInit()
{
RAD_onInit(); //инициализация библиотеки
RAD_setProgramName("Mashka Expert"); //задание имени советника
RAD_setLogName(RAD_ProgramName()+"_logger.log"); //указание имени файла для ведения лога
RAD_setEquityBreakdown(40); //указываем допустимый уровень просадки по эквити. Проверяется по каждому тику
RAD_setMagic(Magic); //указываем стандартное значение мэджика
RAD_DebugEnable(); //включить режим отладки
RAD_LogEnable(); //запуск логгирования
return(INIT_SUCCEEDED);
}
//====================================================
void OnDeinit(const int reason)
{
RAD_onDeinit(); //пока что обработчик сего события пуст, но для будущего пусть будет
}
//====================================================
void OnTick()
{
RAD_onTick(); //обработка внутренних дел библиотеки
//наступил новый бар
if(isNewBar())
{
double fast = iMA(NULL, 0, FastPeriod, 0, MODE_EMA, PRICE_CLOSE, 0);//быстрая МА
double slow = iMA(NULL, 0, SlowPeriod, 0, MODE_EMA, PRICE_CLOSE, 0);//медленная МА
double lot=LotOnRisk(Risk);
RAD_ASSERT(0,"fast:"+fast+" slow:"+slow+" lot:"+lot);
//условия для открытия БАЙ, иначе СЕЛЛ
if(fast>slow)
{
RAD_ASSERT(1,"Open BUY order");
if(CountOrders(omBuy|omPoolTrades)==0) //проверка на уже открытие ордера БАЙ
OpenBuy(lot,Stoploss,Takeprofit); //открытие ордера БАЙ
}else{
RAD_ASSERT(2,"Open SELL order");
if(CountOrders(omSell|omPoolTrades)==0) //проверка на открытые ордера СЕЛЛ
OpenSell(lot,Stoploss,Takeprofit); //открытие ордера СЕЛЛ
}
}
}
//+------------------------------------------------------------------+
Естественно, такой советник не будет приносить прибыли, т.к. эту стратегию на "машках" мы все с вами знаем :)
Это только пример кода, видно, что не нужно никаких проверок на значения, не нужен расчёт стопов, не нужно писать специальные 100-кратно вложенные проверки ордера, всё это написано за вас в библиотеке. Ещё пример функций, который работает с ордерами:
Возвратит количество ордеров с любым мэджиком и символом типа BUY в пуле Trades
CountOrders(omBuy | omPoolTrades)
Возвратит количество ордеров типа SELL, SELL_STOP, SELL_LIMIT c мэджиком 123 и символом EURUSD в пуле History
CountOrders(omSells | omPoolHistory, 123, "EURUSD")
Возвратит количество ордеров типа BUY и BUY_STOP с мэджиком 123 и любым символом в пуле Trades
CountOrders(omBuy | omBuyStop | omPoolTrades, 123)
Закроет все ордера типов BUY, BUY_STOP, BUY_LIMIT с любым мэджиком и символом и вернёт их количество
CloseOrders(omBuys)
Закроет вообще все доступные на счёте ордера всех типов
CloseOrders(omAll)
Проверка принадлежности ордера к типам BUY или SELL в пуле Trades, мэджику 123 и символу EURUSD
if(isOrderFilter(ticket, omActive | omPoolTrades, 123, "EURUSD"))
Проверка принадлежности ордера к типу BUY в любом пуле, мэджику 123 и любому символу
if(isOrderFilter(ticket, omBuy | omPoolAll, 123, NULL))
Код выглядит просто и в то же время функционален и универсален.
Расширена работа с массивами. Теперь вам не придётся писать каждый раз код, который бы добавлял элемент в массив, теперь достаточно вызвать что-то вроде этого:
int a[];
ArrayAdd(a, 12);
ArrayAdd(a, 24);
ArrayAdd(a, 55);
ArrayAdd(a, 75); //массив будет выглядеть как [12,24,55,75]
Так же не замудрённо выглядит и удаление элементов из массива:
ArrayDel(a, 2); //удалит 3-й элемент массива, получится [12, 24,75]
Или так:
ArrayDel(a, 1, 3); //удалит три элемента, начиная с позиции 1. Получится [12]
Реализовано это через шаблоны функций для варианта передачи по значению и по ссылке
Если нужно скачать страницу из интернета, достаточно вызвать:
string page;
int size;
//Cкачается страница Гугла, используя 2 попытки при неудаче с интервалом между попытками 5 сек.
//То же самое с файлом, только во второй параметр записывается имя файла.
size = DownloadPage("http://www.google.com", page, 2, 5);
Обёрнуты эти страшные выражения MarketInfo(symbol, MODE_MAXLOT) в нормальные функции => MarketInfoMaxLot(Symbol()) Математический аппарат также расширился, поиск максимального значения из нескольких теперь не выглядит как куча вложенных MathMax(MathMax(MathMax...))), а реализовано вплоть до 5 аргументов через шаблоны функций и можно вызвать:
double max;
max = MathMax(12.4, 55.432, 128e-4, 8003.44);
А генерация случайных чисел в диапазоне от -34000 до 125000 выглядит вот так:
double random;
random = MathRandomDouble(-34000.0, 125000.0); //генерация случайного числа от -34000 до 125000
random = MathDiscrete(random, 100.0); //по желанию добавим дискретизацию случайного по 100
Впрочем, исходный код открыт, смотрите, дописывайте, предлагайте варианты по устройству библиотеки, её функционалу и общие замечания.