Разработка и тестирование советника Fractal OutSide

 

Всем желающим предлагаю поучавствовать в разработке и тестировании советника Fractal OutSide.
План работы:
1. Разработка ;
2. Оптимизация на разных инструмнтах;
3. Тестирование на разных инструментах;
4. Доработка;
5. Оптимизация на разных инструмнтах;
6. Тестирование на разных инструментах;
7. Доработка;
8. и т. д.

В основе советника будет лежать принцип описаный здесь.
Идея советника описана здесь.

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

Выложил результаты оптимизации евро и фунта здесь (внизу страницы).
Сейчас оптимизируется на ене.


 

Вот код советника (для первого этапа):

extern double    Lot=0.0;
extern double    Risk=1.0;

extern double    a1=0.0;
extern double    a2=10.0;
extern double    b1=0.0;
extern double    b2=10.0;
extern int       c1=0;
extern int       c2=20;
extern int       d1=0;
extern int       d2=30;

extern int       Slippage=3; // Проскальзывание
extern int       Magic=1;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
// 
if(a1>a2){return(0);}
if(b1>b2){return(0);} 
if(c1>c2){return(0);} 
if(d1>d2){return(0);}  
if(c1>d1){return(0);} 
if(c2>d2){return(0);} 

//----
  double Tick=MarketInfo(Symbol(),MODE_TICKSIZE);
  double spread=MarketInfo(Symbol(),MODE_SPREAD)*Point;
  
int i;

// Нахождение точек для модели Buy

int iBp0, iBp1, iBp2, iBp3;
double Bp0, Bp1, Bp2, Bp3;
int Bc, Bd;
double Ba,Bb;
bool OkBp1;
bool OkBp0; // Для того, чтобы советник не обновлял ордера, при текущей свече с меньшим экстремумом

for(i=3;i<Bars;i++){
Bp1=iFractals(NULL,0,MODE_UPPER,i);
 if(Bp1>0){
 iBp1=i;
 //Print("iBp1=", iBp1, " Bp1=", Bp1);
 break;
 }
} 
if(Bp1>=High[iHighest(NULL,0,MODE_HIGH,iBp1,0)]){OkBp1=true;}  
//Print("OkBp1=", OkBp1);


iBp0=iLowest(NULL,0,MODE_LOW,iBp1,0);
Bp0=Low[iBp0];
if ( Bid>(Bp0+((Bp1-Bp0)/2)) ) {OkBp0=true;}
//Print("iBp0=", iBp0, " Bp0=", Bp0);
//Print("OkBp0=", OkBp0);

for(i=iBp1;i<Bars;i++){
Bp2=iFractals(NULL,0,MODE_LOWER,i);
  if(Bp2>0){
  iBp2=i;
  //Print("iBp2=", iBp2, " Bp2=", Bp2);
  break;
  }
}

for(i=iBp2;i<Bars;i++){
Bp3=iFractals(NULL,0,MODE_UPPER,i);
 if(Bp3>0){
 iBp3=i;
 //Print("iBp3=", iBp3, " Bp3=", Bp3);
 break;
 }
} 
Ba=(Bp3-Bp2)/(Bp1-Bp2);
Bb=(Bp1-Bp2)/(Bp1-Bp0);
Bc=iBp0;
Bd=iBp1;

// Нахождение точек для модели Sell

int iSp0, iSp1, iSp2, iSp3;
double Sp0, Sp1, Sp2, Sp3;
int Sc, Sd;
double Sa, Sb;
bool OkSp1;
bool OkSp0; // Для того, чтобы советник не обновлял ордера, при текущей свече с меньшим экстремумом

for(i=3;i<Bars;i++){
Sp1=iFractals(NULL,0,MODE_LOWER,i);
 if(Sp1>0){
 iSp1=i;
 //Print("iSp1=", iSp1, " Sp1=", Sp1);
 break;
 }
} 
if(Sp1<=Low[iLowest(NULL,0,MODE_LOW,iSp1,0)]){OkSp1=true;}  
//Print("OkSp1=", OkSp1);


iSp0=iHighest(NULL,0,MODE_HIGH,iSp1,0);
Sp0=High[iSp0];
if ( Ask<(Sp0-((Sp0-Sp1)/2)) ) {OkSp0=true;}
//Print("iSp0=", iSp0, " Sp0=", Sp0);
//Print("OkSp0=", OkSp0);

for(i=iSp1;i<Bars;i++){
Sp2=iFractals(NULL,0,MODE_UPPER,i);
  if(Sp2>0){
  iSp2=i;
  //Print("iSp2=", iSp2, " Sp2=", Sp2);
  break;
  }
}

for(i=iSp2;i<Bars;i++){
Sp3=iFractals(NULL,0,MODE_LOWER,i);
 if(Sp3>0){
 iSp3=i;
 //Print("iSp3=", iSp3, " Sp3=", Sp3);
 break;
 }
} 

Sa=(Sp2-Sp3)/(Sp2-Sp1);
Sb=(Sp2-Sp1)/(Sp0-Sp1);
Sc=iSp0;
Sd=iSp1;

// Параметры ордеров

  double B;
  double Bsl;
  double S;
  double Ssl;   
  double Btp; 
  double Stp; 
  B=NormalizeDouble(Bp1+1*Tick+spread,Digits);      // Цена для покупки
  Bsl=NormalizeDouble(Bp0-1*Tick,Digits);          // Стоп лосс для ордера на покупку
  Btp=NormalizeDouble(B+((NormalizeDouble((((B-Bsl)/Tick)*1),0))*Tick),Digits); // Тейк профит для ордера на покупку
  S=NormalizeDouble(Sp1-1*Tick,Digits);             // Цена для продажи
  Ssl=NormalizeDouble(Sp0+spread+1*Tick,Digits);  // Стоп лосс для ордера на продажу
  Stp=NormalizeDouble(S-((NormalizeDouble((((Ssl-S)/Tick)*1),0))*Tick),Digits); // Тейк профит для ордера на продажу
  

 

 
// Проверка открытых ордеров и выставленых ордеров
int total = OrdersTotal(); // Общее кол-во открытых и отложеных ордеров.
int Ticket = OrderTicket( ); // Возвращает номер тикета для текущего выбранного ордера. 
int PendingOrderBuy;  
int PendingOrderSell;   
bool MarketOrderBuy=false;
bool MarketOrderSell=false;
if(total>0){  
  for(i=0;i<=total;i++){
     if (OrderSelect(i, SELECT_BY_POS)==true){
        if (OrderSymbol()==Symbol() && OrderMagicNumber()==Magic){
         double OpenPrice=NormalizeDouble(OrderOpenPrice(),Digits);
         double StopLoss=NormalizeDouble(OrderStopLoss(),Digits);
         double TakeProfit=NormalizeDouble(OrderTakeProfit(),Digits);
         Ticket = OrderTicket( );        
           if (OrderType( )==OP_BUY){
           MarketOrderBuy = true; 
           }
           if (OrderType( )==OP_SELL){
           MarketOrderSell = true;
           }
           if (OrderType( )==OP_BUYSTOP){
           PendingOrderBuy = PendingOrderBuy+1;
           if(OpenPrice!=B) {OrderDelete(Ticket,CLR_NONE);} 
           if(StopLoss!=Bsl){OrderDelete(Ticket,CLR_NONE);}      
           if(PendingOrderBuy>1){OrderDelete(Ticket,CLR_NONE);}  
           }
           if (OrderType( )==OP_SELLSTOP){
           PendingOrderSell = PendingOrderSell+1;
           if(OpenPrice!=S) {OrderDelete(Ticket,CLR_NONE);} 
           if(StopLoss!=Ssl){OrderDelete(Ticket,CLR_NONE);}    
           if(PendingOrderSell>1){OrderDelete(Ticket,CLR_NONE);} 
           }  
        }
     }
  }
} 

 
bool Buy; // если Buy==true, значит появились условия для Buy stop
bool Sell;// если Sell==true, значит появились условия для Sell stop


if(
   OkBp0==true && OkBp1==true
    && Ba>a1 && Ba<a2 && Bb>b1 && Bb<b2 && Bc>c1 && Bd>d1 && Bc<c2 && Bd<d2
    && PendingOrderBuy==false 
    && MarketOrderBuy==false
   ){Buy=true;}
   
if(
   OkSp0==true && OkSp1==true
    && Sa>a1 && Sa<a2 && Sb>b1 && Sb<b2 && Sc>c1 && Sd>d1 && Sc<c2 && Sd<d2
    && PendingOrderSell==false
    && MarketOrderSell==false
   ){Sell=true;}
 
 
     // Расчёт рабочего лота
  double Minlot=MarketInfo(Symbol(),MODE_MINLOT);      // Размер минимального допустимого лота
  //Print ("Минимальный лот ", Minlot);
  int Normalize_Volume; // Колличество знаков после запятой для минимального лота
  if (Minlot==0.01){Normalize_Volume=2;} // Колличество знаков после запятой для минимального лота = 2
  if (Minlot==0.1){Normalize_Volume=1;}  // Колличество знаков после запятой для минимального лота = 1
  if (Minlot==1){Normalize_Volume=0;}    // Колличество знаков после запятой для минимального лота = 0
   double Balans=AccountBalance( ); // Баланс счёта
   double Prais_Point = MarketInfo(Symbol(), MODE_TICKVALUE); // Стоимость одного пункта
   int Bsl_Point=((B+Slippage*Tick)-Bsl)/Tick; // Размер стоплосса в пунктах для позиции Buy  
   int Ssl_Point=(Ssl-(S-Slippage*Tick))/Tick; // Размер стоплосса в пунктах для позиции Sell  
   double R=Balans/100*Risk; // Размер риска на одну позицию в валюте депозита
     if (Buy==true){ 
     double R_Bsl_Point = R / Bsl_Point; // Сколько должен стоить один пункт, в позиции Buy , с учётом уровня риска
     double B_Volume=NormalizeDouble((R_Bsl_Point/Prais_Point), Normalize_Volume); // Размер лота для позиции Buy  с учётом допустимого риска
     // Print (B_Volume);
     }     
     if (Sell==true){
     double R_Ssl_Point = R / Ssl_Point; // Сколько должен стоить один пункт, в позиции Sell , с учётом уровня риска
     double S_Volume=NormalizeDouble((R_Ssl_Point/Prais_Point), Normalize_Volume); // Размер лота для позиции Sell  с учётом допустимого риска
     // Print (S_Volume);
     }  
     if(Lot>0){B_Volume=Lot; S_Volume=Lot;}
     
  

// Выставление отложеных ордеров
if(Buy==true){
         Ticket=OrderSend (Symbol(),OP_BUYSTOP,B_Volume,B,Slippage,Bsl,Btp,NULL,Magic,0,CLR_NONE);
         if(Ticket<0)
         {
         //Print("Buy. ", B, ", ", Bsl, ", ", Btp, "  OrderSend failed with error #",GetLastError());
         return(0);
         }
}
if(Sell==true){
         Ticket=OrderSend (Symbol(),OP_SELLSTOP,S_Volume,S,Slippage,Ssl,Stp,NULL,Magic,0,CLR_NONE);
         if(Ticket<0)
         {
         //Print("Sell. ", S, ", ", Ssl, ", ", Stp, " OrderSend failed with error #",GetLastError());
         return(0);
         }
}          
     
      
//----
   return(0);
  }
 
Не совсем понял логику открытия поз. В какой моент выставляется стопордер в случае бая и при каких условиях? Вы тестировали после оптимизации на интервалах вне оптимизации?
 
Andrey4-min писал(а) >>

Всем желающим предлагаю поучавствовать в разработке и тестировании советника Fractal OutSide.
План работы:
1. Разработка ;
2. Оптимизация на разных инструмнтах;
3. Тестирование на разных инструментах;
4. Доработка;
5. Оптимизация на разных инструмнтах;
6. Тестирование на разных инструментах;
7. Доработка;
8. и т. д.

В основе советника будет лежать принцип описаный здесь.
Идея советника описана здесь.

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

Выложил результаты оптимизации евро и фунта здесь (внизу страницы).
Сейчас оптимизируется на ене.

Тема кстати заслуживает внимания.

На мой взгляд судя по рисунку приложенном, целесообразней было бы войти с пробоем точки 3 а не 1и с профитом выставленным по Фибо 2 к 3.

 
Dezil >>:
Не совсем понял логику открытия поз. В какой моент выставляется стопордер в случае бая и при каких условиях? Вы тестировали после оптимизации на интервалах вне оптимизации? 

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

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

Вконце первого этапа будет как минимум 4-е набора параметров оптимизации, полученные на евро, фунте, ене и швецарце.

Затем параметры полученые при оптимизации на евро будут протестированы на фунте, ене и швецарце.

параметры полученые при оптимизации на фунте будут протестированы на евро, ене и швецарце.

параметры полученые при оптимизации на ене будут протестированы на фунте, евро и швецарце.

параметры полученые при оптимизации на швецарце будут протестированы на фунте, ене и евро.

Таким образом будет вычеслены те параметры, которые на всех четырёх валютных парах дали лучший результат.

 
Vlad72 >>:

Тема кстати заслуживает внимания.

На мой взгляд судя по рисунку приложенном, целесообразней было бы войти с пробоем точки 3 а не 1и с профитом выставленным по Фибо 2 к 3.

Спасибо за идею, обязательно проверю такую комбинацию.

 

Также и лося надо ставить не так (моё мнение), может я и ошибаюсь.

Часто бывает что цену закидывает и она возвращается на прежний курс и продолжает движение очень резво.

Попробуй сделать так :если уж вход делать типа паттернов 1-2-3, то и выход сделай так же.

Только чур поделись советником, я сейчас вручную оттестил эту систему на тестере на часовках с начала года 2009 на 4 парах в среднем с пары в месяц выходит по 500 пунктов при тике в 1 бакс.

 
Vlad72 >>:

Также и лося надо ставить не так (моё мнение), может я и ошибаюсь.

Часто бывает что цену закидывает и она возвращается на прежний курс и продолжает движение очень резво.

Попробуй сделать так :если уж вход делать типа паттернов 1-2-3, то и выход сделай так же.

Только чур поделись советником, я сейчас вручную оттестил эту систему на тестере на часовках с начала года 2009 на 4 парах в среднем с пары в месяц выходит по 500 пунктов при тике в 1 бакс.

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

 

Не трать время зря, я посмотрел твой советник и он работает не корректно!!.Смотрел его на часах и ужас .Цена идёт "вструю" а он где то выискивает фракталы, там и близко их нет.

Причина обращения: