Обучение языку MQL4 под MetaTrader 4📌

От xbms, 13 апреля, 2013 в Уголок Программиста

#4376

Добрый день, начал обучение Mql4, прошел уроки и дом. зд., начал писать советник на индикаторе Slope Direction Line!Идея в том, чтобы сова открывала ордер на 2й свече после перекрашивания индикатора. С моими знаниями написал это (во вложение), объясните пожалуйста в чем ошибка?



Добрый день! В этих нулях:

uptr = iCustom(NULL, 0, "Slope Direction Line", period, method, price, 0, 0);
dntr = iCustom(NULL, 0, "Slope Direction Line", period, method, price, 1, 0);

Когда у iCustom(); последний парметр shift задан 0, то данные берутся с самой последней свечи, которая является текущей формирующейся. Если поставить 1, то данные будут браться с последней закрытой. Если 2, то с предпоследней закрытой и т.д.
#4377

Кстати, вопрос: в уроках ведущий то использует скобки в операторе if, то не использует. Так и не могу определиться: нужны они или нет?


Вы имеете в виду фигурные скобки? { }
Тут все просто: если после оператора if выполняется одно действие,то скобки не нужны. А если несколько,то тогда эти действия заключаются в фигурные скобки.
Пример:
if(...) return; то же, что и if(...)
{
return;
}
но первый вариант проще и красивее.

if(...)
{
a=3;
b=5;
c=7;
}

Изменено 26 апреля, 2017 пользователем Sergey Forex

#4378


Когда у iCustom(); последний парметр shift задан 0, то данные берутся с самой последней свечи, которая является текущей формирующейся. Если поставить 1, то данные будут браться с последней закрытой. Если 2, то с предпоследней закрытой и т.д.

Спасибо за ответ! И еще а эти команды Open[2] Close[2] разве тоже самое не реализуют?



Добавлено: 26-04-2017 08:25:56

И все же главной проблемой осталось, как реализовать программно, вход по изменению цвета индикатора, а не по достижению цены нужного уровня уровня?Объясните пожалуйста или намекните ходя б где почитать ?

Изменено 26 апреля, 2017 пользователем d1w4m3

#4379

Спасибо за ответ! И еще а эти команды Open[2] Close[2] разве тоже самое не реализуют?



Это не команды. Это обращение к массивам-таймсериям, которые хранят в себе цены бара: открытие, закрытие, хай, лоу. Например, обратившись к Open[2], получите цену открытия бара 2.
#4380

Всем доброго времени суток) У меня возникла трудность, не могу понять как уговорить советник видеть трендовую линию. Справку читал, ее же курил, но видимо мой уровень интеллекта чуть ниже, чем тот для кого он писался. Я даже не понимаю с какой стороны к этому подойти. С горизонтальной линией разобрался кое как #:-s Можно какой нибудь простой код? Где выше линии покупаем, ниже продаем и было бы здорово с коротенькими пояснениями. Вот где то так :-/

#4381


Добрый день, коллега!
Если у каждой валютной пары aa и bb разные, то так:

string symbols[] = {"AUDCAD","AUDCHF","AUDJPY"};
int aa[] = {3, 5, 6};
int bb[] = {4, 9, 8};

и далее сама функция:
int blabla(int i)  // где, i - индекс валютной пары в массиве
{
if (aa > bb && Symbols() == symbols)
return(1);
else
return(4);
return(0);
}


Все, пасиб, разобрался)
#4382

Добрый день, и все же главной проблемой осталось, как реализовать программно, вход по изменению цвета индикатора, а не по достижению цены нужного уровня?Объясните пожалуйста или намекните ходя б где почитать ?

#4383

Добрый день, и все же главной проблемой осталось, как реализовать программно, вход по изменению цвета индикатора, а не по достижению цены нужного уровня?Объясните пожалуйста или намекните ходя б где почитать ?


Посмотрите в индикаторе буферы, которые отвечают за цвет. К ним и привязывайтесь.
#4384


Добрый день, и все же главной проблемой осталось, как реализовать программно, вход по изменению цвета индикатора, а не по достижению цены нужного уровня?Объясните пожалуйста или намекните ходя б где почитать ?


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

Посмотрел, привязался, сдвиг поставил, чтоб на 3й открывал, но не пойму в чем проблема или условие задаю не верно?

slope2.mq43 скач.

Изменено 28 апреля, 2017 пользователем d1w4m3

#4385

Скиньте тогда и сам Slope Direction Line, чтобы глянуть.

#4386

Спасибо за помощь!

Slope_Direction_Line.mq42 скач.

#4387
d1w4m3, Если вывести в комментарии значения uptr и dntr, то получим такие значения:
Если тренд восходящий, то uptr покажет цену, например 1,2918.
При этом dntr будет выдавать 2147483647 (EMPTY_VALUE Пустое значение в индикаторном буфере).
И наоборот при нисходящем тренде.

Как вариант можно написать функции UP_Trend() и DN_Trend() и входить на основании их.
P.S. Когда вы модифицируете открытый ордер, то СЛ и ТП лучше считать не от бида, а от цены открытия ордера, потому что бид может далеко убежать за это время.

Во вложении.

slope2========.mq41 скач.

Изменено 28 апреля, 2017 пользователем Sergey Forex

#4388

Привет всем. подскажите пожалуйста как в индюке исправить уровень стоп аута. в индюке показывает его как 50% просадка по балансу. а должен указывать как % от залога. т.е.
У вас на депозите 5000$.
Вы открыли сделку по USD/JPY объемом 100000 долларов при кредитном плече 1:200.
Соответственно, залог под открытую позицию будет составлять 500$.
Если больше никаких сделок не было совершено, то сделка по USD/JPY будет закрыта по стоп-ауту при достижении убытка в размере 4900$.
Уровень стоп аута составляет 20% от суммы залога, то есть, когда размер ваших свободных средств достигнет 100$(=5000$-4900$), сделка будет закрыта.

Drawdown.mq41 скач.
Drawdown.ex40 скач.

#4389

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

Спойлер

//±——————————————————————+
//| TrendLine.mq4 |
//| Copyright c 2010. |
//| http://mql4you.ru |
//±——————————————————————+
#property copyright «Copyright c 2010.»
#property link «http://mql4you.ru»
#include
extern int MaxRisk=2;
extern int TakeProfit=600;
extern int StopLoss=30;
extern int Delta=5;
//±——————————————————————+
int init() {return(0);}
//±——————————————————————+
int deinit() {Comment(««);return(0);}
//±——————————————————————+
int start()
{
return(0);}
//±——————————————————————+

Проверим что есть трендовая линия и она в единственном экземпляре:
if(ObjectsTotal(OBJ_TREND)!=1)
{Comment(»Нарисуйте 1 трендовую линию!»);
return(0);}

Получим ИМЯ трендовой линии:
for(int i=0;i{string name=ObjectName(i);
if(ObjectType(name)==OBJ_TREND) break;}

Проверим что трендовая линия нарисована правильно (по движению цены):
datetime t1=ObjectGet(name,OBJPROP_TIME1);
datetime t2=ObjectGet(name,OBJPROP_TIME2);
if(t1>t2)
{Comment(«Неправильно нарисована трендовая линия!»);
return(0);}

Продолжим линию (свойство луч):
ObjectSet(name,OBJPROP_RAY,true);

Определим тренд (вверх или вниз):
bool trend=false;
double p1=ObjectGet(name,OBJPROP_PRICE1);
double p2=ObjectGet(name,OBJPROP_PRICE2);
if(p1
Определим текущее значение трендовой линии и сообщим ее параметры:
double pr=ObjectGetValueByShift(name,0);
Comment(«Name=»,name,» Trend=»,trend,» Value=»,pr);

Осталось подсчитать количество открытых ордеров и если их нет и цена подошла к трендовой линии открыть ордер.
Подсчитаем кол-во ордеров:
int oBuy=0,oSell=0;
for(i=OrdersTotal() ?1;i>=0;i—)
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol())
{if(OrderType()==OP_BUY) oBuy++;
if(OrderType()==OP_SELL) oSell++;}

Если нет ордеров и цена подошла к трендовой линии — откроем ордер:
double tp=0,sl=0;
double Lot=GetLot(MaxRisk);
if(Lot==0.0) {Alert(«Недостаточно средств!»);return(0);}
if(oBuy+oSell==0 && trend && Bid>=pr && Bid{if(TakeProfit>0) tp=Ask+TakeProfit*Point;
if(StopLoss>0) sl=Ask-StopLoss*Point;
NewOrder(OP_BUY,Lot,Ask,tp,sl);}
if(oBuy+oSell==0 && !trend && Ask=pr-Delta*Point)
{if(TakeProfit>0) tp=Bid-TakeProfit*Point;
if(StopLoss>0) sl=Bid+StopLoss*Point;
NewOrder(OP_SELL,Lot,Bid,tp,sl);}


Кто нибудь выручите!
#4390

Пожалуйста помогите! Не могу понять как работать с трендовой линией, что бы советник ее увидел. Нашел простенький код, тоже не смог разобраться. Вроде как там есть подключаемая внешняя библиотека...
(click to show/hide)
Кто нибудь выручите!



А что именно Вам не понятно?
Причесал немного приведенный Вами код. Библиотека в нем нужна лишь для подсчета размера лота и отправки ордера и никак не связана с работой с трендовой линией. Я эти места немного изменил. Все должно работать. Вот этот код в виде скрипта:

//+------------------------------------------------------------------+
//| TrendLine.mq4 |
//+------------------------------------------------------------------+
#property version "1.00"
#property strict
#property show_inputs

extern double Lot=0.01;
extern int TakeProfit=600;
extern int StopLoss=30;
extern int Delta=50;//Отступ в пунтках от линии

//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//Получим ИМЯ трендовой линии:
string name;
for(int i=0;i {
name=ObjectName(i);
if(ObjectType(name)==OBJ_TREND) break;
}
//Проверим что трендовая линия нарисована правильно (по движению цены):
datetime t1=(datetime)ObjectGet(name,OBJPROP_TIME1);
datetime t2=(datetime)ObjectGet(name,OBJPROP_TIME2);
if(t1>t2)
{
Comment("Неправильно нарисована трендовая линия!");
return;
}
//Продолжим линию (свойство луч):
ObjectSet(name,OBJPROP_RAY,true);

//Определим тренд (вверх или вниз):
//false - тренд вниз;
//true - тренд вверх;
bool trend=false;
double p1=ObjectGet(name,OBJPROP_PRICE1);
double p2=ObjectGet(name,OBJPROP_PRICE2);
if(p1
//Определим текущее значение трендовой линии и сообщим ее параметры:
double pr=ObjectGetValueByShift(name,0);
Comment("Name=" ,name," Trend= ",trend," Value= ",pr);

//Осталось подсчитать количество открытых ордеров и если их нет и цена подошла к трендовой линии открыть ордер.
//Подсчитаем кол-во ордеров:
int oBuy=0,oSell=0;
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol())
{
if(OrderType()==OP_BUY) oBuy++;
if(OrderType()==OP_SELL) oSell++;
}
}
}
//Если нет ордеров и цена подошла к трендовой линии — откроем ордер:
double tp=0,sl=0;

if(Lot==0.0)
{
Alert("Недостаточно средств!");
return;
}
//если тренд вверх
if(oBuy+oSell==0 && trend && Bid>=pr && Bid {
if(TakeProfit>0) tp=Ask+TakeProfit*Point;
if(StopLoss>0) sl=Ask-StopLoss*Point;
int ticket=OrderSend(Symbol(),OP_BUY,Lot,Ask,50,sl,tp,NULL,0,0,clrNONE);
}

//если тренд вниз
if(oBuy+oSell==0 && !trend && Ask=pr-Delta*Point)
{
if(TakeProfit>0) tp=Bid-TakeProfit*Point;
if(StopLoss>0) sl=Bid+StopLoss*Point;
int ticket=OrderSend(Symbol(),OP_SELL,Lot,Bid,50,sl,tp,NULL,0,0,clrNONE);
}
}


Можете нарисовать линию на графике так, чтобы она проходила вблизи от последнего значения цены (не дальше расстояния Delta). Если все в порядке, то скрипт откроет ордер в зависимости от наклона линии.
#4391

Спасибо! Да сейчас он ее видит. Но видит он ее всего раз, открыл бай и после закрытия по условию он ее теряет. Почему не видит постоянно?

Спойлер

//+------------------------------------------------------------------+
//| ProbaTrend.mq4 |
//| бла бла бла |
//| master1.man@inbox.ru |
//+------------------------------------------------------------------+
#property copyright "бла бла бла"
#property link "master1.man@inbox.ru"
#property version "1.00"
#property strict

extern double Lots = 0.2;
extern int TP = 20;
extern int MagicB = 1;
extern int MagicS = 2;

int ticket;
double price, Sl, TP2, lastlot;
string name;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---

//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---

}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{

//Получим ИМЯ трендовой линии:
string name;
for(int i=0;i {
name=ObjectName(i);
if(ObjectType(name)==OBJ_TREND) break;
}

//Определим текущее значение трендовой линии и сообщим ее параметры:
double pr=ObjectGetValueByShift(name,0);
Comment("Name=" ,name," Trend= "," Value= ",pr);

if (Bid > pr && CountBuy() == 0)
{
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 0, 0, 0, "", MagicB, 0, Blue);
if(OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES));
}

if (Ask {
ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, 0, 0, 0, "", MagicS, 0, Red);
if(OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES));
}

if (Bid 0)
{
int count = 0;

for (int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicB)
{
OrderClose(OrderTicket(), OrderLots(), Bid, 0);
}
}
}
}

if (Ask > pr && CountSell() > 0)
{
int count = 0;

for (int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicS)
{
OrderClose(OrderTicket(), OrderLots(), Bid, 0);
}
}
}
}

}
//+------------------------------------------------------------------+
int CountBuy()
{
int count = 0;
for (int trade = OrdersTotal() - 1; trade >= 0; trade--)
{
if (OrderSelect(trade, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicB && OrderType() == OP_BUY)
count++;
}
}
return (count);
}
//+------------------------------------------------------------------+
int CountSell()
{
int count = 0;
for (int trade = OrdersTotal() - 1; trade >= 0; trade--)
{
if (OrderSelect(trade, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicS && OrderType() == OP_SELL)
count++;
}
}
return (count);
}
//+------------------------------------------------------------------+

#4392

Спасибо! Да сейчас он ее видит. Но видит он ее всего раз, открыл бай и после закрытия по условию он ее теряет. Почему не видит постоянно?


Мммм.... не понимаю вопрос Ваш. Что значит "не видит"? Вот в эту переменную сохраняется значение трендовой линии на нулевом баре:

double pr=ObjectGetValueByShift(name,0);

А точнее сказать, каждый раз, когда Вы вызываете функцию ObjectGetValueByShift(name,0), где переменная name содержит имя нужной трендовой линии, то при условии, что у Вас на графике одна трендовая линия и имя ее = name, не может советник ее "не видеть".
Уточните вопрос все-таки.

#4393

Нашел причину, но легче от этого не стало(... В тестере когда ордер закрывается от момента покупки до закрытия рисуется трендовая линия и советник переключается на нее. А так как линия не луч а отрезок, то на следующем баре для нее уже double pr = 0. У меня проблема с трендовой линией. Не могу понять, как выбрать. Например, на графике две трендовых линии которым я присвоил имена. Так вот как перебрать все объекты, найти их по именам, узнать их цену по 0 бару и работать с ними согласно написаных условий. Перебрать ордера и выбрать любой нужный это без проблем, да и с индикаторами тоже сложностей нет, уважаемый xbms все на пальцах объяснил. А вот с графическими объектами просто беда у меня... Может кто объяснит? А то я деревянный, до меня туго доходит)

#4394

При этом dntr будет выдавать 2147483647 (EMPTY_VALUE Пустое значение в индикаторном буфере).
И наоборот при нисходящем тренде.


Сергей, а если значения постоянно 2147483647 (EMPTY_VALUE Пустое значение в индикаторном буфере) для обоих буферов? Просто попробовал написать бота для другого индикатора (не из урока) - в Комментах постоянно такое значение для обоих буферов.
#4395

Нашел причину, но легче от этого не стало(... В тестере когда ордер закрывается от момента покупки до закрытия рисуется трендовая линия и советник переключается на нее. А так как линия не луч а отрезок, то на следующем баре для нее уже double pr = 0. У меня проблема с трендовой линией. Не могу понять, как выбрать. Например, на графике две трендовых линии которым я присвоил имена. Так вот как перебрать все объекты, найти их по именам, узнать их цену по 0 бару и работать с ними согласно написаных условий. Перебрать ордера и выбрать любой нужный это без проблем, да и с индикаторами тоже сложностей нет, уважаемый xbms все на пальцах объяснил. А вот с графическими объектами просто беда у меня... Может кто объяснит? А то я деревянный, до меня туго доходит)



master.man, в Вашем же коде прописан цикл for, где перебираются все имеющиеся объекты на графике:


for(int i=0;i {
name=ObjectName(i);
if(ObjectType(name)==OBJ_TREND) break;
}

Только этот цикл прерывается оператором break сразу же после обнаружения первого попавшегося объекта, который является трендовой линией:

if(ObjectType(name)==OBJ_TREND) break;

Если перевести эту строчку на человеческий язык, то получим следующее:
если текущий объект с именем name является трендовой линией, то прервать выполнение цикла for и идти дальше по ходу кода.

Соответственно, чтобы мы могли работать со всеми интересующими нас трендовыми линиями, то цикл прерывать не надо. А пишем примерно следующее:


//перебираем все графические объекты
for(int i=0;i {
//если объект является трендовой линией
string name=ObjectName(i);
if(ObjectType(name)==OBJ_TREND)
{
//здесь уже можем прописывать и прописывать
//различные признаки, которые будут характерны именно
//для интересующего нас объекта.

//напрмер, если мы знаем заранее какое д.б. имя у объекта
if(ObjectName(i)=="OurTrebdLine")
{
//здесь уже пишем что получаем от этой линии
//и как это обрабатываем
}
}
}



#4396


При этом dntr будет выдавать 2147483647 (EMPTY_VALUE Пустое значение в индикаторном буфере).
И наоборот при нисходящем тренде.


Сергей, а если значения постоянно 2147483647 (EMPTY_VALUE Пустое значение в индикаторном буфере) для обоих буферов? Просто попробовал написать бота для другого индикатора (не из урока) - в Комментах постоянно такое значение для обоих буферов.

Вообще-то такого быть не должно. Одно значение должно быть заполнено. Киньте код, можно в личку.
#4397

Вообще-то такого быть не должно. Одно значение должно быть заполнено. Киньте код, можно в личку.


Сергей, высылаю здесь, так как через личку программы не прицепить.
Высылаю индикатор и бота, которого начал писать. Сначала написал по открытому коду индикатора со всеми переменными - не работал. Решил посмотреть урок про iCustom и написал по буферам. И во время проверки обнаружил, что значения одинаковые и пустые, хотя индикатор сигналит.

Binary_Indicator.ex40 скач.
Binary_Indicator.mq42 скач.
UPDOWN.mq42 скач.

#4398

Кто может обьяснить:


#property indicator_chart_window
#property indicator_buffers 2
double signalup[];
double signaldn[];

int OnInit()
{

SetIndexBuffer(0,signalup);
//SetIndexStyle (0,DRAW_NONE);
SetIndexBuffer(1,signaldn);
//SetIndexStyle (1,DRAW_NONE);

return(0);
}

int start()
{ int i;
double up = ((Open-Close)/Point)/10;
double dn = ((Open-Close)/Point)/10;
if (up>0) signalup=up;
if (dn=MathAbs(dn);

return(0);
}



индикатор вродь как должен возвращать значение тела свечи, но когда обращаюсь к буферам из совы по iCustom оказывается что они пустые(т.е 2147483647). В чем может быть проблема??

-----------------------------------------------------
ВСЕ РАЗОБРАЛСЯ, СПАСИБО, удалите если не нужно это сообщение

Изменено 30 апреля, 2017 пользователем sniv

#4399
sniv Вы объявили переменную i, и даже её используете, а какое значение в ней? Это-ж номер бара и надо с ним работать...
#4400

Да, я уже допер) впихнул конструкцию в for и нормализовал значения open close, вот тогда все и заработало).
Но все равно спасибо.

Для публикации сообщений создайте учётную запись или авторизуйтесь

Перейти к списку тем
Форум · 2.0.20260627.0025