//+------------------------------------------------------------------+ //| Exp_HelpTrade.mq4 | //| Copyright 2012, MetaQuotes Software Corp. | //| http://www.metaquotes.net | //+------------------------------------------------------------------+ #property copyright "Copyright 2012, MetaQuotes Software Corp." #property link "http://www.metaquotes.net" //---- extern string InputFile="InputExp_AvtoTrade_v1.csv"; extern bool Averag =true; // усреднение разрешено(true) extern int Atotal =5; // количество допустимых усреднений extern bool Lev =true; // доливка по уровням разрешена extern int SizeLev =5; // последнее касание ценой уровня должно быть не менее чем SizeLev минут назад extern int LevRound =1; // усредняться через 1 уровень extern bool Pros =true; // доливка по просадке разрешена extern double Prosadka =50; // просадка в валюте депозита extern double Profit =50; // профит закрытия в валюте депозита //---- #define total 10 // размерность основных массивов //---------------------------------------------- Глобальные переменные ---------------------------- //---- Основные гл. переменные string Name_pref; // префикс для создания гл. переменных bool work; // флаг корректного запуска //---- характеристики группы ордеров double Gprofit[total], // текущий профит группы GOrd_Lotsf[total], // запланированный объем GOrd_Lots[total]; // объем 1 ордера группировки string GOrd_symbol[total][2], // инструменты. Логически связан с массивом GOrd_Type GOrd_symbolf[total][2]; // инструменты. Логически связан с массивом GOrd_Typef int GOrd_Type[total][2], // направление открытия позиций GOrd_Typef[total][2], GM[total]; // магические числа групп //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { int i, handlle,mag; string symb1,symb2; double lots; //---- work=true; Name_pref=WindowExpertName(); ArrayInitialize(GM,-1); //---- загружаем инфу из файла handlle=FileOpen(InputFile,FILE_CSV|FILE_READ,";"); if(handlle<1) { work=false; Alert("Файл ",InputFile," не найден.\nПроверьте наличие файла и перезапустите эксперт"); return(0); } FileReadString(handlle); FileReadString(handlle); FileReadString(handlle); FileReadString(handlle); for(i=0; !FileIsEnding(handlle) && i=0; i--) { if(!OrderSelect(i,SELECT_BY_POS)) continue; mag=OrderMagicNumber(); //---- проверяем принадлежность и собираем инфу по ордеру for(j=0; j=Atotal || !Lev) break; // доливаться уже нельзя digits=MarketInfo(GOrd_symbol[i][s],MODE_DIGITS); point =MarketInfo(GOrd_symbol[i][s],MODE_POINT); ask =MarketInfo(GOrd_symbol[i][s],MODE_ASK); bid =MarketInfo(GOrd_symbol[i][s],MODE_BID); j=GOrd_Type[i][s]; //---- eps=ND(10*point); //---- PrCur=ND(j*bid+(1-j)*ask); // правильная цена для текущего инструмента O=ND(MathMod(PrCur/point,100)*point); // расстояние до ближайшего меньшего кр. уровня if(O>eps && O<100-eps) continue; // цена далеко от близлежащих уровней LevCur=ND(PrCur-O); if(O>=100-eps) LevCur=ND(LevCur+j*100*point); // ближайший правильный круглый уровень name3=Name_pref+"_M"+GM[i]+"_"+GOrd_symbol[i][s]+"_L"+DoubleToStr(LevCur,5); if(GlobalVariableCheck(name3)) continue; // доливка уже производилась //---- проверка на размер уровня a=MathPow(-1,j); for(l=1; l<=SizeLev; l++) { highm=iHigh(GOrd_symbol[i][s],PERIOD_M1,l); lowm =iLow(GOrd_symbol[i][s],PERIOD_M1,l); highm=ND(j*highm+(1-j)*lowm); if(a*(LevCur-highm)>0) break; } if(l0) continue; //---- проверка касания с уровнем //Print("Поиск позиции GM[i]=",GM[i]," i=",i); for(s=0; s<=1; s++) { point =MarketInfo(GOrd_symbolf[i][s],MODE_POINT); ask =MarketInfo(GOrd_symbolf[i][s],MODE_ASK); bid =MarketInfo(GOrd_symbolf[i][s],MODE_BID); eps =ND(10*point); //---- type=-1; for(j=0; j<=1; j++) { //---- определяем расстояние до ближайшего уровня PrCur=ND(j*bid+(1-j)*ask); // правильная цена для текущего инструмента O=ND(MathMod(PrCur/point,100)*point); // расстояние до ближайшего меньшего кр. уровня if(O>eps && O<100-eps) continue; // цена далеко от близлежащих уровней //---- правильный уровень LevCur=ND(PrCur-O); if(O>=100-eps) LevCur=ND(LevCur+j*100*point); // ближайший правильный круглый уровень //---- проверяем касание a=MathPow(-1,j); for(l=1; l<=SizeLev; l++) { highm=iHigh(GOrd_symbolf[i][s],PERIOD_M1,l); lowm =iLow(GOrd_symbolf[i][s],PERIOD_M1,l); highm=ND(j*highm+(1-j)*lowm); if(a*(LevCur-highm)>0) break; } if(l0) continue; GlobalVariablesDeleteAll(Name_pref+"_M"+GM[i]); } } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ int My_orders(int magic=-1,int type=-1,string symbol="", double lot=-1,datetime Opent=0) { int Ordtotal=OrdersTotal(); //---- for (int i=0; i0; ii--) { //пытаемся открыть(установить ордер) RefreshRates(); stl =MarketInfo(symb,MODE_STOPLEVEL);//Уровень стопов ask =MarketInfo(symb,MODE_ASK); bid =MarketInfo(symb,MODE_BID); stl=stl*point; //------------------------------- Определение и проверка цены открытия ---------------------- if(tip==0) price=ask; else if(tip==1) price=bid; if(price<=0) { Print("Open_Ord(...): Отрицательная цена установки отлдоженного ордера. Операция невозможна. Price=",price); return(ticket); } //---- проверка цены установки отложенных ордеров if(tip==2 && NormalizeDouble(ask-price-stl,dig)<0) price=ask-stl; if(tip==4 && NormalizeDouble(price-ask-stl,dig)<0) price=ask+stl; if(tip==3 && NormalizeDouble(price-bid-stl,dig)<0) price=bid+stl; if(tip==5 && NormalizeDouble(bid-price-stl,dig)<0) price=bid-stl; //------------------------------- Проверка объема для рыночных позиций ---------------------- //------------------------------- Открытие позиции(установка ордеров), установка стопов ------ ticket=OrderSend(symb,tip,NormalizeDouble(lots,2),NormalizeDouble(price,dig),Slippage,0,0,comment,magic); if(ticket>0) { //ордер выставлен. Пытаемся установить стопы if(!OrderSelect(ticket,SELECT_BY_TICKET)) { Print("Open_Ord(...): Неизвестная ошибка при установки стопприказов."); return(ticket); } //---------------------------- Определение стопприказов ------------------------------------ a=MathPow(-1,tip); //знакоопределяющий коэффициент ordprice=OrderOpenPrice(); price=ordprice; //---- Определение StopLoss в значении цены if (NormalizeDouble(stop,dig)==0 && stoploss!=0) SL=ordprice-a*stoploss*point; else SL=stop; //---- Определение TakeProfit в значении цены if (NormalizeDouble(takeprofit2,dig)==0 && takeprofit!=0) TP=ordprice+a*takeprofit*point; else TP=takeprofit2; if(NormalizeDouble(SL,dig)==0 && NormalizeDouble(TP,dig)==0) return(ticket); //---- Установка стопов for(k=1; k<=50; k++) { RefreshRates(); //---------------------------- Сбор информации ------------------------------------------- ask=MarketInfo(symb,MODE_ASK); bid=MarketInfo(symb,MODE_BID); stl=MarketInfo(symb,MODE_STOPLEVEL)+1;//Уровень стопов stl*=point; //---- определяем цену относительно которой будем проверять стопы ---- if(tip==0) price=bid; else if(tip==1) price=ask; //---------------------------- Проверка стопприказов ------------------------------------- if(NormalizeDouble(TP,dig)!=0 && NormalizeDouble(a*(TP-price)-stl,dig)<0) TP=price+a*stl; if(NormalizeDouble(SL,dig)!=0 && NormalizeDouble(a*(price-SL)-stl,dig)<0) SL=price-a*stl; //---- if(NormalizeDouble(SL,dig)<0 || NormalizeDouble(TP,dig)<0) { Print("Open_Ord(...): Модификация невозможна. Отрицательные стоп приказы ордера: ",ticket," SL=",SL," TP=",TP); return(ticket); } //---------------------------- Модификация стоп приказов --------------------------------- if(OrderModify(ticket,NormalizeDouble(ordprice,dig),NormalizeDouble(SL,dig),NormalizeDouble(TP,dig),0)) return(ticket); else { //анализ ошибок. Er=GetLastError(); if(Errors(Er)) continue; break; } } //---- вышли из цикла модификации => стопы не установлены Print("Open_Ord(...): He удалось установить стопприказы ордера: ",ticket,". Error: ",Er); return(ticket); } else { //анализ ошибок. Er=GetLastError(); if(Errors(Er)) continue; break; } } //----вышли из цикла установки => ордер не установлен Print("Open_Ord(...): Неудачная попытка открытия(установки) позиции(ордера). Error: ",Er); return(ticket); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ bool Errors(int Error) { //Inform(15,Error); // Сообщение switch(Error) { //Надо обновить данные. case 0: // Хотя это спорно. 0 можно считать и критической ошибкой case 1: // Нет ошибки, но результат операции неизвестен case 128: // Истек срок ожидания сделки case 129: // Неправильная цена case 135: // Цена изменилась case 138: // Новые цены RefreshRates(); // Обновим данные return(true); // Ошибка преодолимая // Ждём новый тик. case 136: //Нет цен. while(RefreshRates()==false) // До нового тика Sleep(10); // Задержка в цикле return(true); // Ошибка преодолимая // Ждем пока кто-то восстановить связь case 6: //нет связи bool connect=false; int iteration=0; Alert("Разрыв связи с сервером."); while((!connect) || (iteration>3600)) { //ждем пол часа Sleep(500); connect=IsConnected(); if(connect) { Print("Связь восстановлена. Продолжаем работу"); return(true); } iteration++; } Alert("Не удалось восстановить соединение"); return(false); //Ждем некоторое время. case 4: //сервер завис case 130: //stops case 131: //неправильный объем. Из опыта: 130 и 131 далеко не всегда то за что их выдают. case 137: //брокер ушел на перекур case 146: //терминал не успевает. Встанем в очередь. Sleep(1000); // Простое решение RefreshRates(); // Обновим данные return(true); // Ошибка преодолимая //Ждем подольше. case 8: //мы надоели брокеру. Подождем и продолжим игру на нервах case 139: // опоздали... Sleep(5000); return(true); // Ждем совсем долго case 132: // может через час выходные закончатся))) Sleep(3600000); return(true); // Критические ошибки: case 2: // Общая ошибка. Сбой системы. Перезагрузить компьютер/проверить сервер case 5: // Старая версия клиентского терминала case 7: // Недостаточно прав case 9: // Серьезный косяк. Брокер в шоке. case 64: // Счет заблокирован case 65: // Не правильный счет case 134: // Фффинансы поют романсы case 133: // Торговля запрещена case 147: // Использование даты истечения ордера запрещено брокером return(false); default: // Другие варианты return(true); } } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ double ND(double x, int k=5) {return(NormalizeDouble(x,k));} //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ bool CloseDel_Ord(int ticket, int Slip=1) { int type; double ask,bid,digits; bool rez; string Symb; //---- //проверка зоны заморозки Symb =OrderSymbol(); type =OrderType(); digits=MarketInfo(Symb,MODE_DIGITS); for(int i=0; i<100; i++) { //100 попыток на успех RefreshRates(); ask=MarketInfo(Symb,MODE_ASK); bid=MarketInfo(Symb,MODE_BID); switch (type) { case 0: rez=OrderClose(ticket,NormalizeDouble(OrderLots(),digits),NormalizeDouble(bid,digits),Slip); break; case 1: rez=OrderClose(ticket,NormalizeDouble(OrderLots(),2),NormalizeDouble(ask,digits),Slip); break; case 2: case 3: case 4: case 5: rez=OrderDelete(ticket); } //---- if (rez==false) { // Не получилось, поинтересуемся ошибками: int Er=GetLastError(); if(Errors(Er)==false) { Print("CloseDel_Ord(...): Неудачный вызов функции( Error: ",Er," )"); return(false); } continue; } break; } if(rez==false) { Print("CloseDel_Ord(...): Неудачный вызов функции(",Er,")"); return(false); } return(true); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++