Скачать MetaTrader 5
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Размещай ссылки на платные сигналы. Получай партнерскую долю!
Ilnaz
448
Ilnaz 2009.05.07 10:30 

Я пытался написать советник с открытием дополнительных лотов по тренду.

Суть заключается вот в чем.

Мы совершаем сделку на покупку/на продажу после сигнала.

После по истечению n-го количество пунктов совершаем еще одну сделку в том же направлений и так совершаем несколько сделок по тренду регулируя максимальное количество лотов.

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


И все сделки закрываем  тейкпрофитом, для всех сделок один тейк профит(по цене)

извиняюсь за качество рисунка

Но есть ошибки в коде. Дополнительные сделки по тренду открываются не по прохождению n-го количества лотов, советник открывает сразу несколько лотов. Пыталься исправить но не получилось, поэтому прошу помочи у всех кто разбирается в mql.  

#property copyright "Copyright © 2008, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
extern double pips=25;
extern double per_K=50;
extern double per_D=50;
extern double slow=3;
extern double zoneBUY=30;
extern double zoneSELL=70;
extern double Lot=0.01;
extern double  Prots= 10; 
extern double Macd_1=12;
extern double Macd_2=26;
extern double Macd_3=9;
extern double MACDOpenLevel=3;
extern double TP=100;
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
  double cenaoppos,Cena;
  double stochastic_osnovnoi_nast,stochastic_signal_nast;
  double stochastic_osnovnoi_prosh,stochastic_signal_prosh;
  stochastic_osnovnoi_nast=iStochastic(NULL,0,per_K,per_D,slow,MODE_LWMA,1,0,1);
  stochastic_signal_nast= iStochastic(NULL,0,per_K,per_D,slow,MODE_LWMA,1,1,1);
  stochastic_osnovnoi_prosh= iStochastic(NULL,0,per_K,per_D,slow,MODE_LWMA,1,0,0);
  stochastic_signal_prosh= iStochastic(NULL,0,per_K,per_D,slow,MODE_LWMA,1,1,0);
  double MacdCurrent, MacdPrevious, SignalCurrent;
   double SignalPrevious;
   MacdCurrent=iMACD(NULL,0,Macd_1,Macd_2,Macd_3,PRICE_CLOSE,MODE_MAIN,0);
   MacdPrevious=iMACD(NULL,0,Macd_1,Macd_2,Macd_3,PRICE_CLOSE,MODE_MAIN,1);
   SignalCurrent=iMACD(NULL,0,Macd_1,Macd_2,Macd_3,PRICE_CLOSE,MODE_SIGNAL,0);
   SignalPrevious=iMACD(NULL,0,Macd_1,Macd_2,Macd_3,PRICE_CLOSE,MODE_SIGNAL,1);
   
  if (OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
  {
  if( stochastic_osnovnoi_nast<stochastic_signal_nast && 
  stochastic_osnovnoi_prosh>stochastic_signal_prosh
      && stochastic_osnovnoi_nast>zoneSELL && 
      stochastic_osnovnoi_prosh>zoneSELL)
       if( MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious && //сигнальная MACD пересекает основную MACD снизу ввверх
         MacdCurrent>(MACDOpenLevel*Point))
  OrderSend(Symbol(),OP_SELL,Lots(),Bid,3,0,Ask+TP*Point);
  }
  
  if (OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true)
  {
   cenaoppos=OrderOpenPrice();
  if (OrderType()==OP_SELL)
  Cena=Bid;//цена 
            if((cenaoppos-pips*Point)<Cena)//если цена открытия-пипс *пунктам больше цены, то//----
                                                                                        
             
 OrderSend(Symbol(),OP_SELL,Lots(),Bid,3,0,0,0,Red); 
  }
  
  if (OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
  {
  if(stochastic_osnovnoi_nast>stochastic_signal_nast && 
  stochastic_osnovnoi_prosh<stochastic_signal_prosh
      &&  stochastic_osnovnoi_nast<zoneBUY && 
      stochastic_osnovnoi_prosh<zoneBUY)
       if ( MacdCurrent>SignalCurrent && MacdPrevious<SignalPrevious &&//сигнальная MACD пересекает основную MACD сверху вниз
         MathAbs(MacdCurrent)>(MACDOpenLevel*Point))
  OrderSend(Symbol(),OP_BUY,Lots(),Ask,3,0,Bid-TP*Point);
  return (0);
  }
  
  if (OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true)
  {
 cenaoppos=OrderOpenPrice();//цена открытия
      
  if (OrderType()==OP_BUY)
 Cena=Ask;//цена 
            if((cenaoppos+pips*Point)<Cena)//если цена открытия +пипс(=)*пунктам меньше цены, то 
              OrderSend(Symbol(),OP_BUY,Lots(),Ask,3,0,0,0,Green);
  }
 
  return(0);
  }
//+------------------------------------------------------------------+
double Lots()                                            // Вычисление лотов
   {
//============================================================================================
   Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1);// Вычисляем колич. лотов  
   double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT);   // Минимально допустимая стоим. лотов
   if (Lot == 0 ) Lot = Min_Lot;                         // Для теста на постоян. миним. лотах
//============================================================================================
   return(Lot);
   }

Жду советов, хотелось бы сделать рабочий советник.

Rid
3170
Rid 2009.05.07 10:57  

Трудновато вникать в ваш код. Вы его слишком небрежно выставили.

Проще новый написать. Примерно так:

В самом конце кода (вне функции СТАРТ) вставляете две функции.

//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru/                  |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает количество позиций.                                 |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любая позиция)                  |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//+----------------------------------------------------------------------------+
int NumberOfPositions(string sy="", int op=-1, int mn=-1) {
  int i, k=OrdersTotal(), kp=0;

  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) kp++;
          }}}}}
  return(kp);
}
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru/                  |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает суммарный профит открытых позиций в пунктах         |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любая позиция)                  |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//+----------------------------------------------------------------------------+
int GetProfitOpenPosInPoint(string sy="", int op=-1, int mn=-1) {
  double p;
  int    i, k=OrdersTotal(), pr=0;

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if ((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) {
        if (mn<0 || OrderMagicNumber()==mn) {
          p=MarketInfo(OrderSymbol(), MODE_POINT);
          if (p==0) if (StringFind(OrderSymbol(), "JPY")<0) p=0.0001; else p=0.01;
          if (OrderType()==OP_BUY) {
            pr+=(MarketInfo(OrderSymbol(), MODE_BID)-OrderOpenPrice())/p;
          }
          if (OrderType()==OP_SELL) {
            pr+=(OrderOpenPrice()-MarketInfo(OrderSymbol(), MODE_ASK))/p;
          }  } } } }
  return(pr);
}
//ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖ

Далее, я делаю примерно так:

при открытии изначальных позиций присваиваю этим позициям свой магик.

//-------------------------Изначальное открытие позиций ---------------------------------
if ( NumberOfPositions(NULL,OP_BUY, Magic)<1){ //если нет открытых бай позиций
if (здесь - ваши условия входа){ //если условия соответствуют заданным 
//покупаем:
ticket=OrderSend(Symbol(),OP_BUY,Lots(),Ask,3,SL,TP,"покупка",Magic,0,Blue);
if(ticket < 0) { Print("Ошибка открытия ордера BUY #", GetLastError());}
 }}
//------------------------------------------------------------------------------------------ 
if ( NumberOfPositions(NULL,OP_SELL, Magic)<1){ //если нет открытых селл позиций
if (здесь - ваши условия входа){ //если условия соответствуют заданным 
//продаем:
ticket=OrderSend(Symbol(),OP_SELL,Lots(),Bid,3,SL,TP,"продажа",Magic,0,Red);
if(ticket < 0){Print("Ошибка открытия ордера SELL #", GetLastError()); }
  } }
Rid
3170
Rid 2009.05.07 11:07  

Далее открываете дополнительные позиции(например с удвоенным лотом), но - присваивая им другой, - свой магик:

//жжжжж Дополнительные позиции жжжжжжжжж   
if (NumberOfPositions(NULL,OP_BUY, Magic)==1 && NumberOfPositions(NULL,OP_BUY, Magic_2)<1) {
//если есть начальная бай позиция и 
//нет дополнительных бай позиций 
 if (GetProfitOpenPosInPoint(NULL,OP_BUY,Magic)<= LEVEL_1){ //если прибыль 
//начальной позиции превышает заданное значение 
//открываем дополнительную позицию
ticket=OrderSend(Symbol(),OP_BUY,Lots()*2, Ask,50,SL,TP,"доп. покупка",Magic_2,0,Blue);
if(ticket < 0) { Print("Ошибка открытия ордера BUY #", GetLastError()); }
               
   } } 
//-----------------------------------   
if (NumberOfPositions(NULL,OP_SELL, Magic)==1 && NumberOfPositions(NULL,OP_SELL, Magic_2)<1) {
//если есть начальная селл позиция и 
//нет дополнительных селл позиций 
 if (GetProfitOpenPosInPoint(NULL,OP_SELL,Magic)<= LEVEL_1) { //если прибыль 
//начальной позиции превышает заданное значение 
//открываем дополнительную селл позицию
ticket=OrderSend(Symbol(),OP_SELL,Lots()*2,Bid,3,SL,TP,"дополн. селл",Magic_2,0,Red);
if(ticket < 0){Print("Ошибка открытия ордера SELL #", GetLastError()); }
   }}   
//----------------------------------

В глобальных переменных не забудьте добавить:


extern int     Magic   = 7777;
extern int     LEVEL_1 = 25 ;

int ticket;
int  Magic_2;int Magic_3;int Magic_4;int Magic_5;
//-- Подключаемые модули --
#include <stderror.mqh>
#include <stdlib.mqh>

Ну и так далее. С каждыми новыми дополн. позициями вы при открытии задаете свой магик: 

Magic_2=;Magic_3 Magic_4;Magic_5 ... ... ;

А чтобы не задавать несколько магиков во внешних парамерах советника  для наскольких дополн. позиций можно сдедать так:

//-- Подключаемые модули --
#include <stderror.mqh>
#include <stdlib.mqh>



int start()
{

//---------------------------------------------- 
Magic_2=Magic*3;Magic_3=Magic*4; Magic_4=Magic*5;Magic_5=Magic*6;
Ilnaz
448
Ilnaz 2009.05.07 11:31  
rid >>:

Далее открываете дополнительные позиции(например с удвоенным лотом), но - присваивая им другой, - свой магик:


В глобальных переменных не забудьте добавить:




Спасибо,

а откуда брать

//-- Подключаемые модули --
#include <stderror.mqh>
#include <stdlib.mqh>

вот мой код который должен открывать дополнительные лоты:

он через каждые pips(в пунктах) должен открывать новые ордера, но к сожалению не работает.

  if (OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true)
  {
 cenaoppos=OrderOpenPrice();//цена открытия
      
  if (OrderType()==OP_BUY)
 Cena=Ask;//цена 
            if((cenaoppos+pips*Point)<Cena)//если цена открытия +пипс(=)*пунктам меньше цены, то 
              OrderSend(Symbol(),OP_BUY,Lots(),Ask,3,0,0,0,Green);
  }
Rid
3170
Rid 2009.05.07 11:41  
zan >>:

Спасибо,

а откуда брать

вот мой код который должен открывать дополнительные лоты:

он через каждые pips(в пунктах) должен открывать новые ордера, но к сожалению не работает.

Это не надо брать ниоткуда. Библиотеки

//-- Подключаемые модули --
#include <stderror.mqh>
#include <stdlib.mqh>
уже изначально присутствуют в мт4. 

А по вашему коду, - я ничего не могу сказать. Точнее, я уже говорил,  что мне легче было свой написать..

Rid
3170
Rid 2009.05.07 12:02  
zan >>:

Я пытался написать советник с открытием дополнительных лотов по тренду.

Суть заключается вот в чем.

Мы совершаем сделку на покупку/на продажу после сигнала.

После по истечению n-го количество пунктов совершаем еще одну сделку в том же направлений и так совершаем несколько сделок по тренду регулируя максимальное количество лотов.

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


Но есть ошибки в коде. Дополнительные сделки по тренду открываются не по прохождению n-го количества лотов, советник открывает сразу несколько лотов. Пыталься исправить но не получилось, поэтому прошу помочи у всех кто разбирается в mql.  

Жду советов, хотелось бы сделать рабочий советник.

У вас открывается неск. позиций сразу, потому, что вы не задаете условия на вход(напр.):

if ( NumberOfPositions(NULL,OP_BUY, Magic)<1){ //если нет открытых бай позиций

//--------------

См. пример моего кода выше

Ilnaz
448
Ilnaz 2009.05.07 12:20  
rid >>:

Это не надо брать ниоткуда. Библиотеки

//-- Подключаемые модули --
#include <stderror.mqh>
#include <stdlib.mqh>
уже изначально присутствуют в мт4.

А по вашему коду, - я ничего не могу сказать. Точнее, я уже говорил, что мне легче было свой написать..

Спасибо большое, попробуем ваш

Rid
3170
Rid 2009.05.07 12:41  

Там я ошибку сделал небольшую в строках (для бай и для селл) -  ДЛЯ ДОП. ПОЗИЦИЙ :

 if (GetProfitOpenPosInPoint(NULL,OP_BUY,Magic)<= LEVEL_1){ //если прибыль 
//начальной позиции превышает заданное значение 

Нужно знак "<=" исправить на ">=" В  селл и в бай 

Ilnaz
448
Ilnaz 2009.05.11 16:05  
Большое спасибо ridу, у кого еще есть какие-нибудь варианты, может вместе подумаем над этой проблемой
iglob
9
iglob 2014.12.12 04:59  

Чтобы просто доливаться через Shag_trend пунктов, надо вот это в код вставлять:

//--------------------добава по тренду-------------------     
      if(CountTrades() > 0)
    {
    for(int i=OrdersTotal()-1; i>=0; i--)
  {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
      if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && (OrderType() == OP_BUY || OrderType() == OP_SELL))
       if (OrderType() == OP_BUY)
       {
           price = FindLastBuyPrice();
           if(Ask >= price + Shag_trend*Point )
           ticketbuy = OrderSend(Symbol(),OP_BUY,DefaultLot,Ask,slippage*cu,0,0,"", MagicNumber,0,Blue);
       }
  //     order_type = OrdersCount(OP_SELL);
      else  if(OrderType() == OP_SELL)
       {
           price = FindLastSellPrice();
           if(Bid <= price - Shag_trend*Point )
           ticketsell = OrderSend(Symbol(),OP_SELL,DefaultLot,Bid,slippage*cu,0,0,"", MagicNumber,0,Red);
       }
      }                
       }} 

А внизу добавить функции:

//======================================================================================================================
double FindLastBuyPrice()
{
  double oldopenprice;
  int oldticket;
 
  ticket = 0;
  for(int i=OrdersTotal()-1; i>=0; i--)
  {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
      if(OrderSymbol() == Symbol() && (OrderMagicNumber() == MagicNumber ||OrderMagicNumber() ==MagicCheck())&& OrderType() == OP_BUY)
      {
       
        oldticket = OrderTicket();
        if(oldticket > ticket)
        {
           oldopenprice = OrderOpenPrice();
           ticket = oldticket;
        }
      }
    }
  }
  return(oldopenprice);
}
//======================================================================================================================
double FindLastSellPrice()
{
  double oldopenprice;
  int oldticket;
     
  ticket = 0;
  for(int i=OrdersTotal()-1; i>=0; i--)
  {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
      if(OrderSymbol() == Symbol() && (OrderMagicNumber() == MagicNumber ||OrderMagicNumber() ==MagicCheck())&& OrderType() == OP_SELL)
      {
       
        oldticket = OrderTicket();
        if(oldticket > ticket)
        {
           oldopenprice = OrderOpenPrice();
           ticket = oldticket;
        }
      }
    }
  }
  return(oldopenprice);

В глобальных переменных надо добавить (не забыть) MagicNumber, Shag_trend,DefaultLot,slippage,cu (коэффициент знака после запятой - Digits).

У меня работает безупречно!

/
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий