include и import не обязательно вместе использовать. Можно или include или import использовать. Можно и вместе, конечно, но они не связаны между собой.
Проще всего include. Создаем файл mqh, сохраняем в папке include. Потом подключаем его:
#include <filename.mqh>
После этого вызываем функции из этого файла точно так же, как будто они находятся в основном файле.
Имя файла в угловых скобках означает, что подключаемый файл находиться в папке include.
Можно и в кавычках писать имя, например:
#include "filename.mqh"
В кавычках путь относительно основного файл. В этом примере - в той же папке, что и основной файл.
include и import не обязательно вместе использовать. Можно или include или import использовать. Можно и вместе, конечно, но они не связаны между собой.
Проще всего include. Создаем файл mqh, сохраняем в папке include. Потом подключаем его:
После этого вызываем функции из этого файла точно так же, как будто они находятся в основном файле.
Имя файла в угловых скобках означает, что подключаемый файл находиться в папке include.
Можно и в кавычках писать имя, например:
В кавычках путь относительно основного файл. В этом примере - в той же папке, что и основной файл.
Дополню. import - это импортирование функций из заранее скомпилированного файла библиотеки, который находится в папке MQL4\Libraries, например, MQL4\Libraries\PrintLabel.ex4.
Основной смысл в том, что функции из такого файла можно передавать другим без исходников, например, продавать в Маркете, как библиотеку. Пожалуй, в случае с программирования на MQL других особых выгод нет.
Когда файл подключается через include, происходит вот что. Перед компиляцией препроцессор тупо вставляет текст включаемого файла в основной файл и уже потом компилирует. То есть это именно ваш вариант. Вот полезный пример, файл у меня лежит в личной папке MQL4\Include\AvLib\Errors.mqh, чтобы не путался с остальными в MQL4\Include, тоже советую сделать свою папку.
//+------------------------------------------------------------------+ //| Errors.mqh | //| Alexey Volchanskiy | //| https://mql.gnomio.com/ | //+------------------------------------------------------------------+ #property copyright "Alexey Volchanskiy" #property link "http://www..ru" #property strict #include <stderror.mqh> #include <stdlib.mqh> // узнает код последней ошибки и возвращает строку с описанием // код ошибки возвращается, т.к. передается по ссылке string GetMyLastError(int &err) { err = GetLastError(); string serr = ErrorDescription(err); ResetLastError(); return(serr); } // узнает код последней ошибки и возвращает строку с описанием string GetMyLastError() // можно задавать несколько функций с одинаковыми именами, но разными параметрами { int err = GetLastError(); string serr = ErrorDescription(err); ResetLastError(); return(serr); }
И теперь его можно подключать и использовать
#include <AvLib\Errors.mqh> // пример вырезан из класса по управлению ордерами, но смысл будет ясен. WriteMsg пишет результат открытия ордера в лог-файл // открывает ордер с проверкой и нормализацией данных COrder* OpenOrderWithCheck(string symbol, int cmd, double volume, double price, int slippage = 0, double stoploss = 0, double takeprofit = 0, string comment = NULL, int magic = 0, datetime expiration = 0, color arrow_color = CLR_NONE) { // При открытии рыночного ордера (OP_SELL или OP_BUY) в качестве цены открытия могут использоваться // только самые последние цены Bid (для продажи) или Ask (для покупки). if(NearOrderExist(symbol, cmd, magic, price)) // проверка на то, что уже есть открытый ордер по близкой цене return NULL; TypeOfOrder ordType = toPending; int dig = (int)MarketInfo(symbol, MODE_DIGITS); // Количество знаков после запятой по инструменту if (cmd == OP_BUY) { price = MarketInfo(symbol, MODE_ASK); ordType = toMarket; } if (cmd == OP_SELL) { price = MarketInfo(symbol, MODE_BID); ordType = toMarket; } price = NormalizeDouble(price, dig); double minlot = MarketInfo(symbol, MODE_MINLOT); // Минимальный размер лота double lotstep = MarketInfo(symbol, MODE_LOTSTEP); // Шаг изменения размера лота double maxlot = MarketInfo(symbol, MODE_MAXLOT); // Максимальный размер лота int lot = (int)(volume / lotstep); // округлили до целого числа шагов изменения лота volume = lot * lotstep; // теперь имеем правильный объем, кратный шагу изменения лота if (volume < minlot) { volume = minlot; Alert("OpenOrder()", "Объем меньше минимального, задаю минимальное значение = ", volume, " лот(а)"); } if (volume > maxlot) { volume = maxlot; Alert("OpenOrder()", "Объем больше максимального, задаю максимальное значение = ", volume, " лот(а)"); } if (arrow_color == CLR_NONE && (cmd == OP_BUY || cmd == OP_BUYSTOP || cmd == OP_BUYLIMIT)) arrow_color = m_colorBuy; if (arrow_color == CLR_NONE && (cmd == OP_SELL || cmd == OP_SELLSTOP || cmd == OP_SELLLIMIT)) arrow_color = m_colorSell; ResetLastError(); int ticket; uint dt1, timeOpen; dt1 = GetTickCount(); if(m_orderModifyAfterOpen) ticket = OrderSend(symbol, cmd, volume, price, slippage, 0, 0, comment, magic, expiration, arrow_color); else { CalcStoplossAndTakeprofit(symbol, cmd, price, stoploss, takeprofit); ticket = OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic, expiration, arrow_color); } timeOpen = GetTickCount() - dt1; COrder* pOrd = NULL; if (ticket < 0) { string err = GetMyLastError(); Print("Ошибка открытия ордера, ", err); WriteMsg("ERROR!!!", cmd, -1, symbol, "OpenOrderWithCheck - ошибка открытия ордера: " + err); return pOrd; } else { WriteMsg(" Open", cmd, ticket, symbol, " timeOpen= " + IntegerToString(timeOpen) + " volume= " + DoubleToStr(volume, 2) + " Price= " + DoubleToStr(price, dig) + " SL= " + DoubleToStr(stoploss, dig) + " TP= " + DoubleToStr(takeprofit, dig)); ResetLastError(); if(m_orderModifyAfterOpen && OrderSelect(ticket, SELECT_BY_TICKET)) { price = OrderOpenPrice(); CalcStoplossAndTakeprofit(symbol, cmd, price, stoploss, takeprofit); int counter = ORDER_MODIFY_REPEAT; bool result = false; while(!result && counter-- > 0) { dt1 = GetTickCount(); result = OrderModify(ticket, price, stoploss, takeprofit, expiration, arrow_color); timeOpen = GetTickCount() - dt1; WriteMsg(" Modify", cmd, ticket, symbol, " timeModify= " + IntegerToString(timeOpen) + " SL= " + DoubleToStr(stoploss, dig) + " TP= " + DoubleToStr(takeprofit, dig)); Sleep(ORDER_MODIFY_REPEAT_SLEEP_TIME); } } if (OrderSelect(ticket, SELECT_BY_TICKET)) { price = OrderOpenPrice(); datetime ordOpenTime = OrderOpenTime(); // нужно запрашивать реальный объем, т.к. на счетах ECN при посылке ордера с большим объемом может открыться несколько ордеров // с разными объемами и разными ценами из-за того, что в стакане просто нет заявки с нужным лотом по запрошенной цене volume = OrderLots(); stoploss = OrderStopLoss(); takeprofit = OrderTakeProfit(); pOrd = AddOrder(ordType, ticket, symbol, cmd, volume, price, ordOpenTime, magic, stoploss, takeprofit, comment, expiration, arrow_color); WriteMsg("Opened", cmd, ticket, symbol, "volume= " + DoubleToStr(volume, 2) + " Price= " + DoubleToStr(price, dig) + " SL= " + DoubleToStr(stoploss, dig) + " TP= " + DoubleToStr(takeprofit, dig)); } } return (pOrd); } //************** // пишет информацию об отрытом ордере в лог-файлы void WriteMsg(string msg0, int cmd, int orderTicket, string orderSymbol, string msg1) { string dts = TimeToStr(TimeCurrent(), TIME_DATE | TIME_MINUTES | TIME_SECONDS); string op; switch (cmd) { case OP_BUY: op = "BUY"; break; case OP_SELL: op = "SELL"; break; case OP_BUYLIMIT: op = "BUYLIMIT"; break; case OP_BUYSTOP: op = "BUYSTOP"; break; case OP_SELLLIMIT: op = "SELLLIMIT"; break; case OP_SELLSTOP: op = "SELLSTOP"; break; default: op = "NONE"; break; } if (m_hLogAllOrders > 0) FileWrite(m_hLogAllOrders, dts, " " + msg0, " Ticket= " + IntegerToString(orderTicket), " " + op, " " + orderSymbol, " " + msg1); if (m_hLogOrders > 0) FileWrite(m_hLogOrders, dts, " ", msg0, " ", orderTicket, " ", op, " ", orderSymbol, " ", msg1); }
include и import не обязательно вместе использовать. Можно или include или import использовать. Можно и вместе, конечно, но они не связаны между собой.
Проще всего include. Создаем файл mqh, сохраняем в папке include. Потом подключаем его:
После этого вызываем функции из этого файла точно так же, как будто они находятся в основном файле.
Имя файла в угловых скобках означает, что подключаемый файл находиться в папке include.
Можно и в кавычках писать имя, например:
В кавычках путь относительно основного файл. В этом примере - в той же папке, что и основной файл.
Откомпилированный файл не требует таскать за собой подключаемые файлы. Хоть сколько файлов подключается к советнику или индикатору, откомпилированный файл будет один.
Какие две функции соединять? include и import? Это не функции. Их не надо соединять, они независимы.
Что значит брать функцию из файла и не возиться с файлами?
Использование import потребует таскать за собой библиотеку. Так что не пользуйтесь import'ом, пользуйтесь include'ом
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Нет сильных навыков в программировании,но основы вроде как знаю. Написал я несколько функций. Например,
void OnTick ()
{ Trailing(); }
int Trailing()
{ kod }
И таких функций, как трейлинг, очень много, занимающие большое место.
Покажите на этом конкретном примере, как перенести эти функции в какой-то файл, ...не совсем понял куда и что переносить и в какой файл-то?
И потом, как включить этот файл в советник #include и импортировать функции #import из включенного файла? Думаю многим понадобиться эта информация, для упрощения своих советников.
В справочнике есть примеры, но я не пойму как использовать сразу #include и #import вместе; и в какой отдельный файл нужно переносить функции?