Как создать ф-ию которую можно вызывать из разных експертов?
И как ее можно вызвать? Допустим у меня есть ф-ия написанная
в експерте перед началом программы. В MetaEditore я начинаю писать
новую прграмму, ставлю флажок Library, копирую туда нужную ф-ию
из експерта. Ф-ия компилируется, но выдает сообщение 'Start function
not found. "Function1" as start function assumed'. Когда в експерте удаляю эту
же ф-ию, он без нее не компилируется, выдает ошибку. Подскажите
как правильно все это организовать?
- Генерация включаемого кода - Разработка программ
- Скачайте MetaTrader 5 build 1730 с новыми возможностями для трейдеров
- Создание и работа с проектом - Проекты и MQL5 Storage
Библиотека (Library) - библиотека пользовательских функций, предназначенная
для хранения и распространения часто используемых блоков пользовательских
программ. Библиотеки не могут самостоятельно запускаться на
выполнение.
Библиотеки рекомендуется хранить в директории каталог_терминалаexpertslibraries
Библиотеки рекомендуется хранить в директории каталог_терминалаexpertslibraries
Да, я это читал, первая страничка в разделе "документация".
Понятно что ф-ия не может сама запускаться на выполнение, я хочу
вызывать часто используемый блок (ф-ию) из эксперта. Если например
у меня есть такая ф-ия:
Вроде понятно вопрос сформулировал. Спасибо.
int OrderScan(int area, int a=-1, int b=-1, int c=-1, int d=-1, int e=-1, int f=-1) { int n; int total=-1; int masiv[6]; masiv[0]=a; masiv[1]=b; masiv[2]=c; masiv[3]=d; masiv[4]=e; masiv[5]=f; if(area==MODE_TRADES) {total=OrdersTotal(); n=1;} if(area==MODE_HISTORY) {total=HistoryTotal(); n=2;} if(total==-1) {Print("Ф-ии OrderScan был передан неправильный параметр pool"); return(-2);} if(masiv[0]==-1) {Print("Ф-ии OrderScan небыло передано ни одного параметра type"); return(-2);} for(int i=1; i<=total; i++) // Перебираем все ордера { switch(n) { case 1: OrderSelect(total-i,SELECT_BY_POS,MODE_TRADES); break; case 2: OrderSelect(total-i,SELECT_BY_POS,MODE_HISTORY); break; } for(int m=0; m<=5; m++) { if(masiv[m]==-1) break; if(OrderType()==masiv[m]) { return(masiv[m]); } } } return(-1); }И я ее часто использую. Для этого в каждый новый эксперт я постоянно вставляю этот блок (обычно в начале программы). А потом несколько раз его вызываю из эксперта например так:
OrderScan(MODE_HISTORY,0,1);Можно это организовать таким образом, чтобы я в каждый эксперт ее не копировал, а обращался к ней как и к любой другой встроенной в mql ф-ии?
Вроде понятно вопрос сформулировал. Спасибо.
Создай файл func.mq4 в директории experts\include, вставь туда эту функцию.
Потом для использования из эксперта вставляй строку #include <func. mq4>
Всё просто ;)
Потом для использования из эксперта вставляй строку #include <func. mq4>
Всё просто ;)
Понял, все получилось. Спасибо :)
komposter:
Создай файл func.mq4 в директории expertsinclude, вставь туда эту функцию.
Потом для использования из эксперта вставляй строку #include <func. mq4>
Всё просто ;)
Так а что делать с надписью Start function not found and cannot be run, возникающей после компиляции библиотеки?Создай файл func.mq4 в директории expertsinclude, вставь туда эту функцию.
Потом для использования из эксперта вставляй строку #include <func. mq4>
Всё просто ;)
Далее, в документации написано, что библиотеку лучше хранить в папке .../experts/library/. Почему тогда папка Includes?
Если я следую Вашим рекомендациям и добавляю в библиотеку функции, которые не задействуются в одном эксперте, но задействуются в другом, то процесс компиляции выдаёт ошибку, что та или иная переменная объявлена небыла. Так что нельзя в терминале иметь одну общую библиотеку для всех советников чтоль?
И вообще, может где н-ть об этом подробно написано?
Чем хорош инклюдник - тем что все прописанные в нем функции и
переменные встраиваются в код программы, которая его вызывает,
прямо на этапе компиляции. Поэтому нет никаких потерь в быстродействии.
Все невызываемые функции при компиляции игнорируются и не добавляются в ex4-файл.
Все невызываемые функции при компиляции игнорируются и не добавляются в ex4-файл.
Rosh:
Чем хорош инклюдник - тем что все прописанные в нем функции и переменные встраиваются в код программы, которая его вызывает, прямо на этапе компиляции. Поэтому нет никаких потерь в быстродействии.
Все невызываемые функции при компиляции игнорируются и не добавляются в ex4-файл.
Понимаете, что происходит - у меня переменная (и не одна) задействуется
как в функции, так и в советнике.Чем хорош инклюдник - тем что все прописанные в нем функции и переменные встраиваются в код программы, которая его вызывает, прямо на этапе компиляции. Поэтому нет никаких потерь в быстродействии.
Все невызываемые функции при компиляции игнорируются и не добавляются в ex4-файл.
Если удалить объявление переменных из советника и объявлять их только в функции, то советник не компилируется. Если объявлять переменные только в советнике, то библиотека не компилируется. Если объявлять переменные и там и там, то выходит полная фигня - например, у меня функция не должна возвращать ни каких значений, а просто обработать группу переменных и присвоить им некоторые значения. Если объявлять эти переменные и там и там, то советник, обработав их присвоит им некоторые значения. Далее идёт запос нашей функции, где переменые объявляются заново (то есть, выходит, что они обнуляются). Какой тогда был смысл обрабатывать их в советнике, если функция расположенная в библиотеке, их обнуляет? пока данная функция находится в теле советника - всё нормально, как только выносишь её в библиотеку, советник не пашет.
Да, можно в функцию передавать кучу параметров. Но это жутко не удобно - ворочать кучами. Вероятность сделать ошибку резко возрастает. Я организовываю код поблочно - так проще контроллировать его правильность. в одном блоке переменные, в другом, в третьем, ... а потом функция на них набрасывается и обрабатывает их всех
за один заход. Если такая функция используется во многих советниках, то есть смысл перенести её в библиотеку. Но выходит, что организация кода не позволяет это сделать. Словом, я напрочь разочаровался в подобном "удобстве".
Нет ли тут смештвания понятия библиотеки (library) и инклюдника(include).
Инклюдники не требуют автономной компиляции, их код "просто
внедряется" в код программы, где использована директива #include
<имя_инклюдника.mq(h|4)> . При этом файл инклюдника может находиться
не обязательно в папке experts/include/ . Поэкспериментируйте.
Кроме того, если я опасаюсь пересечения имен перемен в инлюднике и в вызывающем файле, то я применяю сложную систему именования в инклюднике, которая на 99% гарантирует, что такие имена не будут использованы в других программах. Например, вот пример инлюкдника:
Кроме того, если я опасаюсь пересечения имен перемен в инлюднике и в вызывающем файле, то я применяю сложную систему именования в инклюднике, которая на 99% гарантирует, что такие имена не будут использованы в других программах. Например, вот пример инлюкдника:
//+------------------------------------------------------------------+ //| Tracert.mq4 | //| Rosh | //| https://www.metaquotes.net// | //+------------------------------------------------------------------+ #property copyright "Rosh" #property link " https://www.metaquotes.net//" //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ double tr_AOPLong,tr_AOPShort; double tr_LongLots,tr_ShortLots; int tr_CurrLongOrders,tr_CurrShortOrders; int tr_Total,tr_Counter; int tr_PrevLongOrders,tr_PrevShortOrders; int tr_CurrTotalOpenedOrders,tr_PrevTotalOpenedOrders; double tr_CurrBalance,tr_PrevCurrBalance; color tr_ProfitColor=Lime, tr_LossColor=DeepPink,tr_LongAOPColor=Blue,tr_ShortAOPColor=Red, tr_CurrCloseColor; int tr_CloseLabelArrow=108, tr_AOPLabelArrow=159; bool tr_CloseLong,tr_CloseShort; double tr_CloseLabelPrice; int tr_CloseLabelShift=20; int tr_CounterCloseLabel=0,tr_CounterAOPLabel=0; int tr_Bars; void SetTrace() { //---- if (IsTesting()&&(tr_Bars!=Bars)) { tr_CloseLong=false; tr_CloseShort=false; tr_AOPLong=0.0; tr_AOPShort=0.0; tr_LongLots=0.0; tr_ShortLots=0.0; tr_CloseLabelShift=iATR(NULL,0,50,1)*3.0/10.0/Point; if (tr_CurrBalance==0.0) { tr_CurrBalance=AccountBalance(); tr_PrevCurrBalance=AccountBalance(); } //----------------Проверка открытых позиций --------------------------- tr_CurrLongOrders=0; tr_CurrShortOrders=0; tr_CurrTotalOpenedOrders=0; tr_Total=OrdersTotal(); for (tr_Counter=0;tr_Counter<tr_Total;tr_Counter++)// подсчет открытых позиций { OrderSelect(tr_Counter, SELECT_BY_POS, MODE_TRADES); if (OrderType()==OP_BUY) { tr_CurrLongOrders++; tr_AOPLong=tr_AOPLong+OrderLots()*OrderOpenPrice(); tr_LongLots=tr_LongLots+OrderLots(); } if (OrderType()==OP_SELL) { tr_CurrShortOrders++; tr_AOPShort=tr_AOPShort+OrderLots()*OrderOpenPrice(); tr_ShortLots=tr_ShortLots+OrderLots(); } } //--------------- усреднение --------------------- if (tr_CurrLongOrders>0) tr_AOPLong=tr_AOPLong/tr_LongLots; if (tr_CurrShortOrders>0)tr_AOPShort=tr_AOPShort/tr_ShortLots; //--------------- усреднение --------------------- if (tr_AOPLong>0.0) { ObjectCreate("AOP"+tr_CounterAOPLabel,OBJ_ARROW,0,Time[1],tr_AOPLong); ObjectSet("AOP"+tr_CounterAOPLabel,OBJPROP_ARROWCODE,tr_AOPLabelArrow); ObjectSet("AOP"+tr_CounterAOPLabel,OBJPROP_COLOR,tr_LongAOPColor); tr_CounterAOPLabel++; } if (tr_AOPShort>0.0) { ObjectCreate("AOP"+tr_CounterAOPLabel,OBJ_ARROW,0,Time[1],tr_AOPShort); ObjectSet("AOP"+tr_CounterAOPLabel,OBJPROP_ARROWCODE,tr_AOPLabelArrow); ObjectSet("AOP"+tr_CounterAOPLabel,OBJPROP_COLOR,tr_ShortAOPColor); tr_CounterAOPLabel++; } tr_CurrTotalOpenedOrders=tr_CurrLongOrders+tr_CurrShortOrders; if ((tr_CurrTotalOpenedOrders!=tr_PrevTotalOpenedOrders)||(tr_PrevLongOrders!=tr_CurrLongOrders)||(tr_PrevShortOrders!=tr_CurrShortOrders)) // изменилось колчиство ордеров в рынке { if (tr_PrevLongOrders>tr_CurrLongOrders) // изменилось число ордеров в Long { tr_CloseLong=true; tr_CloseLabelPrice=High[1]+tr_CloseLabelShift*Point; } if (tr_PrevShortOrders>tr_CurrShortOrders) // изменилось число ордеров в Short { tr_CloseShort=true; tr_CloseLabelPrice=Low[1]-tr_CloseLabelShift*Point; } tr_PrevLongOrders=tr_CurrLongOrders; tr_PrevShortOrders=tr_CurrShortOrders; tr_PrevTotalOpenedOrders=tr_CurrTotalOpenedOrders; } //---------------- Проверка изменения Баланса tr_CurrBalance=AccountBalance(); if (tr_CurrBalance!=tr_PrevCurrBalance)// проверка изменения Balance { if (tr_CurrBalance-tr_PrevCurrBalance>0.0) tr_CurrCloseColor=tr_ProfitColor; else tr_CurrCloseColor=tr_LossColor; tr_PrevCurrBalance=tr_CurrBalance; //------------------ установка Метки закрытия -------------------- ObjectCreate("Close"+tr_CounterCloseLabel,OBJ_ARROW,0,Time[1],tr_CloseLabelPrice); ObjectSet("Close"+tr_CounterCloseLabel,OBJPROP_ARROWCODE,tr_CloseLabelArrow); ObjectSet("Close"+tr_CounterCloseLabel,OBJPROP_COLOR,tr_CurrCloseColor); tr_CounterCloseLabel++; //------------------ установка Метки закрытия -------------------- }// проверка изменения Balance }//(IsTesting()) //---- // Print("Total=",tr_Total); tr_Bars=Bars; return(0); } //+------------------------------------------------------------------+Именя переменных начинаются с префикса tr_
Rosh:
Нет ли тут смештвания понятия библиотеки (library) и инклюдника(include). Инклюдники не требуют автономной компиляции, их код "просто внедряется" в код программы, где использована директива #include <имя_инклюдника.mq(h|4)> . При этом файл инклюдника может находиться не обязательно в папке experts/include/ . Поэкспериментируйте.
Кроме того, если я опасаюсь пересечения имен перемен в инлюднике и в вызывающем файле, то я применяю сложную систему именования в инклюднике, которая на 99% гарантирует, что такие имена не будут использованы в других программах. Например, вот пример инлюкдника:
Посмотрюпозже - устал сейчас. А к Вам у меня просьба будет. Вот
тут я выложил свою разработку - универсальный трейлинг-стоп.
Нет ли тут смештвания понятия библиотеки (library) и инклюдника(include). Инклюдники не требуют автономной компиляции, их код "просто внедряется" в код программы, где использована директива #include <имя_инклюдника.mq(h|4)> . При этом файл инклюдника может находиться не обязательно в папке experts/include/ . Поэкспериментируйте.
Кроме того, если я опасаюсь пересечения имен перемен в инлюднике и в вызывающем файле, то я применяю сложную систему именования в инклюднике, которая на 99% гарантирует, что такие имена не будут использованы в других программах. Например, вот пример инлюкдника:
MQL4 Code ....Именя переменных начинаются с префикса tr_
http://forum.alpari-idc.ru/thread34835.html Качайте версию 1.3 - она в самом низу страницы.
У Вас не плохо получается программить - гляньте пожалуйста код - инструмент получился очень удобный - может какие недочёты найдёте - хотелось бы исправить - людям всётаки выложил в общий доступ.
Открытый код есть здесь:
http://forum.liteforex.net/viewtopic.php?t=8526
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь