Share
Go down
gandra
Global Moderator
Number of messages : 3578
Points : 8505
Date of Entry : 2013-01-13
Year : 49
Residence Country : Serbia
View user profilehttps://www.mql5.com/en/users/drgandrahttps://www.fxjunction.com/profile/gandra/account/I

ma1 Trend EA + Trend Indikator

on Thu Jul 18, 2019 11:58 pm
Pozdrav svima,

Kao sto sam danas i obecao, videcete kako i na koji nacin napraviti svoj sopstveni indikator , i  iskoristiti ga za davanje buy i sell signala za  robotica koji vam je dostupan za preuzimanje. Takodje ovaj indikator mozete koristi i samostalno. Da bi smo kreirali indikator otvorimo nasu mt5 platformu , kliknemo na MetaEditor,  a zatim u gornjem levom uglu kliknemo na New ikonicu. Izaberemo trecu opciju odozgo : "Custom Indicator", kliknemo next, damo ime nasem  indikatoru, a zatim next (ovde nista ne cekiramo), pa opet next (ni ovde nista ne cekiramo ), i na kraju finish. Obrisite sve  i plusnite kod ispod. Zatim Kompajlujte kod klikom na Compile ikonicu. Ovo sam  zaboravio da vam napomenem u tekstovima pre ovog.  Notacija je samo za pocetnike! A zatim proverimo da nema slucajno koja greska ili upozorenje, mada ne bi trebalo da bude, jer kod mene je kod kompajlovan sa 0 error(s), i 0 warning(s).  Klikom na Spojler mozete preuzeti ovaj trend indikator.
custom_trend_indicator.mq5:

Code:

//+------------------------------------------------------------------+
//|                                       custom_trend_indicator.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                               [You must be registered and logged in to see this link.] |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "drenjanind@mail.ru"
#property version   "1.00"
#property indicator_chart_window

#property indicator_buffers 2
#property indicator_plots   2

#property indicator_type1 DRAW_ARROW
#property indicator_type2 DRAW_ARROW

#property indicator_color1 clrGreen
#property indicator_color2 clrRed

double buff_up[];
double buff_down[];

int ArrowShift = -30;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0, buff_up, INDICATOR_DATA);
   SetIndexBuffer(1, buff_down, INDICATOR_DATA);
  
   IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
  
   PlotIndexSetInteger(0, PLOT_ARROW, 71);
   PlotIndexSetInteger(1, PLOT_ARROW, 72);
  
   PlotIndexSetInteger(0, PLOT_ARROW_SHIFT, ArrowShift);
   PlotIndexSetInteger(1, PLOT_ARROW_SHIFT, -ArrowShift);
  
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{

   int i, limit;
  
   if (rates_total < 5)
   return(0);
  
   if (prev_calculated < 7)
   {
     limit =2;
    
     ArrayInitialize(buff_down, EMPTY_VALUE);
     ArrayInitialize(buff_up, EMPTY_VALUE);
   } else limit = rates_total - 5;
  
   for(i = limit; i < rates_total - 3; i++)
   {
    if (close[i] > close[i+2] && close[i] > close[i+3] && close[i] >= close[i-1] && close[i] >+ close[i-2])
    buff_up[i] = close[i];
    else buff_up[i]= EMPTY_VALUE;
    
    if (close[i] < close[i+2] && close[i] < close[i+3] && close[i] <= close[i-1] && close[i] <= close[i-2])
    buff_down[i] = close[i];
    else buff_down[i]= EMPTY_VALUE;
   }
   return(rates_total);
}
//+------------------------------------------------------------------+

Jos nesto da napomenem. Sistem automatski ubaci nas indikator u folder  Indicators. Tako ne berite brigu oko toga. Sad je potrebno da generisemo templejts za naseg robotica. Kliknemo opet na ikonicu New izaberemo prvu opciju Expert Advisor (templates) , next (dajte ime ovom robotu ), next itd.. na kraju finish.  I tako , posto smo generisali  templejts , obrisite sve i plusnite kod iz spojlera ispod. Kompajlujte kod i pokrenite test.
trendy_ea.mq5 :

Code:

//+------------------------------------------------------------------+
//|                                                    trendy_ea.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                               [You must be registered and logged in to see this link.] |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "drenjanind@mail.ru"
#property version   "1.00"

#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>


CPositionInfo    _pos;
CTrade         _trade;
CSymbolInfo   _symbol;

double Lot        = 0.1;
int    StopLoss    = 30;
int    TakeProfit  = 50;
ulong MagicNumber  = 5050;

ulong Slippage     = 30;

double SL;
double TP;

int indi;  //  skaracenica od custum trend indikatora
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   if (!_symbol.Name(Symbol()))
    return(INIT_FAILED);
  
   RefreshRates();
  
  
   _trade.SetExpertMagicNumber(MagicNumber);
   // funkcija koja dozvoljava rad naseg EA sa svim tipovima racuna
   if (IsFillingTypeAllowed(SYMBOL_FILLING_FOK))
     _trade.SetTypeFilling(ORDER_FILLING_FOK);
   else if (IsFillingTypeAllowed(SYMBOL_FILLING_IOC))
     _trade.SetTypeFilling(ORDER_FILLING_IOC);
   else _trade.SetTypeFilling(ORDER_FILLING_RETURN);
   // slip page
   _trade.SetDeviationInPoints(Slippage);
   // tri ili pet decimala
   if (_symbol.Digits() == 3 || _symbol.Digits() == 5){
     SL = StopLoss *10;
     TP = TakeProfit *10;
   }
   else{
    SL = StopLoss;
    TP = TakeProfit;
   }
   // inicijalizacija  indikatora
   indi =iCustom(_symbol.Name(), Period(), "custom_trend_indicator");
   if (indi == INVALID_HANDLE){
    Print("indi create failed");
    return(INIT_FAILED);
    }
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
  static datetime last_time = 0;
  datetime current_time = iTime(_symbol.Name(), _Period, 0);
  
  if (current_time == last_time)
  return;
  
  if (!RefreshRates())
  {
   last_time =0;
   return;
  }
  
  last_time = current_time;
  
// indi trend
  int buffer_size = 30; // za trideset sveca
  double  buffer_open[];
  double  buffer_high[];
  double   buffer_low[];
  double buffer_close[];
  
  if (CopyBuffer(indi, LOWER_LINE, 0, buffer_size, buffer_open) != buffer_size || ArraySize(buffer_open) != buffer_size)
  {
   last_time =0;
   return;
  }
  
  if (CopyBuffer(indi, UPPER_LINE, 0, buffer_size, buffer_high) != buffer_size || ArraySize(buffer_high) != buffer_size)
  {
   last_time =0;
   return;
  }

  if (CopyBuffer(indi, LOWER_LINE, 0, buffer_size, buffer_low) != buffer_size || ArraySize(buffer_low) != buffer_size)
  {
   last_time =0;
   return;
  }
  
  if (CopyBuffer(indi, LOWER_LINE, 0, buffer_size, buffer_close) != buffer_size || ArraySize(buffer_close) != buffer_size)
  {
   last_time =0;
   return;
  }
  
 ArraySetAsSeries(buffer_open , true);
 ArraySetAsSeries(buffer_high , true);
 ArraySetAsSeries(buffer_low , true);
 ArraySetAsSeries(buffer_close , true);
 
 double current_open = EMPTY_VALUE;
 double current_high = EMPTY_VALUE;
 double current_low  = EMPTY_VALUE;
 double current_close  = EMPTY_VALUE;
 
 double last_open = EMPTY_VALUE;
 double last_high = EMPTY_VALUE;
 double last_low  = EMPTY_VALUE;
 double last_close  = EMPTY_VALUE;
 
 for (int i =1; i< buffer_size; i++)
 {
  if (buffer_open[i] != EMPTY_VALUE && buffer_open[i] != 0)
  {
   if (last_open == EMPTY_VALUE)
   {
    last_open = buffer_open[i];
    continue;
   }
  }
  if (buffer_high[i] != EMPTY_VALUE && buffer_high[i] != 0)
  {
   if (last_high == EMPTY_VALUE)
   {
    last_high = buffer_high[i];
    continue;
   }
   }
   if (buffer_low[i] != EMPTY_VALUE && buffer_low[i] != 0)
  {
   if (last_low == EMPTY_VALUE)
   {
    last_open = buffer_open[i];
    continue;
   }
  }
   if (current_close == EMPTY_VALUE)
   {
    current_close = buffer_close[i];
    break;
   }
  }
 
 for (int i =1; i< buffer_size; i++)
 {
  if (buffer_high[i] != EMPTY_VALUE && buffer_high[i] != 0)
  {
   if (last_high == EMPTY_VALUE)
   {
    last_high = buffer_high[i];
    continue;
   }
   if (current_high == EMPTY_VALUE)
   {
    current_high = buffer_high[i];
    break;
   }
  }
 }  

// provera za buy sell signal
 if (last_low != EMPTY_VALUE && current_low != EMPTY_VALUE)
 {
   if (current_low < last_low)
   {
     CloseTrade(POSITION_TYPE_SELL);
     if (PosCount(POSITION_TYPE_BUY) == 0)
     {
       double sl = _symbol.Ask() - SL * _Point;
       double tp = _symbol.Ask() + TP * _Point;
       OpenBuy(sl, tp);
     }
   }
 }
 
  if (last_high != EMPTY_VALUE && current_high != EMPTY_VALUE)
 {
   if (current_high < last_high)
   {
     CloseTrade(POSITION_TYPE_BUY);
     if (PosCount(POSITION_TYPE_SELL) == 0)
     {
       double sl = _symbol.Ask() + SL * _Point;
       double tp = _symbol.Ask() - TP * _Point;
       OpenSell(sl, tp);
     }
   }
 }
}
//+------------------------------------------------------------------+
bool IsFillingTypeAllowed(int fill_type)
{
  int filling = _symbol.TradeFillFlags();
  
  return((filling && fill_type) == fill_type);
}
//+------------------------------------------------------------------+
int PosCount (ENUM_POSITION_TYPE position_type)
{
 int count =0;
 
 for(int i = PositionsTotal()-1; i>0; i--)
 {
  if (_pos.SelectByIndex(i) &&
     _pos.Symbol() == _symbol.Name() &&
     _pos.Magic() == MagicNumber &&
     _pos.PositionType() == position_type )
  count ++;
 }
 return(count);
}
//+------------------------------------------------------------------+
void CloseTrade(ENUM_POSITION_TYPE  position_type)
{
 for (int i = PositionsTotal() -1; i>=0; i--)
 {
  if (_pos.SelectByIndex(i)          &&
     _pos.Symbol() == _symbol.Name() &&
     _pos.Magic() == MagicNumber     &&
     _pos.PositionType() == position_type )
  _trade.PositionClose(_pos.Ticket());
 }
}
//+------------------------------------------------------------------+
bool RefreshRates()
{
 if (!_symbol.RefreshRates()){
  Print("quote update failed");
  return(false);
 }

 if (_symbol.Ask() == 0 || _symbol.Bid() == 0){
  return(false);
 }
 
 return(true);
}
//+------------------------------------------------------------------+
void OpenBuy(double sl, double tp)
{
  sl = _symbol.NormalizePrice(sl);
  tp = _symbol.NormalizePrice(tp);
  
  if (_trade.Buy(Lot, _symbol.Name(), _symbol.Ask(), sl, tp))
  {
    if (_trade.ResultDeal() == 0)
    {
     Print("failed to open buy order");
    }
  }
  else
    {
     Print("failed to open buy order");
    }
}
//+------------------------------------------------------------------+
void OpenSell(double sl, double tp)
{
  sl = _symbol.NormalizePrice(sl);
  tp = _symbol.NormalizePrice(tp);
  
  if (_trade.Sell(Lot, _symbol.Name(), _symbol.Bid(), sl, tp))
  {
    if (_trade.ResultDeal() == 0)
    {
     Print("failed to open sell order");
    }
  }
  else
    {
     Print("failed to open sell order");
    }
}
//+------------------------------------------------------------------+

Robota sam testirao na EURUSD,  GBPUSD, EURJPY , dnevnom vremenskom opsegu, sa inicijalnim depozitom od samo 1000 USD,  i  polugom 1:33.  Rezultati testiranja su sledeci:
EURUSD:

[You must be registered and logged in to see this image.]
[You must be registered and logged in to see this image.]
[You must be registered and logged in to see this image.]
GBPUSD:

[You must be registered and logged in to see this image.]
[You must be registered and logged in to see this image.]
[You must be registered and logged in to see this image.]
EURJPY:

[You must be registered and logged in to see this image.]
[You must be registered and logged in to see this image.]
[You must be registered and logged in to see this image.]

Robot je napravi profit na prva dva valutna para. A na eurjpy mali gubitak negde oko 40 dolara. Tako, sad preostaje samo da se igramo sa logikom koja daje/generise  buy/sell  signal. Zatim potrebno je da se dodaju jos neke stvarcice  kao sto su trjeling stop ili break even  za pocetak. Licno mislim da je pozeljno da se doda samo jedna od te dve opcije. Mozda je trejling stop bolja opcija bar za mene. I jedan i drugi primer imate vec odradjen , tako da vam preostaje samo da ih implementirate u ovaj EA.

Takodje nisam zaboravio moje obecanje koje sam dao ihihi, a odnosi se na jedan komplet operativan EA u kojem su implementirane obe opcije. Vec imam skuckanog robota pod nazivom "Portugalac", tako, eto ocekujte ga uskoro u ovoj sekciji.

Toliko ,odoh.
Back to top
Permissions in this forum:
You cannot reply to topics in this forum