Предлагаю написать советник по стратегии Anatoly74

Предлагаю написать советник по стратегии Anatoly74

anatoly74.opentraders.ru/14283.html#comment86256

Набросал небольшое ТЗ.

Идентификацию тренда будем производить по лентам Боллинджера. Так легче оптимизировать. При резкой смене тренда ленты раширяются на расстояние Delta, тогда покупаем или продаем с рынка в направлении тренда и набрасываем

( Читать дальше )


Простейший сеточный советник "Hello!"

Простейший сеточный советник «Hello!» на одном индикаторе.

Рабочий тайм фрейм Н1. Хорошо карабкается по тренду и усредняется во флете. Не любит резкой смены тренда. При уходе позиции в минус добавляет усредняющие ордера и пересчитывает стопы. Оптимизирован на 2000-2013 годах. Дает хороший форвард тест.

«Hello!» потому что работает по хаям и лоу :) 



( Читать дальше )


MeasureFIBO - добавляем второй инидкатор Фибоначчи с предустановленными нестандартными значениями

Задача была поставлена от tibi: дать ему второй индикатор Фибо, в котором можно было бы предустановить значения, не меняющиеся после удаления инидкатора с графика.
Задача усложнилась тем, что значения Фибы у tibi секретные *ninja* , а значит надо научить его самостоятельно поставить нужные значения в индикатор так, чтобы они потом сохранялись.

Ок,

( Читать дальше )


Обновление платформы MetaTrader 4
[*]



Уважаемые участники форума!

Сегодня было произведено плановое обновление реального торгового сервера. Цель нововведений — расширение функциональности, увеличение стабильности и быстродействия платформы MetaTrader 4.

Большая часть изменений коснулась языка программирования MQL4. Это позволило в несколько раз увеличить скорость выполнения и повысить

( Читать дальше )


Простейший скрипт - советник для анализа статистики.

Подобный анализ статистики рынка с сайта www.statlist.net можно сделать с помощью простейшего скрипта.



С 2000-го года на D1, паттерн — свеча черная, свеча белая — следующая белая.
Вероятность 48.2%, в пятницу 65.2%.





( Читать дальше )


(mql4) Функция расчета лота в зависимости от величины просадки

Недавно я писал о методе увеличения прибыли с помощью введения зависимости лота от величины просадки. Читать подробнее о методе

Идею (которую раньше проверял в Excel) удалось воплотить в код MQL4. В этой заметке выкладываю получившийся код.

( Читать дальше )


Приемы MQL: открытие только одной сделки за один бар

По мере изучения MQL и перевода своих стратегий на код сталкиваюсь с некоторыми типовыми задачами, решение которых планирую выкладывать в данной группе.

Итак, первое, с чем я столкнулся — это необходимость открытия только одной сделки в текущем баре. Т.е. получили сигнал в текущем баре и после открытия сделки больше в этом баре новых сделок не открываем.

Есть разные способы решения задачи. От использования предопределенной переменной Bars в данном случае предостерегают, т.к. Bars может изменяться, например, при докачке истории.

Выбрал следующий способ.

1.Добавляем функцию IfOrderYetOpen

( Читать дальше )


По просьбе wizzard... Инфосоветник. (Часть 2)

Официальное продолжение решение вопроса моего друга wizzard-а...

… необходимо получить график зависимости суммы прибыли(убытка) по текущим открытым сделкам от времени. То есть если открыто три сделки +5, -12, +15 то значение +8.
Интересна зависимость этого параметра от времени. Можно каждую минуту вычислять этот параметр и складывать в файл.


Часть 1 состоит в том, чтобы получать значения об открытых ордерах всех валютных пар, полностью, их сумму в общем отображении.
Часть 2 состоит в том, чтобы задавая периодичность времени в настройках, эксперт мог сохранять в файл значение Прибыль_Убыток каждый раз с периодичностью n минут и записывать время в которое это произошло.

Часть 1 находится вот здесь
Ниже представлена реализация второй части *улыбается*

( Читать дальше )


Пишем усреднитель.

Воспользуемся для нашего усреднителя готовой торговой системой одного из успешных управляющих на рынке FOREX.

Суть системы в следующем:

1) В ноль-ноль по терминальному времени открывается две сделки по GBPUSD, одна на север, вторая на юг. Тейк короткий — 10-15 пп. Лот — 0,01 на 100$ депозита.
2) Дальше, одна из сделок закрывается по тейку. На втором направлении начинается усреднение. Пипстеп рассчитывается из следующих соображений:
а) исторически сложившееся максимальное бескоррекционное движение GBPUSD,
б) максимально допустимая просадка в 50% на N-ное количество колен.
На сегодня этот диапазон составляет 2-2,5 фигуры.
3) Далее, если этого расстояния оказывается недостаточно для закрытия серии, тогда срабатывает отложенный локирующий ордер. Сова отключается и разруливание лока производится вручную.

За основу возьмем код эксперта Ilan 1.4.

Далее достаточно немного изменить блок сигнала для первой сделки:


     
if (TradeNow && total<1){
         
double PrevCl = iClose(Symbol(),0,2);
         
double CurrCl = iClose(Symbol(),0,1);
         
SellLimit = Bid;  
         
BuyLimit = Ask;
   
           
if(!ShortTrade && !LongTrade){
               
NumOfTrades = total;
                 
if(PrevCl > CurrCl){
                     iLots
= fGetLots(OP_SELL);
                       
if(iLots>0){//#
                           ticket
= OpenPendingOrder(OP_SELL,iLots,SellLimit,slip,SellLimit,0,0,EAName+"-"+NumOfTrades,MagicNumber,0,HotPink);
                           
if(ticket<0){Print(iLots,"Error: ",GetLastError()); return(0);}
                           
LastBuyPrice = FindLastBuyPrice();
                           
NewOrdersPlaced = true;
                       
}//#
                 
}  
                 
else{
                     iLots
= fGetLots(OP_BUY);
                       
if(iLots>0){//#      
                           ticket
= OpenPendingOrder(OP_BUY,iLots,BuyLimit,slip,BuyLimit,0,0,EAName+"-"+NumOfTrades,MagicNumber,0,Lime);
                             
if(ticket<0){Print(iLots,"Error: ",GetLastError()); return(0);}
                                 
LastSellPrice = FindLastSellPrice();
                                 
NewOrdersPlaced = true;
                             
}//#
                       
}
                 
}      
               
if(ticket>0) expiration = CurTime()+MaxTradeOpenHours*60*60;
               
TradeNow = false;
           
}



Новый вариант у нас будет иметь вид:


     
if (TradeNow && total<1){

         
SellLimit = Bid;  
         
BuyLimit = Ask;
   
           
if(!ShortTrade && !LongTrade && Hour()==0)
           
{
               
NumOfTrades = total;
                 
{
                     iLots
= fGetLots(OP_SELL);
                       
if(iLots>0){//#
                           ticket
= OpenPendingOrder(OP_SELL,iLots,SellLimit,slip,SellLimit,0,Bid-TakeProfit*Point,EAName+"-"+NumOfTrades,MagicNumber,0,HotPink);
                           
if(ticket<0){Print(iLots,"Error: ",GetLastError()); return(0);}
                           
LastBuyPrice = FindLastBuyPrice();
                           
NewOrdersPlaced = true;
                       
}//#
                 
}  
                       
{
                     iLots
= fGetLots(OP_BUY);
                       
if(iLots>0){//#      
                           ticket
= OpenPendingOrder(OP_BUY,iLots,BuyLimit,slip,BuyLimit,0,Ask+TakeProfit*Point,EAName+"-"+NumOfTrades,MagicNumber,0,Lime);
                             
if(ticket<0){Print(iLots,"Error: ",GetLastError()); return(0);}
                                 
LastSellPrice = FindLastSellPrice();
                                 
NewOrdersPlaced = true;
                             
}//#
                       
}
                 
}      
               
if(ticket>0) expiration = CurTime()+MaxTradeOpenHours*60*60;
               
TradeNow = false;
           
}



И наш усреднитель уже может выставлять две разнонаправленные сделки в ноль часов, затем выводить в плюс убыточную сделку.



Рис.1. Схема работы усреднителя.

И вот новый код готов!


//+------------------------------------------------------------------+
//|                                   2008                   Ilan1.4 |
//+------------------------------------------------------------------+


#property copyright "Nikisaki@yandex.ru"

extern int     MMType=1; // Тип ММ: 0-Lots, 1-как было в 1.2, 2-мартингейл (коэффициент LotExponent)
extern bool    UseClose=false; // закрытие по убытку PipStep. рекомендутся false
extern bool    UseAdd=true; // переоткрытие с новым лотом. лот для переоткрытия считается по LotExponent независимо от MMType рекомендутся = true
extern double  LotExponent = 1.667; // умножение лотов в серии по експоненте для вывода в безубыток. первый лот 0.1, серия: 0.16, 0.26, 0.43 ...
extern double  slip = 3; // допустимое проскальзывание цены в пипсах
extern double  Lots = 0.1; // теперь можно и микролоты 0.01 при этом если стоит 0.1 то следующий лот в серии будет 0.16
extern double  LotsDigits=2; // 2 - микролоты 0.01, 1 - мини лоты 0.1, 0 - нормальные лоты 1.0
extern double  TakeProfit = 10; // Уровень прибыли в пипсаз от цены открытия.
 
double  Stoploss = 500; // эти три параметра не работают
 
double  TrailStart = 10;
 
double  TrailStop = 10;
extern double  PipStep = 30; // растоянию в пипсах убытка на котором открываеться следующий ордер колена.
extern int     MaxTrades = 10;
extern bool    UseEquityStop = false;
extern double  TotalEquityRisk = 20; //loss as a percentage of equity
extern bool    UseTrailingStop = false;
extern bool    UseTimeOut = false;
extern double  MaxTradeOpenHours = 48;

int MagicNumber = 12324;
double PriceTarget, StartEquity, BuyTarget, SellTarget;
double AveragePrice, SellLimit, BuyLimit;
double LastBuyPrice, LastSellPrice, ClosePrice, Spread;
int flag;
string EAName = "CostAvg-Pyramid";
datetime timeprev
=0, expiration;
int NumOfTrades=0;
double iLots;
int cnt=0, total;
double Stopper=0;  
bool TradeNow = false, LongTrade=false, ShortTrade=false;
int ticket;
bool NewOrdersPlaced = false;

int init()
{
 
Spread = MarketInfo(Symbol(), MODE_SPREAD)*Point;
 
return(0);
}

int deinit()
{
 
return(0);
}

int start(){

 
 
   
if (UseTrailingStop){
     
TrailingAlls(TrailStart, TrailStop, AveragePrice);
   
}
   
if (UseTimeOut){
     
if(CurTime() >= expiration){
         
CloseThisSymbolAll();
         
Print("Closed All due to TimeOut");
     
}
   
}
 
   
if(timeprev==Time[0]){
     
return(0);
   
}
 
   timeprev
=Time[0];
 
   
double CurrentPairProfit = CalculateProfit();
     
if(UseEquityStop){
         
if(CurrentPairProfit<0 && MathAbs(CurrentPairProfit)>(TotalEquityRisk/100)*AccountEquityHigh()){
           
CloseThisSymbolAll();
           
Print("Closed All due to Stop Out");
           
NewOrdersPlaced = false;
         
}
     
}

 
   total
=CountTrades();
   
     
if (total == 0){
         flag
= 0;
     
}
     
   
double LastBuyLots;
   
double LastSellLots;
     
     
for(cnt=OrdersTotal()-1;cnt>=0;cnt--){// поиск последнего направления
         
OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
           
if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=MagicNumber)continue;
               
if(OrderSymbol()==Symbol()&&OrderMagicNumber()==MagicNumber)
                 
if(OrderType()==OP_BUY){
                     
LongTrade = true;
                     
ShortTrade = false;
                     
LastBuyLots=OrderLots();
                     
break;
                 
}
               
if(OrderSymbol()==Symbol()&&OrderMagicNumber()==MagicNumber)
                 
if(OrderType()==OP_SELL){
                     
LongTrade = false;
                     
ShortTrade = true;
                     
LastSellLots=OrderLots();
                     
break;
               
}
     
}
 
     
if(total>0 && total <= MaxTrades){
         
RefreshRates();
         
LastBuyPrice = FindLastBuyPrice();
         
LastSellPrice = FindLastSellPrice();
           
if(LongTrade && (LastBuyPrice - Ask) >= (PipStep*Point)){
               
TradeNow = true;
           
}
           
if(ShortTrade && (Bid - LastSellPrice) >= (PipStep*Point)){
               
TradeNow = true;
           
}
     
}
 
     
if (total < 1){
         
ShortTrade = false;
         
LongTrade = false;
         
TradeNow = true;
         
StartEquity = AccountEquity();
     
}

     
if (TradeNow){
         
LastBuyPrice = FindLastBuyPrice();
         
LastSellPrice = FindLastSellPrice();
           
if(ShortTrade){
                 
if(UseClose){
                     fOrderCloseMarket
(false,true);
                     iLots
= NormalizeDouble(LotExponent*LastSellLots,LotsDigits);
                 
}
                 
else{
                     iLots
= fGetLots(OP_SELL);
                 
}
                 
if(UseAdd){
                     
NumOfTrades = total;              
                       
if(iLots>0){//#
                           
RefreshRates();
                           ticket
= OpenPendingOrder(OP_SELL,iLots,Bid,slip,Ask,0,0,EAName+"-"+NumOfTrades,MagicNumber,0,HotPink);
                           
if(ticket<0){Print("Error: ",GetLastError()); return(0);}
                           
LastSellPrice = FindLastSellPrice();
                           
TradeNow = false;
                           
NewOrdersPlaced = true;
                       
}//#
                 
}
           
}
           
else if (LongTrade){  
                 
if(UseClose){
                     fOrderCloseMarket
(true,false);
                     iLots
= NormalizeDouble(LotExponent*LastBuyLots,LotsDigits);
                 
}          
                 
else{
                     iLots
= fGetLots(OP_BUY);
                 
}
                 
if(UseAdd){
                     
NumOfTrades = total;
                       
if(iLots>0){//#
                           ticket
= OpenPendingOrder(OP_BUY,iLots,Ask,slip,Bid,0,0,EAName+"-"+NumOfTrades,MagicNumber,0,Lime);
                           
if(ticket<0){Print("Error: ",GetLastError()); return(0);}
                           
LastBuyPrice = FindLastBuyPrice();
                           
TradeNow = false;
                           
NewOrdersPlaced = true;
                       
}//#
                 
}
           
}
     
}
 
     
if (TradeNow && total<1){

         
SellLimit = Bid;  
         
BuyLimit = Ask;
   
           
if(!ShortTrade && !LongTrade && Hour()==0)
           
{
               
NumOfTrades = total;
                 
{
                     iLots
= fGetLots(OP_SELL);
                       
if(iLots>0){//#
                           ticket
= OpenPendingOrder(OP_SELL,iLots,SellLimit,slip,SellLimit,0,Bid-TakeProfit*Point,EAName+"-"+NumOfTrades,MagicNumber,0,HotPink);
                           
if(ticket<0){Print(iLots,"Error: ",GetLastError()); return(0);}
                           
LastBuyPrice = FindLastBuyPrice();
                           
NewOrdersPlaced = true;
                       
}//#
                 
}  
                       
{
                     iLots
= fGetLots(OP_BUY);
                       
if(iLots>0){//#      
                           ticket
= OpenPendingOrder(OP_BUY,iLots,BuyLimit,slip,BuyLimit,0,Ask+TakeProfit*Point,EAName+"-"+NumOfTrades,MagicNumber,0,Lime);
                             
if(ticket<0){Print(iLots,"Error: ",GetLastError()); return(0);}
                                 
LastSellPrice = FindLastSellPrice();
                                 
NewOrdersPlaced = true;
                             
}//#
                       
}
                 
}      
               
if(ticket>0) expiration = CurTime()+MaxTradeOpenHours*60*60;
               
TradeNow = false;
           
}

//----------------------- CALCULATE AVERAGE OPENING PRICE
   total
=CountTrades();
   
AveragePrice=0;
   
double Count = 0;
   
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
   
{
   
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
   
if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=MagicNumber)
     
continue;
   
if(OrderSymbol()==Symbol()&&OrderMagicNumber()==MagicNumber)
     
if(OrderType()==OP_BUY || OrderType()==OP_SELL)  
     
{
       
AveragePrice=AveragePrice+OrderOpenPrice()*OrderLots();
       
Count = Count + OrderLots();
     
}
   
}
   
if(total > 0)
   
AveragePrice=NormalizeDouble(AveragePrice/Count, Digits);

   
//----------------------- RECALCULATE STOPLOSS & PROFIT TARGET BASED ON AVERAGE OPENING PRICE
   
if(NewOrdersPlaced)
   
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
   
{
   
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
   
if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=MagicNumber)
     
continue;
   
if(OrderSymbol()==Symbol()&&OrderMagicNumber()==MagicNumber)
     
if(OrderType()==OP_BUY) // Calculate profit/stop target for long
     
{
     
PriceTarget=AveragePrice+(TakeProfit*Point);
     
BuyTarget = PriceTarget;
     
Stopper=AveragePrice-(Stoploss*Point);
//      Stopper=0;
      flag
= 1;
     
}
   
if(OrderSymbol()==Symbol()&&OrderMagicNumber()==MagicNumber)
     
if(OrderType()==OP_SELL) // Calculate profit/stop target for short
     
{
     
PriceTarget=AveragePrice-(TakeProfit*Point);
     
SellTarget = PriceTarget;
     
Stopper=AveragePrice+(Stoploss*Point);  
//      Stopper=0;
      flag
= 1;
     
}
   
}
//----------------------- IF NEEDED CHANGE ALL OPEN ORDERS TO NEWLY CALCULATED PROFIT TARGET    
 
if(NewOrdersPlaced)
 
if(flag==1)// check if average has really changed
 
{  
   
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
   
{
//     PriceTarget=total;
     
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);            
     
if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=MagicNumber)
     
continue;
     
if(OrderSymbol()==Symbol()&&OrderMagicNumber()==MagicNumber)
//      OrderModify(OrderTicket(),0,Stopper,PriceTarget,0,Yellow);// set all positions to averaged levels
     
OrderModify(OrderTicket(),AveragePrice,OrderStopLoss(),PriceTarget,0,Yellow);// set all positions to averaged levels
     
NewOrdersPlaced = false;
   
}
 
}
}
double ND(double v){return(NormalizeDouble(v,Digits));}

int fOrderCloseMarket(bool aCloseBuy=true,bool aCloseSell=true){
   
int tErr=0;
     
for(int i=OrdersTotal()-1;i>=0;i--){
         
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
           
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber){
               
if(OrderType()==OP_BUY && aCloseBuy){
                 
RefreshRates();
                     
if(!IsTradeContextBusy()){
                       
if(!OrderClose(OrderTicket(),OrderLots(),ND(Bid),5,CLR_NONE)){
                           
Print("Error close BUY "+OrderTicket());//+" "+fMyErDesc(GetLastError()));
                           tErr
=-1;
                       
}
                     
}
                     
else{
                       
static int lt1=0;
                           
if(lt1!=iTime(NULL,0,0)){
                              lt1
=iTime(NULL,0,0);
                             
Print("Need close BUY "+OrderTicket()+". Trade Context Busy");
                           
}            
                       
return(-2);
                     
}  
               
}
               
if(OrderType()==OP_SELL && aCloseSell){
                 
RefreshRates();
                     
if(!IsTradeContextBusy()){                        
                       
if(!OrderClose(OrderTicket(),OrderLots(),ND(Ask),5,CLR_NONE)){
                           
Print("Error close SELL "+OrderTicket());//+" "+fMyErDesc(GetLastError()));
                           tErr
=-1;
                       
}  
                     
}
                     
else{
                       
static int lt2=0;
                           
if(lt2!=iTime(NULL,0,0)){
                              lt2
=iTime(NULL,0,0);
                             
Print("Need close SELL "+OrderTicket()+". Trade Context Busy");
                           
}            
                       
return(-2);
                     
}          
               
}
           
}
         
}
     
}
   
return(tErr);
}  


double fGetLots(int aTradeType){
   
double tLots;
     
switch(MMType){
         
case 0:
            tLots
=Lots;
         
break;
         
case 1:
            tLots
=NormalizeDouble(Lots*MathPow(LotExponent,NumOfTrades),LotsDigits);
         
break;
         
case 2:
           
int LastClosedTime=0;
            tLots
=Lots;
               
for(int i=OrdersHistoryTotal()-1;i>=0;i--){
                 
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)){
                     
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber){
                       
if(LastClosedTime<OrderCloseTime()){
                           
LastClosedTime=OrderCloseTime();
                             
if(OrderProfit()<0){
                                 tLots
=NormalizeDouble(OrderLots()*LotExponent,LotsDigits);
                             
}
                             
else{
                                 tLots
=Lots;
                             
}
                       
}
                     
}
                 
}
                 
else{
                     
return(-3);
                 
}
               
}
         
break;
     
}
     
     
if(AccountFreeMarginCheck(Symbol(),aTradeType,tLots)<=0){
         
return(-1);
     
}
     
if(GetLastError()==134){
         
return(-2);
     
}
   
return(tLots);    
}

int CountTrades()
{
 
int count=0;
 
int trade;
 
for(trade=OrdersTotal()-1;trade>=0;trade--)
 
{
 
OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
 
 
if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=MagicNumber)
   
continue;
   
 
if(OrderSymbol()==Symbol()&&OrderMagicNumber()==MagicNumber)
 
if(OrderType()==OP_SELL || OrderType()==OP_BUY)
   count
++;
 
}//for
 
return(count);
}


void CloseThisSymbolAll()
{
 
int trade;
 
for(trade=OrdersTotal()-1;trade>=0;trade--)
 
{
 
OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);

 
if(OrderSymbol()!=Symbol())
   
continue;
 
if(OrderSymbol()==Symbol() && OrderMagicNumber()== MagicNumber)
 
{
   
if(OrderType()==OP_BUY)
   
OrderClose(OrderTicket(),OrderLots(),Bid,slip,Blue);

   
if(OrderType()==OP_SELL)
   
OrderClose(OrderTicket(),OrderLots(),Ask,slip,Red);
 
}
 
Sleep(1000);
 
}
}

int OpenPendingOrder(int pType,double pLots,double pLevel,int sp, double pr, int sl, int tp,string pComment,int pMagic,datetime pExpiration,color pColor)
{
 
int ticket=0;
 
int err=0;
 
int c = 0;
 
int NumberOfTries = 100;
 
switch (pType)
 
{
     
case OP_BUYLIMIT:
         
for(c = 0 ; c < NumberOfTries ; c++)
         
{
            ticket
=OrderSend(Symbol(),OP_BUYLIMIT,pLots,pLevel,sp,StopLong(pr,sl),TakeLong(pLevel,tp),pComment,pMagic,pExpiration,pColor);
            err
=GetLastError();
           
if(err==0)
           
{
               
break;
           
}
           
else
           
{
               
if(err==4 || err==137 ||err==146 || err==136) //Busy errors
               
{
                 
Sleep(1000);
                 
continue;
               
}
               
else //normal error
               
{
                 
break;
               
}  
           
}
         
}  
         
break;
     
case OP_BUYSTOP:
         
for(c = 0 ; c < NumberOfTries ; c++)
         
{
            ticket
=OrderSend(Symbol(),OP_BUYSTOP,pLots,pLevel,sp,StopLong(pr,sl),TakeLong(pLevel,tp),pComment,pMagic,pExpiration,pColor);
            err
=GetLastError();
           
if(err==0)
           
{
               
break;
           
}
           
else
           
{
               
if(err==4 || err==137 ||err==146 || err==136) //Busy errors
               
{
                 
Sleep(5000);
                 
continue;
               
}
               
else //normal error
               
{
                 
break;
               
}  
           
}
         
}
         
break;
     
case OP_BUY:
         
for(c = 0 ; c < NumberOfTries ; c++)
         
{  
           
RefreshRates();
            ticket
=OrderSend(Symbol(),OP_BUY,pLots,Ask,sp,StopLong(Bid,sl),TakeLong(Ask,tp),pComment,pMagic,pExpiration,pColor);
            err
=GetLastError();
           
if(err==0)
           
{
               
break;
           
}
           
else
           
{
               
if(err==4 || err==137 ||err==146 || err==136) //Busy errors
               
{
                 
Sleep(5000);
                 
continue;
               
}
               
else //normal error
               
{
                 
break;
               
}  
           
}
         
}
         
break;
     
case OP_SELLLIMIT:
         
for(c = 0 ; c < NumberOfTries ; c++)
         
{
            ticket
=OrderSend(Symbol(),OP_SELLLIMIT,pLots,pLevel,sp,StopShort(pr,sl),TakeShort(pLevel,tp),pComment,pMagic,pExpiration,pColor);
            err
=GetLastError();
           
if(err==0)
           
{
               
break;
           
}
           
else
           
{
               
if(err==4 || err==137 ||err==146 || err==136) //Busy errors
               
{
                 
Sleep(5000);
                 
continue;
               
}
               
else //normal error
               
{
                 
break;
               
}  
           
}
         
}
         
break;
     
case OP_SELLSTOP:
         
for(c = 0 ; c < NumberOfTries ; c++)
         
{
            ticket
=OrderSend(Symbol(),OP_SELLSTOP,pLots,pLevel,sp,StopShort(pr,sl),TakeShort(pLevel,tp),pComment,pMagic,pExpiration,pColor);
            err
=GetLastError();
           
if(err==0)
           
{
               
break;
           
}
           
else
           
{
               
if(err==4 || err==137 ||err==146 || err==136) //Busy errors
               
{
                 
Sleep(5000);
                 
continue;
               
}
               
else //normal error
               
{
                 
break;
               
}  
           
}
         
}
         
break;
     
case OP_SELL:
         
for(c = 0 ; c < NumberOfTries ; c++)
         
{
            ticket
=OrderSend(Symbol(),OP_SELL,pLots,Bid,sp,StopShort(Ask,sl),TakeShort(Bid,tp),pComment,pMagic,pExpiration,pColor);
            err
=GetLastError();
           
if(err==0)
           
{
               
break;
           
}
           
else
           
{
               
if(err==4 || err==137 ||err==146 || err==136) //Busy errors
               
{
                 
Sleep(5000);
                 
continue;
               
}
               
else //normal error
               
{
                 
break;
               
}  
           
}
         
}
         
break;
 
}
 
 
return(ticket);
}  

double StopLong(double price,int stop)
{
 
if(stop==0)
 
return(0);
 
else
 
return(price-(stop*Point));
}

double StopShort(double price,int stop)
{
 
if(stop==0)
 
return(0);
 
else
 
return(price+(stop*Point));
}

double TakeLong(double price,int take)
{
 
if(take==0)
 
return(0);
 
else
 
return(price+(take*Point));
}

double TakeShort(double price,int take)
{
 
if(take==0)
 
return(0);
 
else
 
return(price-(take*Point));
}


double CalculateProfit()
{

   
double Profit=0;
   
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
   
{
   
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
   
if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=MagicNumber)
     
continue;
   
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
     
if(OrderType()==OP_BUY || OrderType()==OP_SELL)  
     
{
       
Profit=Profit+OrderProfit();
     
}
   
}

 
return(Profit);
}

void TrailingAlls(int start,int stop, double AvgPrice)
{
 
int profit;
 
double stoptrade;
 
double stopcal;
 
 
if(stop==0)
 
return;
 
 
int trade;
 
for(trade=OrdersTotal()-1;trade>=0;trade--)
 
{
 
if(!OrderSelect(trade,SELECT_BY_POS,MODE_TRADES))
   
continue;

 
if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=MagicNumber)
   
continue;

 
if(OrderSymbol()==Symbol()||OrderMagicNumber()==MagicNumber)
 
{
   
if(OrderType()==OP_BUY)
   
{
    profit
=NormalizeDouble((Bid-AvgPrice)/Point,0);
   
if(profit<start)
     
continue;
    stoptrade
=OrderStopLoss();
    stopcal
=Bid-(stop*Point);
   
if(stoptrade==0||(stoptrade!=0&&stopcal>stoptrade))
//     OrderModify(OrderTicket(),OrderOpenPrice(),stopcal,OrderTakeProfit(),0,Blue);
     
OrderModify(OrderTicket(),AvgPrice,stopcal,OrderTakeProfit(),0,Aqua);
   
}//Long
 
   
if(OrderType()==OP_SELL)
   
{
    profit
=NormalizeDouble((AvgPrice-Ask)/Point,0);
   
if(profit<start)
     
continue;
    stoptrade
=OrderStopLoss();
    stopcal
=Ask+(stop*Point);
   
if(stoptrade==0||(stoptrade!=0&&stopcal<stoptrade))
//     OrderModify(OrderTicket(),OrderOpenPrice(),stopcal,OrderTakeProfit(),0,Red);
     
OrderModify(OrderTicket(),AvgPrice,stopcal,OrderTakeProfit(),0,Red);
   
}//Shrt
 
}
 
Sleep(1000);
 
}//for
}




double AccountEquityHigh()
{
 
static double AccountEquityHighAmt,PrevEquity;
 
if(CountTrades()==0) AccountEquityHighAmt=AccountEquity();
   
if(AccountEquityHighAmt < PrevEquity) AccountEquityHighAmt=PrevEquity;
   
else AccountEquityHighAmt=AccountEquity();
 
PrevEquity = AccountEquity();
 
return(AccountEquityHighAmt);
}


double FindLastBuyPrice()
{
 
double oldorderopenprice = 0, orderprice;
 
int cnt, oldticketnumber = 0, ticketnumber;
 
 
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
 
{
 
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
 
if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=MagicNumber)
   
continue;
 
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber && OrderType()==OP_BUY)  
 
{
     ticketnumber
= OrderTicket();
     
if(ticketnumber>oldticketnumber)
     
{
      orderprice
=OrderOpenPrice();
      oldorderopenprice
=orderprice;
      oldticketnumber
=ticketnumber;
     
}
 
}
 
}
 
 
return(orderprice);
}

double FindLastSellPrice()
{
 
double oldorderopenprice = 0, orderprice;
 
int cnt, oldticketnumber = 0, ticketnumber;
 
 
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
 
{
 
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
 
if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=MagicNumber)
   
continue;
 
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber && OrderType()==OP_SELL)  
 
{
     ticketnumber
= OrderTicket();
     
if(ticketnumber>oldticketnumber)
     
{
      orderprice
=OrderOpenPrice();
      oldorderopenprice
=orderprice;
      oldticketnumber
=ticketnumber;
     
}
 
}
 
}
 
 
return(orderprice);
}



В результате получаем вот такую картинку:


Рис.2. Один из результатов оптимизации эксперта с начала 2009 года.

Догоним и перегоним господина Таниса!


Добавим функцию Мартингейла к советнику.

Возьмем простейший советник торгующий с фиксированными значениями стопов.


//+------------------------------------------------------------------+
//|                                                        WellX.mq4 |
//|                                            Copyright © 2011, AM2 |
//|                                      http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, AM2"
#property link      "http://www.forexsystems.biz"

#define MAGIC 20111010

extern double StopLoss   = 400;
extern double TakeProfit = 800;
extern double ADXPeriod  = 14;
extern double BBPeriod   = 20;
extern double BBDev      = 2;
extern int Level         = 30;
extern double Lots       = 1;

bool b=true, s=true;  

//+------------------------------------------------------------------+
int start()
 
{
//---- go trading only for first tiks of new bar
   
if(Volume[0]>1) return;  
//----  
   
int p=0;    
//---- get Indicatorrs
   
double bbh=iBands(NULL,0,BBPeriod,BBDev,0,PRICE_CLOSE,MODE_UPPER,0);
   
double bbl=iBands(NULL,0,BBPeriod,BBDev,0,PRICE_CLOSE,MODE_LOWER,0);
   
double adx=iADX(NULL,0,ADXPeriod,PRICE_CLOSE,MODE_MAIN,0);
 
//----

   
for (int i=0; i<OrdersTotal(); i++)
   
{
     
if (OrderSelect(i, SELECT_BY_POS)==true)
     
{  
         
if (OrderSymbol()!=Symbol() || OrderMagicNumber()!=MAGIC) continue;
         
if (OrderType()==OP_BUY || OrderType()==OP_SELL) p++;      
     
}  
   
}  
//---- buy
   
if(adx<Level && Ask<bbl && b && p<1)  
     
{
     
OrderSend(Symbol(),OP_BUY,Lots,Ask,30,Ask-StopLoss*Point,Ask+TakeProfit*Point,"",MAGIC,0,Blue);
      b
=false;
      s
=true;  
     
}        
//---- sell  
   
if(adx<Level && Bid>bbh && s && p<1)  
     
{
     
OrderSend(Symbol(),OP_SELL,Lots,Bid,30,Bid+StopLoss*Point,Bid-TakeProfit*Point,"",MAGIC,0,Red );
      b
=true;
      s
=false;
     
}      
//----
   
return(0);
 
}
//+------------------------------------------------------------------+



Результат оптимизации эксперта с 2000-го года ниже:



Функция Мартингейла может иметь следующий вид:


//+------------------------------------------------------------------+
int LossCount = 0;
double LotsArray[]={0.1,0.2,0.4,0.8,1.6,3.2};

...

double Lots()
 
{
   
double Lot = Lots;
   
int total = OrdersHistoryTotal();
   
for (int i = 0; i < total; i++)
   
{
     
OrderSelect(i, SELECT_BY_POS, MODE_HISTORY);
     
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MAGIC)
       
{
         
if (OrderProfit() > 0)
         
{
           
Lot=LotsArray[0];
           
LossCount = 0;    
         
}        
         
else
           
{
           
Lot=LotsArray[LossCount+1];
           
LossCount++;
           
}
       
}
   
}
   
return(Lot);
}
//+------------------------------------------------------------------+


Остается только собрать все воедино:


//+------------------------------------------------------------------+
//|                                                        WellX.mq4 |
//|                                            Copyright © 2011, AM2 |
//|                                      http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, AM2"
#property link      "http://www.forexsystems.biz"

#define MAGIC 20111010

extern double StopLoss   = 400;
extern double TakeProfit = 800;
extern double ADXPeriod  = 14;
extern double BBPeriod   = 20;
extern double BBDev      = 2;
extern int Level         = 30;
extern double Lots       = 0.1;

int LossCount = 0;
double LotsArray[]={0.1,0.2,0.4,0.8,1.6,3.2};
bool b=true, s=true;

//+------------------------------------------------------------------+
int start()
 
{
//---- go trading only for first tiks of new bar
   
if(Volume[0]>1) return;  
//----  
   
int p=0;    
//---- get Indicatorrs
   
double bbh=iBands(NULL,0,BBPeriod,BBDev,0,PRICE_CLOSE,MODE_UPPER,0);
   
double bbl=iBands(NULL,0,BBPeriod,BBDev,0,PRICE_CLOSE,MODE_LOWER,0);
   
double adx=iADX(NULL,0,ADXPeriod,PRICE_CLOSE,MODE_MAIN,0);
 
//----

   
for (int i=0; i<OrdersTotal(); i++)
   
{
     
if (OrderSelect(i, SELECT_BY_POS)==true)
     
{  
         
if (OrderSymbol()!=Symbol() || OrderMagicNumber()!=MAGIC) continue;
         
if (OrderType()==OP_BUY || OrderType()==OP_SELL) p++;      
     
}  
   
}  
//---- buy
   
if(adx<Level && Ask<bbl && b && p<1)  
     
{
     
OrderSend(Symbol(),OP_BUY,Lots(),Ask,30,Ask-StopLoss*Point,Ask+TakeProfit*Point,"",MAGIC,0,Blue);
      b
=false;
      s
=true;  
     
}        
//---- sell  
   
if(adx<Level && Bid>bbh && s && p<1)  
     
{
     
OrderSend(Symbol(),OP_SELL,Lots(),Bid,30,Bid+StopLoss*Point,Bid-TakeProfit*Point,"",MAGIC,0,Red );
      b
=true;
      s
=false;
     
}      
//----
   
return(0);
 
}
//+------------------------------------------------------------------+
double Lots()
 
{
   
double Lot = Lots;
   
int total = OrdersHistoryTotal();
   
for (int i = 0; i < total; i++)
   
{
     
OrderSelect(i, SELECT_BY_POS, MODE_HISTORY);
     
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MAGIC)
       
{
         
if (OrderProfit() > 0)
         
{
           
Lot=LotsArray[0];
           
LossCount = 0;    
         
}        
         
else
           
{
           
Lot=LotsArray[LossCount+1];
           
LossCount++;
           
}
       
}
   
}
   
return(Lot);
}
//+------------------------------------------------------------------+


Прибыль эксперта после оптимизации конечно же куда скромнее, но для наглядности вполне подходит.



Результат с того же 2000-го года.

Дерзайте, юные умы!


Решение: ошибка Cannot open file в MT

Иногда при попытке запустить даже стандартный скрипт из поставки MetaTrader (например, period_converter) пользователь сталкивается с ситуацией, что скрипт не работает. Неделю или месяц назад работал, а сегодня нет.

В таких случаях нужно посмотреть логи на закладке «Эксперты». Если там обнаружите ошибку:

2011.09.08 10:25:35     Cannot open file 'C:\Program Files\MetaTrader\experts\scripts\period_converter.ex4' on the EURUSD,H1


то проблема решается просто

( Читать дальше )


Как прикрутить к советнику трейлингстоп и вывод в безубыток?

Как известно вывод позиции в безубыток и последующий трейлинг позиции, могут значительно повысить прибыльность торговой системы.

Чтобы проделать необходимые нам операции воспользуемся готовыми функциями трейлингстопа и БУ.

( Читать дальше )


Как написать простейший советник на MQL4?

Подобным вопросом наверняка задается любой новичок желающий освоить написание экспертов для торговли на рынке FOREX. При желании и некоторой сноровке эту задачу можно решить за один вечер.

Для начала сформулируем правила открытия и закрытия позиций.

( Читать дальше )


Используйте RefreshRates()

Уважаемые разработчики!

Опыт Тестовой Лаборатории показал, что многие разработчики не используют в коде своих советников функцию RefreshRates(). Совершенно напрасно! Игнорирование этой функции может привести к пропуску сделок.

Эксперты работают с копией исторических данных. Когда вычисления производятся в течение долгого времени, эти данные могут устареть, в логах появляются записи «Old Tick».



В результате нарушается работа советника. В Лаборатории были случаи, когда советник перестает полностью функционировать до перезагрузки. Использование функции RefreshRates() в большинстве случаев решает проблему.


Тестирование советника, торгующего на основе средней скользящей "Diaspar"





Я бы хотел протестировать в реальном времени советник, сигналы которого основаны на пересечении графика и скользящей средней с определенными настройками. Этой стратегией вручную пользуется

( Читать дальше )


Загрузка...