В объявлениях разработчиков советников часто можно встретить фразу «сделаю для реальной торговли». Для человека немного знакомого с MQL вполне под силу самостоятельно переписать советник для реальной торговли. Если у вас не имеется собственных наработок в этом направлении можно воспользоваться готовыми функциями опытных программистов.
Пусть у нас есть советник, торгующий по двум МА. При пересечении медленной МА быстрой снизу вверх покупаем, наоборот продаем.
//+------------------------------------------------------------------+
//| 2MA .mq4 |
//| Copyright 2015, AM2 |
//| http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2015, AM2"
#property link "http://www.forexsystems.biz"
#property description "Martin expert advisor"
extern int StopLoss = 1200;
extern int TakeProfit = 1400;
extern int Slip = 50;
extern int MA1Period = 9;
extern int MA2Period = 22;
extern int Magic = 123;
extern double Lots = 0.1;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void PutOrder(int type,double price)
{
int r=0;
color clr=Green;
double sl=0,tp=0;
if(type==1 || type==3 || type==5)
{
clr=Red;
if(StopLoss>0) sl=NormalizeDouble(price+StopLoss*Point,Digits);
if(TakeProfit>0) tp=NormalizeDouble(price-TakeProfit*Point,Digits);
}
if(type==0 || type==2 || type==4)
{
clr=Blue;
if(StopLoss>0) sl=NormalizeDouble(price-StopLoss*Point,Digits);
if(TakeProfit>0) tp=NormalizeDouble(price+TakeProfit*Point,Digits);
}
r=OrderSend(NULL,type,Lots,NormalizeDouble(price,Digits),Slip,sl,tp,"",Magic,0,clr);
return;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CountTrades()
{
int count=0;
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
{
if(OrderType()<2) count++;
}
}
}
return(count);
}
//+------------------------------------------------------------------+
//| Check for open order conditions |
//+------------------------------------------------------------------+
void OpenPos()
{
double ma11=iMA(NULL,0,MA1Period,0,MODE_EMA,PRICE_CLOSE,1);
double ma21=iMA(NULL,0,MA2Period,0,MODE_EMA,PRICE_CLOSE,1);
double ma12=iMA(NULL,0,MA1Period,0,MODE_EMA,PRICE_CLOSE,2);
double ma22=iMA(NULL,0,MA2Period,0,MODE_EMA,PRICE_CLOSE,2);
//---- buy
if(ma11>ma21 && ma12<ma22)
{
PutOrder(0,Ask);
}
//---- sell
if(ma11<ma21 && ma12>ma22)
{
PutOrder(1,Bid);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void ClosePos()
{
double ma11=iMA(NULL,0,MA1Period,0,MODE_EMA,PRICE_CLOSE,1);
double ma21=iMA(NULL,0,MA2Period,0,MODE_EMA,PRICE_CLOSE,1);
double ma12=iMA(NULL,0,MA1Period,0,MODE_EMA,PRICE_CLOSE,2);
double ma22=iMA(NULL,0,MA2Period,0,MODE_EMA,PRICE_CLOSE,2);
//---
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
{
if(OrderType()==OP_BUY)
{
if(ma11<ma21 && ma12>ma22)
{
if(!OrderClose(OrderTicket(),OrderLots(),Bid,Slip,Red))
Print("OrderClose error ",GetLastError());
}
}
if(OrderType()==OP_SELL)
{
if(ma11>ma21 && ma12<ma22)
{
if(!OrderClose(OrderTicket(),OrderLots(),Ask,Slip,Blue))
Print("OrderClose error ",GetLastError());
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| Start function |
//+------------------------------------------------------------------+
void OnTick()
{
if(CountTrades()<1)
{
OpenPos();
}
else ClosePos();
}
//+------------------------------------------------------------------+
Для того, чтобы переписать советник воспользуемся библиотекой функций от Игоря Кима.
Нам понадобятся следующие функции:
Функция
ExistPositions().
Предназначена для проверки наличия открытых покупок или продаж.
//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 06.03.2008 |
//| Описание : Возвращает флаг существования позиций |
//+----------------------------------------------------------------------------+
//| Параметры: |
//| sy - наименование инструмента ("" - любой символ, |
//| NULL - текущий символ) |
//| op - операция (-1 - любая позиция) |
//| mn - MagicNumber (-1 - любой магик) |
//| ot - время открытия ( 0 - любое время открытия) |
//+----------------------------------------------------------------------------+
bool ExistPositions(string sy="", int op=-1, int mn=-1, datetime ot=0) {
int i, k=OrdersTotal();
if (sy=="0") sy=Symbol();
for (i=0; i<k; i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if (OrderSymbol()==sy || sy=="") {
if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
if (op<0 || OrderType()==op) {
if (mn<0 || OrderMagicNumber()==mn) {
if (ot<=OrderOpenTime()) return(True);
}
}
}
}
}
}
return(False);
}
Функция
OpenPosition() для online.
//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 21.03.2008 |
//| Описание : Открывает позицию и возвращает её тикет. |
//+----------------------------------------------------------------------------+
//| Параметры: |
//| sy - наименование инструмента (NULL или "" - текущий символ) |
//| op - операция |
//| ll - лот |
//| sl - уровень стоп |
//| tp - уровень тейк |
//| mn - MagicNumber |
//+----------------------------------------------------------------------------+
int OpenPosition(string sy, int op, double ll, double sl=0, double tp=0, int mn=0) {
color clOpen;
datetime ot;
double pp, pa, pb;
int dg, err, it, ticket=0;
string lsComm=WindowExpertName()+" "+GetNameTF(Period());
if (sy=="" || sy=="0") sy=Symbol();
if (op==OP_BUY) clOpen=clOpenBuy; else clOpen=clOpenSell;
for (it=1; it<=NumberOfTry; it++) {
if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) {
Print("OpenPosition(): Остановка работы функции");
break;
}
while (!IsTradeAllowed()) Sleep(5000);
RefreshRates();
dg=MarketInfo(sy, MODE_DIGITS);
pa=MarketInfo(sy, MODE_ASK);
pb=MarketInfo(sy, MODE_BID);
if (op==OP_BUY) pp=pa; else pp=pb;
pp=NormalizeDouble(pp, dg);
ot=TimeCurrent();
ticket=OrderSend(sy, op, ll, pp, Slippage, sl, tp, lsComm, mn, 0, clOpen);
if (ticket>0) {
if (UseSound) PlaySound(NameFileSound); break;
} else {
err=GetLastError();
if (pa==0 && pb==0) Message("Проверьте в Обзоре рынка наличие символа "+sy);
// Вывод сообщения об ошибке
Print("Error(",err,") opening position: ",ErrorDescription(err),", try ",it);
Print("Ask=",pa," Bid=",pb," sy=",sy," ll=",ll," op=",GetNameOP(op),
" pp=",pp," sl=",sl," tp=",tp," mn=",mn);
// Блокировка работы советника
if (err==2 || err==64 || err==65 || err==133) {
gbDisabled=True; break;
}
// Длительная пауза
if (err==4 || err==131 || err==132) {
Sleep(1000*300); break;
}
if (err==128 || err==142 || err==143) {
Sleep(1000*66.666);
if (ExistPositions(sy, op, mn, ot)) {
if (UseSound) PlaySound(NameFileSound); break;
}
}
if (err==140 || err==148 || err==4110 || err==4111) break;
if (err==141) Sleep(1000*100);
if (err==145) Sleep(1000*17);
if (err==146) while (IsTradeContextBusy()) Sleep(1000*11);
if (err!=135) Sleep(1000*7.7);
}
}
return(ticket);
}
Функция
ClosePositions().
Эта функция выполняет закрытие позиций, параметры которых удовлетворяют заданным значениям:
//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 19.02.2008 |
//| Описание : Закрытие позиций по рыночной цене |
//+----------------------------------------------------------------------------+
//| Параметры: |
//| sy - наименование инструмента ("" - любой символ, |
//| NULL - текущий символ) |
//| op - операция (-1 - любая позиция) |
//| mn - MagicNumber (-1 - любой магик) |
//+----------------------------------------------------------------------------+
void ClosePositions(string sy="", int op=-1, int mn=-1) {
int i, k=OrdersTotal();
if (sy=="0") sy=Symbol();
for (i=k-1; i>=0; i--) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if ((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) {
if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
if (mn<0 || OrderMagicNumber()==mn) ClosePosBySelect();
}
}
}
}
}
Добавляем эти функции в советник. Вместо функции CountTrades() у нас будет кимовская
ExistPositions(string sy="", int op=-1, int mn=-1, datetime ot=0);
В блоке OnTick()
Изменяем строку
if(CountTrades()<1)
на
if(ExistPositions(Symbol(),-1,Magic,0)==false)
Далее функцию PutOrder() заменим на
OpenPosition. Чтобы это сделать нам понадобятся еще дополнительные функции: GetNameTF, ErrorDescription,GetNameOP,Message. Добавим их также в код нашего эксперта.
//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 01.09.2005 |
//| Описание : Возвращает наименование таймфрейма |
//+----------------------------------------------------------------------------+
//| Параметры: |
//| TimeFrame - таймфрейм (количество секунд) (0 - текущий ТФ) |
//+----------------------------------------------------------------------------+
string GetNameTF(int TimeFrame=0) {
if (TimeFrame==0) TimeFrame=Period();
switch (TimeFrame) {
case PERIOD_M1: return("M1");
case PERIOD_M5: return("M5");
case PERIOD_M15: return("M15");
case PERIOD_M30: return("M30");
case PERIOD_H1: return("H1");
case PERIOD_H4: return("H4");
case PERIOD_D1: return("Daily");
case PERIOD_W1: return("Weekly");
case PERIOD_MN1: return("Monthly");
default: return("UnknownPeriod");
}
}
//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 01.09.2005 |
//| Описание : Возвращает наименование торговой операции |
//+----------------------------------------------------------------------------+
//| Параметры: |
//| op - идентификатор торговой операции |
//+----------------------------------------------------------------------------+
string GetNameOP(int op) {
switch (op) {
case OP_BUY : return("Buy");
case OP_SELL : return("Sell");
case OP_BUYLIMIT : return("Buy Limit");
case OP_SELLLIMIT: return("Sell Limit");
case OP_BUYSTOP : return("Buy Stop");
case OP_SELLSTOP : return("Sell Stop");
default : return("Unknown Operation");
}
}
string Error(int error_code)
{
string error_string;
//----
switch(error_code)
{
//---- Коды ошибок, возвращаемые торговым сервером:
case 0: error_string="Нет ошибок"; break;
case 1: error_string="Нет ошибки, но результат неизвестен"; break;
case 2: error_string="Общая ошибка"; break;
case 3: error_string="Неправильные параметры"; break;
case 4: error_string="Торговый сервер занят"; break;
case 5: error_string="Старая версия клиентского терминала"; break;
case 6: error_string="Нет связи с торговым сервером"; break;
case 7: error_string="Недостаточно прав"; break;
case 8: error_string="Слишком частые запросы"; break;
case 9: error_string="Недопустимая операция нарушающая функционирование сервера"; break;
case 64: error_string="Счет заблокирован"; break;
case 65: error_string="Неправильный номер счета"; break;
case 128: error_string="Истек срок ожидания совершения сделки"; break;
case 129: error_string="Неправильная цена"; break;
case 130: error_string="Неправильные стопы"; break;
case 131: error_string="Неправильный объем"; break;
case 132: error_string="Рынок закрыт"; break;
case 133: error_string="Торговля запрещена"; break;
case 134: error_string="Недостаточно денег для совершения операции"; break;
case 135: error_string="Цена изменилась"; break;
case 136: error_string="Нет цен"; break;
case 137: error_string="Брокер занят"; break;
case 138: error_string="Новые цены"; break;
case 139: error_string="Ордер заблокирован и уже обрабатывается"; break;
case 140: error_string="Разрешена только покупка"; break;
case 141: error_string="Слишком много запросов"; break;
case 145: error_string="Модификация запрещена, так как ордер слишком близок к рынку"; break;
case 146: error_string="Подсистема торговли занята"; break;
case 147: error_string="Использование даты истечения ордера запрещено брокером"; break;
case 148: error_string="Количество открытых и отложенных ордеров достигло предела, установленного брокером.";break;
default: error_string="Неизвестная ошибка.";
}
//----
return(error_string);
}
//+------------------------------------------------------------------+
//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 01.09.2005 |
//| Описание : Вывод сообщения в коммент и в журнал |
//+----------------------------------------------------------------------------+
//| Параметры: |
//| m - текст сообщения |
//+----------------------------------------------------------------------------+
void Message(string m) {
Comment(m);
if (StringLen(m)>0 && PrintEnable) {
if (AllMessages || prevMessage!=m) {
prevMessage=m;
Print(m);
}
}
}
//+----------------------------------------------------------------------------+
Также добавим необходимые глобальные переменные из библиотек
//------- Глобальные переменные для безошибочной компиляции -------------------+
bool AllMessages, PrintEnable, gbDisabled;
string prevMessage;
Добавим дополнительные входные переменные:
extern int NumberOfTry = 5; // Количество попыток выставления и закрытия ордера
extern string NameFileSound = "News.wav"; // Имя файла для мелодии открытия закрытия ордера
extern bool UseSound = True; // Использовать мелодию при открытии закрытии ордера
для открытия позиции в функции OpenPos() заменим функцию PutOrder() на кимовскую
OpenPosition
В результате OpenPos() будет выглядеть следующим образом:
void OpenPos()
{
double ma11=iMA(NULL,0,MA1Period,0,MODE_EMA,PRICE_CLOSE,1);
double ma21=iMA(NULL,0,MA2Period,0,MODE_EMA,PRICE_CLOSE,1);
double ma12=iMA(NULL,0,MA1Period,0,MODE_EMA,PRICE_CLOSE,2);
double ma22=iMA(NULL,0,MA2Period,0,MODE_EMA,PRICE_CLOSE,2);
//---- buy
if(ma11>ma21 && ma12<ma22)
{
OpenPosition(Symbol(),OP_BUY,Lots,NormalizeDouble(Ask-StopLoss*Point,Digits),NormalizeDouble(Ask+TakeProfit*Point,Digits),Magic);
}
//---- sell
if(ma11<ma21 && ma12>ma22)
{
OpenPosition(Symbol(),OP_SELL,Lots,NormalizeDouble(Ask+StopLoss*Point,Digits),NormalizeDouble(Ask-TakeProfit*Point,Digits),Magic);;
}
}
Закрытие позиций изменим таким же образом, подставив в функцию ClosePos() закрытие по киму ClosePositions(Symbol(),-1,Magic);
И получим:
void ClosePos()
{
double ma11=iMA(NULL,0,MA1Period,0,MODE_EMA,PRICE_CLOSE,1);
double ma21=iMA(NULL,0,MA2Period,0,MODE_EMA,PRICE_CLOSE,1);
double ma12=iMA(NULL,0,MA1Period,0,MODE_EMA,PRICE_CLOSE,2);
double ma22=iMA(NULL,0,MA2Period,0,MODE_EMA,PRICE_CLOSE,2);
//---
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
{
if(OrderType()==OP_BUY)
{
if(ma11<ma21 && ma12>ma22)
{
ClosePositions(Symbol(),-1,Magic);
}
}
if(OrderType()==OP_SELL)
{
if(ma11>ma21 && ma12<ma22)
{
ClosePositions(Symbol(),-1,Magic);
}
}
}
}
}
}
В результате таких манипуляций получаем, код для реальной торговли.
//+------------------------------------------------------------------+
//| 2MAMartin.mq4 |
//| Copyright 2015, AM2 |
//| http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2015, AM2"
#property link "http://www.forexsystems.biz"
#property description "Martin expert advisor"
extern int StopLoss = 1200;
extern int TakeProfit = 1400;
extern int Slip = 50;
extern int MA1Period = 9;
extern int MA2Period = 22;
extern int Magic = 123;
extern double Lots = 0.1;
extern int NumberOfTry = 5; // Количество попыток выставления и закрытия ордера
extern string NameFileSound = "News.wav"; // Имя файла для мелодии открытия закрытия ордера
extern bool UseSound = True; // Использовать мелодию при открытии закрытии ордера
//------- Глобальные переменные для безошибочной компиляции -------------------+
bool AllMessages,PrintEnable,gbDisabled;
string prevMessage;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 06.03.2008 |
//| Описание : Возвращает флаг существования позиций |
//+----------------------------------------------------------------------------+
//| Параметры: |
//| sy - наименование инструмента ("" - любой символ, |
//| NULL - текущий символ) |
//| op - операция (-1 - любая позиция) |
//| mn - MagicNumber (-1 - любой магик) |
//| ot - время открытия ( 0 - любое время открытия) |
//+----------------------------------------------------------------------------+
bool ExistPositions(string sy="",int op=-1,int mn=-1,datetime ot=0)
{
int i,k=OrdersTotal();
if(sy=="0") sy=Symbol();
for(i=0; i<k; i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==sy || sy=="")
{
if(OrderType()==OP_BUY || OrderType()==OP_SELL)
{
if(op<0 || OrderType()==op)
{
if(mn<0 || OrderMagicNumber()==mn)
{
if(ot<=OrderOpenTime()) return(True);
}
}
}
}
}
}
return(False);
}
//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 21.03.2008 |
//| Описание : Открывает позицию и возвращает её тикет. |
//+----------------------------------------------------------------------------+
//| Параметры: |
//| sy - наименование инструмента (NULL или "" - текущий символ) |
//| op - операция |
//| ll - лот |
//| sl - уровень стоп |
//| tp - уровень тейк |
//| mn - MagicNumber |
//+----------------------------------------------------------------------------+
int OpenPosition(string sy,int op,double ll,double sl=0,double tp=0,int mn=0)
{
color clOpen;
datetime ot;
double pp,pa,pb;
int dg,err,it,ticket=0;
string lsComm=WindowExpertName()+" "+GetNameTF(Period());
if(sy=="" || sy=="0") sy=Symbol();
if(op==OP_BUY) clOpen=Blue; else clOpen=Red;
for(it=1; it<=NumberOfTry; it++)
{
if(!IsTesting() && (!IsExpertEnabled() || IsStopped()))
{
Print("OpenPosition(): Остановка работы функции");
break;
}
while(!IsTradeAllowed()) Sleep(5000);
RefreshRates();
dg=MarketInfo(sy, MODE_DIGITS);
pa=MarketInfo(sy, MODE_ASK);
pb=MarketInfo(sy, MODE_BID);
if(op==OP_BUY) pp=pa; else pp=pb;
pp=NormalizeDouble(pp, dg);
ot=TimeCurrent();
ticket=OrderSend(sy,op,ll,pp,Slip,sl,tp,lsComm,mn,0,clOpen);
if(ticket>0)
{
if(UseSound) PlaySound(NameFileSound); break;
} else {
err=GetLastError();
if(pa==0 && pb==0) Message("Проверьте в Обзоре рынка наличие символа "+sy);
// Вывод сообщения об ошибке
Print("Error(",err,") opening position: ",ErrorDescription(err),", try ",it);
Print("Ask=",pa," Bid=",pb," sy=",sy," ll=",ll," op=",GetNameOP(op),
" pp=",pp," sl=",sl," tp=",tp," mn=",mn);
// Блокировка работы советника
if(err==2 || err==64 || err==65 || err==133)
{
gbDisabled=True; break;
}
// Длительная пауза
if(err==4 || err==131 || err==132)
{
Sleep(1000*300); break;
}
if(err==128 || err==142 || err==143)
{
Sleep(1000*66.666);
if(ExistPositions(sy,op,mn,ot))
{
if(UseSound) PlaySound(NameFileSound); break;
}
}
if(err==140 || err==148 || err==4110 || err==4111) break;
if(err==141) Sleep(1000*100);
if(err==145) Sleep(1000*17);
if(err==146) while(IsTradeContextBusy()) Sleep(1000*11);
if(err!=135) Sleep(1000*7.7);
}
}
return(ticket);
}
//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 19.02.2008 |
//| Описание : Закрытие позиций по рыночной цене |
//+----------------------------------------------------------------------------+
//| Параметры: |
//| sy - наименование инструмента ("" - любой символ, |
//| NULL - текущий символ) |
//| op - операция (-1 - любая позиция) |
//| mn - MagicNumber (-1 - любой магик) |
//+----------------------------------------------------------------------------+
void ClosePositions(string sy="",int op=-1,int mn=-1)
{
int i,k=OrdersTotal();
if(sy=="0") sy=Symbol();
for(i=k-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op))
{
if(OrderType()==OP_BUY || OrderType()==OP_SELL)
{
if(mn<0 || OrderMagicNumber()==mn) ClosePosBySelect();
}
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void ClosePosBySelect()
{
bool fc;
color clClose;
double ll,pa,pb,pp;
int err,it;
if(OrderType()==OP_BUY || OrderType()==OP_SELL)
{
for(it=1; it<=NumberOfTry; it++)
{
if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
while(!IsTradeAllowed()) Sleep(5000);
RefreshRates();
pa=MarketInfo(OrderSymbol(), MODE_ASK);
pb=MarketInfo(OrderSymbol(), MODE_BID);
if(OrderType()==OP_BUY)
{
pp=pb; clClose=White;
} else {
pp=pa; clClose=White;
}
ll=OrderLots();
fc=OrderClose(OrderTicket(), ll, pp, Slip, clClose);
if(fc)
{
if(UseSound) PlaySound(NameFileSound); break;
} else {
err=GetLastError();
if(err==146) while(IsTradeContextBusy()) Sleep(1000*11);
Print("Error(",err,") Close ",GetNameOP(OrderType())," ",
ErrorDescription(err),", try ",it);
Print(OrderTicket()," Ask=",pa," Bid=",pb," pp=",pp);
Print("sy=",OrderSymbol()," ll=",ll," sl=",OrderStopLoss(),
" tp=",OrderTakeProfit()," mn=",OrderMagicNumber());
Sleep(1000*5);
}
}
}
else Print("Некорректная торговая операция. Close ",GetNameOP(OrderType()));
}
//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 01.09.2005 |
//| Описание : Возвращает наименование таймфрейма |
//+----------------------------------------------------------------------------+
//| Параметры: |
//| TimeFrame - таймфрейм (количество секунд) (0 - текущий ТФ) |
//+----------------------------------------------------------------------------+
string GetNameTF(int TimeFrame=0)
{
if(TimeFrame==0) TimeFrame=Period();
switch(TimeFrame)
{
case PERIOD_M1: return("M1");
case PERIOD_M5: return("M5");
case PERIOD_M15: return("M15");
case PERIOD_M30: return("M30");
case PERIOD_H1: return("H1");
case PERIOD_H4: return("H4");
case PERIOD_D1: return("Daily");
case PERIOD_W1: return("Weekly");
case PERIOD_MN1: return("Monthly");
default: return("UnknownPeriod");
}
}
//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 01.09.2005 |
//| Описание : Возвращает наименование торговой операции |
//+----------------------------------------------------------------------------+
//| Параметры: |
//| op - идентификатор торговой операции |
//+----------------------------------------------------------------------------+
string GetNameOP(int op)
{
switch(op)
{
case OP_BUY : return("Buy");
case OP_SELL : return("Sell");
case OP_BUYLIMIT : return("Buy Limit");
case OP_SELLLIMIT: return("Sell Limit");
case OP_BUYSTOP : return("Buy Stop");
case OP_SELLSTOP : return("Sell Stop");
default : return("Unknown Operation");
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
string ErrorDescription(int error_code)
{
string error_string;
//----
switch(error_code)
{
//---- Коды ошибок, возвращаемые торговым сервером:
case 0: error_string="Нет ошибок"; break;
case 1: error_string="Нет ошибки, но результат неизвестен"; break;
case 2: error_string="Общая ошибка"; break;
case 3: error_string="Неправильные параметры"; break;
case 4: error_string="Торговый сервер занят"; break;
case 5: error_string="Старая версия клиентского терминала"; break;
case 6: error_string="Нет связи с торговым сервером"; break;
case 7: error_string="Недостаточно прав"; break;
case 8: error_string="Слишком частые запросы"; break;
case 9: error_string="Недопустимая операция нарушающая функционирование сервера"; break;
case 64: error_string="Счет заблокирован"; break;
case 65: error_string="Неправильный номер счета"; break;
case 128: error_string="Истек срок ожидания совершения сделки"; break;
case 129: error_string="Неправильная цена"; break;
case 130: error_string="Неправильные стопы"; break;
case 131: error_string="Неправильный объем"; break;
case 132: error_string="Рынок закрыт"; break;
case 133: error_string="Торговля запрещена"; break;
case 134: error_string="Недостаточно денег для совершения операции"; break;
case 135: error_string="Цена изменилась"; break;
case 136: error_string="Нет цен"; break;
case 137: error_string="Брокер занят"; break;
case 138: error_string="Новые цены"; break;
case 139: error_string="Ордер заблокирован и уже обрабатывается"; break;
case 140: error_string="Разрешена только покупка"; break;
case 141: error_string="Слишком много запросов"; break;
case 145: error_string="Модификация запрещена, так как ордер слишком близок к рынку"; break;
case 146: error_string="Подсистема торговли занята"; break;
case 147: error_string="Использование даты истечения ордера запрещено брокером"; break;
case 148: error_string="Количество открытых и отложенных ордеров достигло предела, установленного брокером.";break;
default: error_string="Неизвестная ошибка.";
}
//----
return(error_string);
}
//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 01.09.2005 |
//| Описание : Вывод сообщения в коммент и в журнал |
//+----------------------------------------------------------------------------+
//| Параметры: |
//| m - текст сообщения |
//+----------------------------------------------------------------------------+
void Message(string m)
{
Comment(m);
if(StringLen(m)>0 && PrintEnable)
{
if(AllMessages || prevMessage!=m)
{
prevMessage=m;
Print(m);
}
}
}
//+------------------------------------------------------------------+
//| Check for open order conditions |
//+------------------------------------------------------------------+
void OpenPos()
{
double ma11=iMA(NULL,0,MA1Period,0,MODE_EMA,PRICE_CLOSE,1);
double ma21=iMA(NULL,0,MA2Period,0,MODE_EMA,PRICE_CLOSE,1);
double ma12=iMA(NULL,0,MA1Period,0,MODE_EMA,PRICE_CLOSE,2);
double ma22=iMA(NULL,0,MA2Period,0,MODE_EMA,PRICE_CLOSE,2);
//---- buy
if(ma11>ma21 && ma12<ma22)
{
OpenPosition(Symbol(),OP_BUY,Lots,NormalizeDouble(Ask-StopLoss*Point,Digits),NormalizeDouble(Ask+TakeProfit*Point,Digits),Magic);
}
//---- sell
if(ma11<ma21 && ma12>ma22)
{
OpenPosition(Symbol(),OP_SELL,Lots,NormalizeDouble(Ask+StopLoss*Point,Digits),NormalizeDouble(Ask-TakeProfit*Point,Digits),Magic);;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void ClosePos()
{
double ma11=iMA(NULL,0,MA1Period,0,MODE_EMA,PRICE_CLOSE,1);
double ma21=iMA(NULL,0,MA2Period,0,MODE_EMA,PRICE_CLOSE,1);
double ma12=iMA(NULL,0,MA1Period,0,MODE_EMA,PRICE_CLOSE,2);
double ma22=iMA(NULL,0,MA2Period,0,MODE_EMA,PRICE_CLOSE,2);
//---
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
{
if(OrderType()==OP_BUY)
{
if(ma11<ma21 && ma12>ma22)
{
ClosePositions(Symbol(),-1,Magic);
}
}
if(OrderType()==OP_SELL)
{
if(ma11>ma21 && ma12<ma22)
{
ClosePositions(Symbol(),-1,Magic);
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| Start function |
//+------------------------------------------------------------------+
void OnTick()
{
if(ExistPositions(Symbol(),-1,Magic,0)==false)
{
OpenPos();
}
else ClosePos();
}
//+------------------------------------------------------------------+
Намного более простой способ, подключить библиотеки функций в самом начале, что позволяет не вставлять все функции в тело эксперта, а вызывать их при необходимости.
#include <b-Positions_include.mqh> // Библиотека функций для работы с позициями
#include <b-KimIV_include.mqh> // Библиотека дополнительных функций
#include <b-Orders_include.mqh> // Библиотека функций для работы с ордерами
Все библиотеки и код эксперта можно скачать одним архивом. Также в архиве есть все функции в формате HTML.
Скачать советник и библиотеки функций:
www.opentraders.ru/downloads/1093/
Комментарии (5)
27 Oxy Сообщений: 3430 - ..ιllιlι.lι.ιllι.ιlι..
35 AM2 Автор Сообщений: 16418 - Андрей
27 Oxy Сообщений: 3430 - ..ιllιlι.lι.ιllι.ιlι..
1. Торговые от TarasBY
2. Торговые от Andrey Shpilev
3. Трейлинг от TarasBY
4. Капитал от TarasBY
5. Ошибки от IURII TOKMAN
6. Капитал от Andrey Khatimlianskii
7. Тралы от Юрий Дзюбан
8. Торговые от Andrey Khatimlianskii
35 AM2 Автор Сообщений: 16418 - Андрей
35 AM2 Автор Сообщений: 16418 - Андрей
Зарегистрируйтесь или авторизуйтесь, чтобы оставить комментарий