Вот файл .cpp проекта, порассматривам его и сходив пару раз в гугл и яндекс, я не обнаружил чего-то вовсе мозголомного, в целом понятно. Вроде даже просто.
//+------------------------------------------------------------------+//| Sample DLL for MQL4 |//| Copyright 2001-2012, MetaQuotes Software Corp. |//| http://www.metaquotes.net |//+------------------------------------------------------------------+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
//---#define MT4_EXPFUNC __declspec(dllexport) //это что?//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+#pragma pack(push,1)
struct RateInfo // Структура, переменные
{
unsigned int ctm;
double open;
double low;
double high;
double close;
double vol;
};
#pragma pack(pop)
//---struct MqlStr
{
int len;
char *string// Указатель на стринг, я плохо помню.
};
staticint CompareMqlStr(constvoid *left,constvoid *right);
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)//функция
{
//---switch(ul_reason_for_call) // оператор что делать
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH: //что это всюду, не понял.break;
}
//---return(TRUE);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC int __stdcall GetIntValue(constint ipar) // __stdcall кладет аргументы в стек справа налево
{ // MT4_EXPFUNC говорит что функция будет видима из метатрайдера, я не совсем понял.printf("GetIntValue takes %d\n",ipar);
return(ipar);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC double __stdcall GetDoubleValue(constdouble dpar)
{
printf("GetDoubleValue takes %.8lf\n",dpar);
return(dpar);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC char* __stdcall GetStringValue(char *spar)
{
printf("GetDoubleValue takes \"%s\"\n",spar);
return(spar);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC double __stdcall GetArrayItemValue(constdouble *arr,constint arraysize,constint nitem)
{
//---if(arr==NULL)
{
printf("GetArrayItemValue: NULL array\n");
return(0.0);
}
if(arraysize<=0)
{
printf("GetArrayItemValue: wrong arraysize (%d)\n", arraysize);
return(0.0);
}
if(nitem<0 || nitem>=arraysize)
{
printf("GetArrayItemValue: wrong item number (%d)\n", nitem);
return(0.0);
}
//---return(arr[nitem]);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC BOOL __stdcall SetArrayItemValue(double *arr,constint arraysize,constint nitem,constdouble value)
{
//---if(arr==NULL)
{
printf("GetArrayItemValue: NULL array\n");
return(FALSE);
}
if(arraysize<=0)
{
printf("GetArrayItemValue: wrong arraysize (%d)\n", arraysize);
return(FALSE);
}
if(nitem<0 || nitem>=arraysize)
{
printf("GetArrayItemValue: wrong item number (%d)\n", nitem);
return(FALSE);
}
//---
arr[nitem]=value;
return(TRUE);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC double __stdcall GetRatesItemValue(const RateInfo* rates,constint rates_total,constint shift,constint nrate)
{
//---if(rates==NULL)
{
printf("GetRatesItemValue: NULL array\n");
return(0.0);
}
//---if(rates_total<0)
{
printf("GetRatesItemValue: wrong rates_total number (%d)\n", rates_total);
return(0.0);
}
//---if(shift<0 || shift>=rates_total)
{
printf("GetRatesItemValue: wrong shift number (%d)\n", shift);
return(0.0);
}
//---if(nrate<0 || nrate>5)
{
printf("GetRatesItemValue: wrong rate index (%d)\n", nrate);
return(0.0);
}
//---int nitem=rates_total-1-shift;
switch(nrate)
{
case0: returndouble(rates[nitem].ctm);
case1: return rates[nitem].open;
case2: return rates[nitem].low;
case3: return rates[nitem].high;
case4: return rates[nitem].close;
case5: return rates[nitem].vol;
}
//---return(0.0);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC int __stdcall SortStringArray(MqlStr *arr,constint arraysize)
{
//---if(arr==NULL)
{
printf("SortStringArray: NULL array\n");
return(-1);
}
if(arraysize<=0)
{
printf("SortStringArray: wrong arraysize (%d)\n", arraysize);
return(-1);
}
//---
qsort(arr,arraysize,sizeof(MqlStr),CompareMqlStr);
//---return(arraysize);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC int __stdcall ProcessStringArray(MqlStr *arr,constint arraysize)
{
int len1,len2;
//---if(arr==NULL)
{
printf("ProcessStringArray: NULL array\n");
return(-1);
}
if(arraysize<=0)
{
printf("ProcessStringArray: wrong arraysize (%d)\n", arraysize);
return(-1);
}
//---for(int i=0; i<arraysize-1; i++)
{
if(arr[i].string==NULL) len1=0;
else len1=strlen(arr[i].string);
if(arr[i+1].string==NULL) len2=0;
else len2=strlen(arr[i+1].string);
//--- uninitialized stringif(arr[i+1].string==NULL) continue;
//--- destination string is uninitialized and cannot be allocated within dllif(arr[i].string==NULL) continue;
//--- memory piece is less than needed and cannot be reallocated within dllif(arr[i].len<len1+len2) continue;
//--- final processing
strcat(arr[i].string,arr[i+1].string);
}
//---return(arraysize);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+int CompareMqlStr(constvoid *left,constvoid *right)
{
MqlStr *leftstr=(MqlStr *)left;
MqlStr *rightstr=(MqlStr *)right;
//---if(leftstr->string==NULL) return(-1); //-> вот этот знак я не знаюif(rightstr->string==NULL) return(1);
//---return(strcmp(leftstr->string,rightstr->string));
}
//+------------------------------------------------------------------+
А как же это работает?? Я не совсем понял, как обращаться в эту ddl - из кода советника? Как? Во-первых, вроде так #include <GetIntValue> Нет как то не так..
2. При вызове dll ведь не обязательно держать включенную студию, так? как же она выполняется?
Покажите пожалуста наипростейший пример обращения к этой самой dll из кода mql.
Еще вот такой вопрос. у меня есть трейлинг. Когда открыт 1 однонаправленный ордер, все работает замечательно, если больше, то он почему-то не работает. Почему?
Вот файл .cpp проекта, порассматривам его и сходив пару раз в гугл и яндекс, я не обнаружил чего-то вовсе мозголомного, в целом понятно. Вроде даже просто.
А как же это работает?? Я не совсем понял, как обращаться в эту ddl - из кода советника? Как? Во-первых, вроде так #include <GetIntValue> Нет как то не так..
Примерно вот таким образом. Чтоб заработало, надо ДЛЛ откомпилировать и положить в папку experts/libraries (читайте справку и учебник, там все подробно расписано).
//сначала надо объявить импорт функции из DLL#import "имя_вашей_длл.dll"int SortStringArray(string *arr[],constint arraysize);
#import
//в тексте программы вызов проще простогоstring arr[];
int size;
...
//где-то в коде массив заполняется
...
//а вот и вызов сортировки
SortStringArray(arr,size);
2. При вызове dll ведь не обязательно держать включенную студию, так? как же она выполняется?
Dll - это, упрощенно говоря, обычная программа Windows, за тем исключением, что функции, реализованные в ней вызываются не пользователем, а другой программой. Для того, чтобы это было возможно, мы и указываем компилятору языка C++ модификатор __declspec(dllexport).
Еще вот такой вопрос. у меня есть трейлинг. Когда открыт 1 однонаправленный ордер, все работает замечательно, если больше, то он почему-то не работает. Почему?
На Ваш взгляд стоит в данном советнике добавить в функию обработки ошибок, проверку на 129 и 138 ошибку?
Если да, то как примерно это сделать?
Как минимум у вас должна быть своя функция для открытия позиций/установки ордеров, обрабатывающая все ошибки. Именно в ней нужно получать последние цены.
Не смотрел никаких заготовок. Но скажу: в советнике нужно обрабатывать все ошибки, возвращаемые сервером. И этого ещё мало. Он должен уметь без потерь функциональности и без сбоя своего алгоритма подхватывать свои позиции после любой непредвиденной ситуации, и продолжить свою работу так, как будто ничего экстраординарного не произошло.
откомпилировать и положить в папку experts/libraries Вот, спасибо!!! Щас попробую. А я раньше встречал, а вот теперь ненахожу ничего такого подробного и удобоваримого, по теме.
Как минимум у вас должна быть своя функция для открытия позиций/установки ордеров, обрабатывающая все ошибки. Именно в ней нужно получать последние цены.
Не смотрел никаких заготовок. Но скажу: в советнике нужно обрабатывать все ошибки, возвращаемые сервером. И этого ещё мало. Он должен уметь без потерь функциональности и без сбоя своего алгоритма подхватывать свои позиции после любой непредвиденной ситуации, и продолжить свою работу так, как будто ничего экстраординарного не произошло.
Шаблон взял из учебника. Не особо сейчас силен в функциях по обработке ошибок.
На открытии ордеров там есть RefreshRates(); (биды и аски заменил через маркет инфо, как сказали)
while(true) // Цикл закрытия орд.
{
if (Total==0 && Opn_B==true) // Открытых орд. нет +
{ // критерий откр. Buy
RefreshRates(); // Обновление данных
SL=Bid - New_Stop(StopLoss)*Point; // Вычисление SL откр.
TP=Bid + New_Stop(TakeProfit)*Point; // Вычисление TP откр.Alert("Попытка открыть Buy. Ожидание ответа..");
Ticket=OrderSend(Symb,OP_BUY,Lts,Ask,2,SL,TP);//Открытие Buyif (Ticket > 0) // Получилось :)
{
Alert ("Открыт ордер Buy ",Ticket);
return; // Выход из start()
}
if (Fun_Error(GetLastError())==1) // Обработка ошибокcontinue; // Повторная попыткаreturn; // Выход из start()
}
И функция обработки ошибок:
int Fun_Error(int Error) // Ф-ия обработ ошибок
{
switch(Error)
{ // Преодолимые ошибки case4: Alert("Торговый сервер занят. Пробуем ещё раз..");
Sleep(3000); // Простое решениеreturn(1); // Выход из функцииcase135:Alert("Цена изменилась. Пробуем ещё раз..");
RefreshRates(); // Обновим данныеreturn(1); // Выход из функцииcase136:Alert("Нет цен. Ждём новый тик..");
while(RefreshRates()==false) // До нового тикаSleep(1); // Задержка в циклеreturn(1); // Выход из функцииcase137:Alert("Брокер занят. Пробуем ещё раз..");
Sleep(3000); // Простое решениеreturn(1); // Выход из функцииcase146:Alert("Подсистема торговли занята. Пробуем ещё..");
Sleep(500); // Простое решениеreturn(1); // Выход из функции// Критические ошибкиcase2: Alert("Общая ошибка.");
return(0); // Выход из функцииcase5: Alert("Старая версия терминала.");
Work=false; // Больше не работатьreturn(0); // Выход из функцииcase64: Alert("Счет заблокирован.");
Work=false; // Больше не работатьreturn(0); // Выход из функцииcase133:Alert("Торговля запрещена.");
return(0); // Выход из функцииcase134:Alert("Недостаточно денег для совершения операции.");
return(0); // Выход из функцииdefault: Alert("Возникла ошибка ",Error); // Другие варианты return(0); // Выход из функции
}
}
Хотел спросить. Можно в нее следующую строку внести от 129 ошибки к примеру так?
case129:Alert("Неправильные цены. Пробуем ещё раз..");
RefreshRates(); // Обновим данныеreturn(1);
У меня в папке experts лежит весь проэкт визуал студии... Откомпилировать- это же файл .exe, точно? Хотел вот скопировать его в папку либрариес... Не найду прикиньте!! Вот папка дебаг проэкта. Я уж извняюсь, тема новая.
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
Вот файл .cpp проекта, порассматривам его и сходив пару раз в гугл и яндекс, я не обнаружил чего-то вовсе мозголомного, в целом понятно. Вроде даже просто.
А как же это работает?? Я не совсем понял, как обращаться в эту ddl - из кода советника? Как? Во-первых, вроде так #include <GetIntValue> Нет как то не так..
2. При вызове dll ведь не обязательно держать включенную студию, так? как же она выполняется?
Покажите пожалуста наипростейший пример обращения к этой самой dll из кода mql.
ничего не пойму тут..
надо чтобы размер лота увеличивался в геометрической прогрессии ( с множителем 2), если открывается второй однонаправленный ордер.
получится вот такой результат
тогда вот так
получится вот такой результат
тогда вот так
спасибо, ход мыслей понял.. разобрался вернее.
для чего эта строчка?
datetime o;Еще вот такой вопрос. у меня есть трейлинг. Когда открыт 1 однонаправленный ордер, все работает замечательно, если больше, то он почему-то не работает. Почему?
{
for(int i = 0; i<OrdersTotal(); i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_BUY)
{
if(Bid - OrderOpenPrice() > TrailingStop*Point)
{
if (OrderStopLoss() < Bid - (TrailingStop + TrailingStep)*Point)
{
SL = NormalizeDouble(Bid - TrailingStop*Point,Digits);
if (OrderStopLoss() !=SL)
OrderModify(OrderTicket(),OrderOpenPrice(),SL,0,0);
}
}
}
if (OrderType() == OP_SELL)
{
if(OrderOpenPrice() - Ask > TrailingStop*Point)
{
if (OrderStopLoss() > Ask + (TrailingStop+ TrailingStep)*Point)
{
SL = NormalizeDouble (Ask+TrailingStop*Point,Digits);
if (OrderStopLoss() !=SL)
OrderModify (OrderTicket(), OrderOpenPrice(), SL,0,0);
}
}
}
}
}
}
}
Вот файл .cpp проекта, порассматривам его и сходив пару раз в гугл и яндекс, я не обнаружил чего-то вовсе мозголомного, в целом понятно. Вроде даже просто.
А как же это работает?? Я не совсем понял, как обращаться в эту ddl - из кода советника? Как? Во-первых, вроде так #include <GetIntValue> Нет как то не так..
Примерно вот таким образом. Чтоб заработало, надо ДЛЛ откомпилировать и положить в папку experts/libraries (читайте справку и учебник, там все подробно расписано).
2. При вызове dll ведь не обязательно держать включенную студию, так? как же она выполняется?
Еще вот такой вопрос. у меня есть трейлинг. Когда открыт 1 однонаправленный ордер, все работает замечательно, если больше, то он почему-то не работает. Почему?
{
for(int i = 0; i<OrdersTotal(); i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_BUY)
{
if(Bid - OrderOpenPrice() > TrailingStop*Point)
{
if (OrderStopLoss() < Bid - (TrailingStop + TrailingStep)*Point)
{
SL = NormalizeDouble(Bid - TrailingStop*Point,Digits);
if (OrderStopLoss() !=SL)
OrderModify(OrderTicket(),OrderOpenPrice(),SL,0,0);
}
}
}
if (OrderType() == OP_SELL)
{
if(OrderOpenPrice() - Ask > TrailingStop*Point)
{
if (OrderStopLoss() > Ask + (TrailingStop+ TrailingStep)*Point)
{
SL = NormalizeDouble (Ask+TrailingStop*Point,Digits);
if (OrderStopLoss() !=SL)
OrderModify (OrderTicket(), OrderOpenPrice(), SL,0,0);
}
}
}
}
}
}
}
потому что в функцию необходимо передать параметры пробуйте так
bool IfProfTrail=false; // Использовать только дял профитных позиций - режим безубытка
int TrailingStop=0; // Дистанция трейлинга = 0 - минимально допустимый
int TrailingStep=1; // Шаг дистанции
Спасибо огромное!
Теперь стало понятно в чем проблемма.
Для покупки использовал:
На сколько знаю покупка идет по ask, а iClose(Symbol(),Period(),0) берет цены из bid. Вследствии чего наверное и происходит ошибка.
Но, тут же возникает вопрос так как, советник не пипсовый, цена находилась в зоне покупки долгое время и обновлялась при каждом тике.Теперь использую следующюю комбинацию:
Почему не открывается сделка? Получается советник зависает на ошибке и не видит дальнейшее изменение цены?
Заготовку для советника взял отсюда https://c.mql5.com/mql4/book/mq4/experts/tradingexpert.mq4
На Ваш взгляд стоит в данном советнике добавить в функию обработки ошибок, проверку на 129 и 138 ошибку?
Если да, то как примерно это сделать?
Как минимум у вас должна быть своя функция для открытия позиций/установки ордеров, обрабатывающая все ошибки. Именно в ней нужно получать последние цены.
Не смотрел никаких заготовок. Но скажу: в советнике нужно обрабатывать все ошибки, возвращаемые сервером. И этого ещё мало. Он должен уметь без потерь функциональности и без сбоя своего алгоритма подхватывать свои позиции после любой непредвиденной ситуации, и продолжить свою работу так, как будто ничего экстраординарного не произошло.
Как минимум у вас должна быть своя функция для открытия позиций/установки ордеров, обрабатывающая все ошибки. Именно в ней нужно получать последние цены.
Не смотрел никаких заготовок. Но скажу: в советнике нужно обрабатывать все ошибки, возвращаемые сервером. И этого ещё мало. Он должен уметь без потерь функциональности и без сбоя своего алгоритма подхватывать свои позиции после любой непредвиденной ситуации, и продолжить свою работу так, как будто ничего экстраординарного не произошло.
Шаблон взял из учебника. Не особо сейчас силен в функциях по обработке ошибок.
На открытии ордеров там есть RefreshRates(); (биды и аски заменил через маркет инфо, как сказали)
И функция обработки ошибок:
Хотел спросить. Можно в нее следующую строку внести от 129 ошибки к примеру так?