Jump to content
muvingman

Напишу советник, скрипт, индикатор на MQL бесплатно

Recommended Posts

AntFX

Насчет таблиц все просто:

double Margin_All() 
{ 
[color="Blue"][b]int h=FileOpen(AccountNumber()+".csv", FILE_CSV|FILE_WRITE);[/b][/color]
double Margin=0; 
int i, Total=OrdersTotal();
for(i=0;i<Total;i++) 
{ 
 OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
 if(OrderMagicNumber()==Magic) 
 { 
  double Lots,OneLot;
  if(OrderType()==1||OrderType()==0) 
  { 
   [color="blue"][b]FileWrite(h, OrderTicket(), OrderSymbol(), OrderType(), DoubleToStr(OrderLots(), 2), DoubleToStr(MarketInfo(OrderSymbol(),MODE_MARGINREQUIRED), 2));[/b][/color]
   Lots=OrderLots(); 
   OneLot=MarketInfo(OrderSymbol(),MODE_MARGINREQUIRED); 
   Margin+=OneLot*Lots; 
  }
 }
} 
[color="blue"][b]FileClose(h);[/b][/color]
return(Margin); 
} 

В итоге после вызова функции у тебя будет файл НомерСчета.csv в папке MetaTrader\Experts\Files (если код выполняется прямо на счете, а не в тестере), в котором будет несколько строк - по кол-ву рассчитываемых ордеров вида:

Тикет;Символ;ТипОрдера;Лотность;МаржаЗа1Лот

 

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


1

Share this post


Link to post
Share on other sites
Andy Tacker

%2$s

Насчет таблиц все просто:

double Margin_All() 
{ 
[color="Blue"][b]int h=FileOpen(AccountNumber()+".csv", FILE_CSV|FILE_WRITE);[/b][/color]
double Margin=0; 
int i, Total=OrdersTotal();
for(i=0;i<Total;i++) 
{ 
 OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
 if(OrderMagicNumber()==Magic) 
 { 
  double Lots,OneLot;
  if(OrderType()==1||OrderType()==0) 
  { 
   [color="blue"][b]FileWrite(h, OrderTicket(), OrderSymbol(), OrderType(), DoubleToStr(OrderLots(), 2), DoubleToStr(MarketInfo(OrderSymbol(),MODE_MARGINREQUIRED), 2));[/b][/color]
   Lots=OrderLots(); 
   OneLot=MarketInfo(OrderSymbol(),MODE_MARGINREQUIRED); 
   Margin+=OneLot*Lots; 
  }
 }
} 
[color="blue"][b]FileClose(h);[/b][/color]
return(Margin); 
} 

В итоге после вызова функции у тебя будет файл НомерСчета.csv в папке MetaTrader\Experts\Files (если код выполняется прямо на счете, а не в тестере), в котором будет несколько строк - по кол-ву рассчитываемых ордеров вида:

Тикет;Символ;ТипОрдера;Лотность;МаржаЗа1Лот

 

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

 

Благодарю, Антон! Получается, что на некоторых счетах с одним советником, показывает верно, а на других - нет ...а на других счетах с двумя советниками - правильно. Вот что интересно, и меня, собственно заинтересовало. Сей час я эти строчки вставлю и отпишу.

Edited by AntFX
для читабельности ветки

:crazy:...или держите дольше, или макайте глубже - дно мутное, ни хрена не видно!!!

Share this post


Link to post
Share on other sites
777krot

Помогите написать индикатор.

 

Принцип индикатора считать бары которые пересекли уровень 1,3780-1,3770.

В правой части поместить число подсчитанных баров.

Максимальное время расчета индикатора 1 год.

Максимальная цена расчета индикатора 1500 пунктов

Уровни разделить по цвету в зависимости от числа подсчитанных баров

 

%2$s

post-97943-1404220654,3869_thumb.png
Edited by AntFX
для читабельности ветки

Share this post


Link to post
Share on other sites
Andy Tacker

В...

процессе я нажрался.

 

По наблюдениям получается, что ВордХворекз чё-та мутит, так как только у них вылезают искажения! И это всего-лишь просто демо! Попробую почитать их Регламент...

Таблицу попробовал, но у меня 4... Наверно чего то не хватает...


:crazy:...или держите дольше, или макайте глубже - дно мутное, ни хрена не видно!!!

Share this post


Link to post
Share on other sites
Melko

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

 

for(int z=0; z<=OrdersTotal(); z++)

{

if (OrderSelect(z,SELECT_BY_POS, MODE_TRADES)==true)

Share this post


Link to post
Share on other sites
AntFX
Всех с прошедшими праздниками. Подскажите, как задать параметр при переборе ордеров, чтобы счет шел не по времени открытия ордера, а по ценам . Ну, к примеру, от ордера с наивысшей ценой к наименьшей, или наоборот, это не имеет значения, а не от первого выставленного ордера до последнего. Других параметров кроме BY_POS и BY_TICKET я не знаю.

 

for(int z=0; z

{

if (OrderSelect(z,SELECT_BY_POS, MODE_TRADES)==true)

 

На самом деле, это не самая тривиальная задача. Для того, чтобы её решить, нужно программно осуществлять сортировку ордеров. Вот пример решения этой задачи:

#define ASCENDING    true
#define DESCENDING   false

#define POS_TICKET      0
#define POS_OPENPRICE   1

double orders[][2];

// --------- Заполнение массива ордеров тикетами -----------
void Fill()
{
  ArrayResize(orders, 0);
  for(int i=0; i<OrdersTotal(); i++)
  {
     if(OrderSelect(i, SELECT_BY_POS))
     {
        ArrayResize(orders, i+1);
        orders[i][POS_TICKET]=OrderTicket();
        orders[i][POS_OPENPRICE]=OrderOpenPrice();
     }
  }
}

// --------- Сортировка списка ордеров по возрастанию (true) либо убыванию (false) цены открытия -------------
void Sort(bool ascend=ASCENDING)
{
  double temp;
  bool done=false;
  while(!done)
  {
     done=true;
     for(int i=1; i<ArrayRange(orders, 0); i++)
     {
        if((ascend && orders[i][POS_OPENPRICE]<orders[i-1][POS_OPENPRICE]) || (!ascend && orders[i][POS_OPENPRICE]>orders[i-1][POS_OPENPRICE]))
        {
           temp=orders[i][POS_TICKET];
           orders[i][POS_TICKET]=orders[i-1][POS_TICKET];
           orders[i-1][POS_TICKET]=temp;
           temp=orders[i][POS_OPENPRICE];
           orders[i][POS_OPENPRICE]=orders[i-1][POS_OPENPRICE];
           orders[i-1][POS_OPENPRICE]=temp;
           done=false;
        }
     }
  }
}

// ----------- Выбор ордера с номером pos в списке (от 0), отсортированном по ценам открытия ордеров. Выбирает ордер для работы с ним и возвращает его тикет
// В случае неудачи возвращает -1
int SelectOrder(int pos=0, bool ascend=ASCENDING)
{
  if(pos<0)   return(-1);
  Fill();
  if(pos>=ArrayRange(orders, 0))  return(-1);
  Sort();
  if(OrderSelect(orders[pos][POS_TICKET], SELECT_BY_TICKET))
     return(orders[pos][POS_TICKET]);
  else
     return(-1);
}

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

Edited by AntFX

1

Share this post


Link to post
Share on other sites
kazakov.v
..., нужно программно осуществлять сортировку ордеров...

 

Лучше (на порядок быстрее будет) использовать штатный ArraySort().

Надо только сортируемый параметр положить в нулевой столбец.


Никому верить нельзя.

Мне - можно.

 

Share this post


Link to post
Share on other sites
AntFX
Лучше (на порядок быстрее будет) использовать штатный ArraySort().

Надо только сортируемый параметр положить в нулевой столбец.

 

Наверное, да. Учту на будущее. Надеюсь, ArraySort ВСЕГДА работает без глюков :crazy:

 

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

Edited by AntFX

1

Share this post


Link to post
Share on other sites
Melko

Благодарю. Но' date=' извините за наглость, объясните пожалуйста мне “на пальцах” как работать с этим кодом, как его вставить в какую либо программу и каким образом вызывать ордер из массива? С массивами просто я дружу на очень большом расстоянии. (#define ASCENDING true, #define DESCENDING false, #define POS_TICKET 0, #define POS_OPENPRICE 1</SPAN>) – </SPAN>постоянные ошибки, не могу врубиться. Все что понял – ASCENDING/DESCENDING – возростание/убывание, и то благодаря знанию англ.. Люди добрые помогите чайнику реализовать прогу!!!!!

Share this post


Link to post
Share on other sites
AntFX

Просто вставляете в свой советник, #define лучше вставить в самом начале кода, остальные переменные и функции можно вставить внизу кода, после конца функции start(). Для того, чтобы использовать функцию, пишите

 

for(int z=0; z

if (SelectOrder(z)>0)

{

//...

}


1

Share this post


Link to post
Share on other sites
Melko

А можно ли просто во время перебора ордеров цены всех ордеров записывать в' date=' например линейный массив – у меня ордеров все равно около 10, а потом с помощью ф-ции [/font']ArrayMinimum или ArrayMaximum вызывать минимальное или максимальное значение, соответственно? По-моему это будет гораздо проще. Или нет? Если такой вариант возможен, то как его реализовать? Или может она уже где то есть готовая?

 

Share this post


Link to post
Share on other sites
AntFX
А можно ли просто во время перебора ордеров цены всех ордеров записывать в, например линейный массив – у меня ордеров все равно около 10, а потом с помощью ф-ции ArrayMinimum или ArrayMaximum вызывать минимальное или максимальное значение, соответственно? По-моему это будет гораздо проще. Или нет? Если такой вариант возможен, то как его реализовать? Или может она уже где то есть готовая?

 

 

Очень интересно, сначала Вы подробно расписали способ реализации, потом спрашиваете "как его реализовать" :)

Раз написали, значит знаете, как реализовывать.

 

Проще-то проще, но это позволит лишь получить ордера по одному из концов списка - наибольший и наименьший, а не все по порядку.

Чтобы получить таким образом все по порядку, нужно добавить к этому ещё одно действие, сами догадайтесь какое :roll:

Edited by AntFX

1

Share this post


Link to post
Share on other sites
AntFX

Вот вариант для прохода от ордера с наибольшей ценой до ордера с наименьшей.

 

if(OrdersTotal()>0)
{
double orders[];
ArrayResize(orders, OrdersTotal());
for(int i=0; i<OrdersTotal(); i++)
{
OrderSelect(i, SELECT_BY_POS);
orders[i]=OrderOpenPrice();
}

while(orders[ArrayMaximum(orders)]>0)
{
i=ArrayMaximum(orders);
OrderSelect(i, SELECT_BY_POS);
/*
  работа с ордером...
*/
orders[i]=0; // то самое действие
}
}

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

Edited by AntFX

1

Share this post


Link to post
Share on other sites
Melko

А если мне нужно из пяти выставленных BUYSTOP-ов всего лишь взять один (с самой низшей ценой) и' date=' отталкиваясь от него, выставить еще один. А сколько там еще ордеров и какие они меня не интересует. Грубо говоря, мне нужен один, который находиться ближе всех к [/font']Ask.

Share this post


Link to post
Share on other sites
AntFX
А если мне нужно из пяти выставленных BUYSTOP-ов всего лишь взять один (с самой низшей ценой) и, отталкиваясь от него, выставить еще один. А сколько там еще ордеров и какие они меня не интересует. Грубо говоря, мне нужен один, который находиться ближе всех к Ask.

 

Ну вот я Вам написал в предыдущем сообщении как это делается с порядком от наибольшего к наименьшему. Вы можете заменить пару строк и будет от наименьшего к наибольшему.


1

Share this post


Link to post
Share on other sites
Melko

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

 

Проблема. Ордера будут меняться постоянно. А если использовать. RefreshRates();

Share this post


Link to post
Share on other sites
AntFX
Проблема. Ордера будут меняться постоянно. А если использовать. RefreshRates();

 

Я имею в виду сам цикл обработки ордеров. Если Вам нужен всего 1 ордер за раз - наибольший/наименьший - то нет проблемы.

Edited by AntFX

1

Share this post


Link to post
Share on other sites
Melko
Я имею в виду сам цикл обработки ордеров. Если Вам нужен всего 1 ордер за раз - наименьший - то нет проблемы.
Так и есть. Это хорошо. Буду пытаться. Благодарю!!!!!!

Share this post


Link to post
Share on other sites
AntFX

Тут даже массив не нужен на самом деле. Вы иначе формулировали задачу в самом начале. Если бы сразу сказали, что нужно, то и проблем бы не было.

 

bool GetOrder(bool MaxMin=false)

{

double price=0;

int num=-1;

for(int i=0; i

{

OrderSelect(i, SELECT_BY_POS);

if(price==0 || (price>0 && ((MaxMin && OrderOpenPrice()>price) || (!MaxMin && OrderOpenPrice()

{

num=i;

price=OrderOpenPrice();

}

}

if(num>=0) return(OrderSelect(num, SELECT_BY_POS));

else return(false);

}

Edited by AntFX

1

Share this post


Link to post
Share on other sites
Melko

Что такое bool GetOrder(bool MaxMin=false)

Share this post


Link to post
Share on other sites
AntFX
Что такое bool GetOrder(bool MaxMin=false)

 

Кэп: это тип возращаемого значения, имя функции и список её параметров с указанным значением по умолчанию.

 

Вы тут про линейные массивы рассуждаете, а что такое функция не в курсе? Неправильная последовательность изучения mql4.

Edited by AntFX

1

Share this post


Link to post
Share on other sites
Melko

Я понимаю. Компилятор ее ну ни как не хочет воспринимать.

Share this post


Link to post
Share on other sites
AntFX
Я понимаю. Компилятор ее ну ни как не хочет воспринимать.

 

Только что проверил, кушает без вопросов. Надеюсь, Вы не пытаетесь эту функцию внутрь функции start() засунуть? Функции не вкладываются одна в другую, они следуют друг за другом.

 

А использовать вызов функции GetOrder() внутри функции start() Вам нужно будет вместо ВСЕЙ вот этой конструкции

for(int z=0; z

{

if (OrderSelect(z,SELECT_BY_POS, MODE_TRADES)==true)

 

Например так:

 

if(GetOrder())

{

// действия с ордером с наименьшей ценой

}

 

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

Edited by AntFX

1

Share this post


Link to post
Share on other sites
Melko

Кстати, вы правы, сунул в start().

Спасибо. Буду разбираться.

Share this post


Link to post
Share on other sites
Melko

А может еще посоветуете ф-цию' date=' которая перед установкой отлож. ордера проверяет на наличие ордера с такой же ценой. Чтобы не наставлять ордера с одинаковой ценой.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×