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

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

#5151

ладно ребята... в общем всем спасибо за помощь. но пока отложу эту тему. как то овчинка выделки не стоит. скажу только что пока остановился на прилагаемом внизу индюке в него вписал условие, заменив строку:
if(Open>Close) s++; на if(Close и соответственно на с b++ .
и он показывает верно. надо будет только подумать как из него код в сову перекинуть или создать соответствующие буфера в индюке для его вызова.

Candles.mq41 скач.

Изменено 5 июня, 2018 пользователем Ar4i

#5152

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

Зря Вы так думаете, в этом деле любую овчинку нужно выделывать.
#5153

Зря Вы так думаете, в этом деле любую овчинку нужно выделывать.


ну хорошо. тогда подскажите ;) как из предложенной записи:

if ( Close[1] > Open[1] ) { countB++; countS = 0; }
else { countS++; countB = 0; }
if ( countS == barCount )... // barCount количество баров

вытащить следующие, а именно так что бы условие if ( countS == barCount ) могло иметь смысл выражения if ( countS == barCount && countB == barCount ) // так не раб. (а куда всунуть обнуление тогда я не пойму)
то есть что бы последующие условия, задавались не только по последнему количеству бычьих или медвежих свечей. а по условию последней серии бычьей и медвежий . в смысле не сложения их, а например 2 бара вниз и три вверх тогда...
мне кажется это могло бы быть интересным.

Изменено 5 июня, 2018 пользователем Ar4i

#5154

if ( countS == barCount && countB == barCount )


У Вас если barCount!=0, то условие никогда не будет соблюдаться, т.к. на каждой проверке предыдущего if будет обнуляться одна из переменных count.
Обнулять эти переменные нужно в нескольких ситуациях(если вообще понял суть задачи):
1. при достижении условия countS == barCount && countB == barCount;
2. если свеча Бычья и countS 3. если свеча Медвежья с countB В итоге мы ловим непрерывную серию бычьих и непрерывную серию медвежьих свеч.
п.с. возможно по условиям задачи придется сбрасывать счетчики, если серия подряд идущих свеч превысит barCount
#5155

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

Это называется свечной паттерн. Их существует великое множество. Японцы их искали и торговали около 100 лет назад уже.
Кроме направления свечей иногда задают и их размер - некоторые паттерны не работают на мелких свечах.
Для описания в программе создают массив направлений:
int patt1[] = {1,1,0,0,0}; // 1 - медвежья, 0 - бычья
ну и ищут соответствия на графике, интересно? можно продолжить. Но мы не закончили с предыдущей темой...
#5156

Всем привет! Хотел узнать как добавить функцию просадки drowdown в процентах и вывести на график эту функцию

#5157

В советник добавить?
Есть функции AccountBalance() и AccountEquity() - почитайте, можно подготовить текст:
string text = StringConcatenate( "Просадка = ", DoubleToStr( AccountEquity() / AccountBalance() * 100, 1 ) ," %" );
Самый простой вывод на экран:
Comment(text);
Эти 2 строчки поместить в функцию OnTick().

#5158

интересно? можно продолжить. Но мы не закончили с предыдущей темой...



можно и продолжить. предыдущая это наверное - мысль об отсчета свечей направлением от уровня или лини . да ее тоже хочется зацепить, ну я нашел пока промежуточное решение, упоминал о нем в посте #5129 на стр 342. в общем пока надеюсь все таки ее сам вытащить а потом рассказать.

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

int patt1[] = {1,1,0,0,0}; // 1 - медвежья, 0 - бычья



объявляем наверное в самом вверху.
как в таком случае инициализировать элемент массива Close[1] > Open[1] ? документация говорит так:

patt1[0] = Close[1] > Open[1];
patt1[1] = Close[2] > Open[2];
patt1[2] = Close[1] patt1[3] = Close[2] patt1[4] = Close[3]
и так это у нас комбинация выходит-патерн: "если" 2 медвежьих и 3 бычьи то...
if ( patt1[0]==1 && patt1[1]==1 && patt1[2]==0 && patt1[3]==0 && patt1[4]==0 )
... условие дальше.
не пойму вышло или нет. надо думаю все ровно считать бары для передачи потом их нужного кол-ва в элементы массива.
и я снова тогда упираюсь в вопрос его организации (счетчика). а именно наверное в то, как быть с обнулением? или я все правильно сделал :-/

Изменено 5 июня, 2018 пользователем Ar4i

#5159

не пойму вышло или нет.

Нет, не вышло.
Там немного сложнее, алгоритм такой:
1. У нас есть: массив направлений свечей паттерна (ключ) patt[] (заполняют массив в Ините именно так - int patt[] = {1,1,0,0,0}; )
переменная размера int size = 5; счётчик свечей совпадающих с ключом паттерна int cntP = 0;
2. Теперь ждём закрытия свечи
3. Сравниваем направление закрытой свечи с ключом:
int barD = Close[1] > Open[1] ? OP_BUY : OP_SELL ; // направление закрытой свечи - OP_BUY = 0, OP_SELL = 1
if ( patt[cntP] == barD ) cntP++; // свеча совпала со следующей позицией ключа
else cntP = 0; // свеча не совпала - обнуляем счётчик
4. Сравниваем счётчик с размером паттерна:
if ( cntP == size-1 ) { ... пишем код ... ; cntP = 0; } // паттерн найден !!!
#5160
0ll общий смысл логики алгоритма вроде бы понятен.
int size = 5; int cntP= 0; записал так, и в шапке.
а вот дальше не очень ясно что унас в OnInit(), а что в OnTick().
перебрав все варианты я не получил удовлетворительный результат.
проверял так:

if ( cntP == size-1 )
{Comment("патерн"); cntP = 0;}


???

Изменено 7 июня, 2018 пользователем Ar4i

#5161

???

Вставляйте в пост обсуждаемый код, ибо если не работает, значит не все варианты пробовали ;) , и быстрее будет.
#5162
0ll:
Спойлер

1.в шапке:
int size = 5;
int cntP= 0; //или int cntP;

2. в OnInit():
int patt[] = {1,1,0,0,0};

int barD = Close[1] > Open[1] ? OP_BUY : OP_SELL ;
if ( patt[cntP] == barD ) cntP++;
else cntP = 0;
// если этот блок из трех строк ставить в OnTick() компилятор выдает:'patt' - не объявленный идентификатор.

3. ну и эту часть я вижу в OnTick() :
if ( cntP == size-1 )
{ Comment("патерн" ); cntP = 0;}
//хотя в OnInit() тоже пробовал.



ps: хотя и такие динамические вычисления как счетчик в OnInit() тоже наверное неуместны. остается упоминания в справке о использование массива в функциt с помощью передаче переменных по ссылке &. но я не очень понял примеры в справке.

Изменено 8 июня, 2018 пользователем 0ll

#5163

ps: хотя и такие динамические вычисления как счетчик в OnInit() тоже наверное неуместны.

Вот здесь Вы правы! Пробуйте так:
Спойлер

1.в шапке:
int patt[] = {1,1,0,0,0};
int size = ArraySize(patt); // Попробуйте так
int cntP= 0;

3. OnTick() :
// здесь обязательно нужен код определения нового бара! - Напишите самостоятельно.
if ( newBar() )
{
int barD = Close[1] > Open[1] ? OP_BUY : OP_SELL ;
if ( patt[cntP] == barD ) cntP++;
else cntP = 0;
if ( cntP == size-1 ) { Comment("патерн" ); cntP = 0;}
}

#5164

нет(
работает не корректно, пропускает сигнал и не всегда держит заданный патерн.

код определения нового бара такой :
bool isNewBar()
{
static datetime new_Bar;
if (new_Bar == Time[0]) return(false);
new_Bar = Time[0]; return(true);
} // и работает корректно

oll получилась по аналоги из урока- Исследуем закономерности патернов Price Action:


double bull1 = Close[1];
double bull2 = Close[2];
double bear3 = Close[3];
double bear4 = Close[4];
double bear5 = Close[5];

if( bear5 > bear4 && bear4 > bear3 && bull2 > bear3 && bull1 > bull2 )

хотя твой вариант конечно по интересней выглядел. но что то не срослось.

и еще вопрос по Close[0]. что такое Open[0] понятно, а вот Close[0]? вар 1) это у нас пока неизвестное текущей еще незакрытой свечи то есть будущие? или это:
вар 2) последние известное. то есть та у которой Open[1]? может в этих не стыковках и кроиться трудность...


Изменено 11 июня, 2018 пользователем Ar4i

#5165

вар 2) последние известное.

Close[0] это последний Бид от брокера.
#5166

Здравствуйте подскажите как найти цену открытия первого ордера,например открыто 5 ордеров, а советник должен найти цену именно первого ордера и орентироваться на эту цену.

#5167


Здравствуйте подскажите как найти цену открытия первого ордера,например открыто 5 ордеров, а советник должен найти цену именно первого ордера и орентироваться на эту цену.

в цикле перебираете открытые ордера. Смотрите время открытия ордера, запоминается его в переменную. На следующем ордера его время сравниваете с сохраненным в переменной. Если новое значение меньше, переписываете значение в переменной.
Можно так же сравнивать тикет- Чем старше ордер, тем меньше тикет. Но это не знаю- точно ли на 100%
#5168

Подскажите если искать цену первого ордера по номеру тикета код будет таким ?

double Find_1_Price(int otype)
{
int oneticket;
double oneopenprice = 0;
ticket = 0;
for(int cnt = OrdersTotal() -1; cnt >= 0; cnt--)
{
if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == otype)
{
oneticket = OrderTicket();
if( ticket {
ticket = oneticket;
oneopenprice = OrderOpenPrice();
}
}
}
}
return(oneopenprice);
}

#5169

Почти. Надо добавить проверку
if( ticket Иначе на первом проходе условие не будет соблюдаться

#5170

if( ticket Иначе на первом проходе условие не будет соблюдаться

Или перед циклом определить ticket = -1; ))
#5171

А разве Ордер Тикет может равняться нулю?

#5172


А разве Ордер Тикет может равняться нулю?

в том то и дело- Нет. Если не сделать проверку, а лучше как Oll предложил, то в ticket всегда будет 0.
#5173

Извините а не могли бы вы показать как будет выглядеть код если использовать время открытия ордера

#5174

Ровно так же, только вместо ticket проверяйте OrderOpenTime()

#5175

Скажите а вот такая конструкция с нахождением первого ордера будет работать ?
И еще, мы расчитали переменную LimitOpenPriceBuy а затем записали значение этой перем. в перем. onepriceBuy
будет ли это значение оставаться постоянно что бы использовать его в дальнейшем при закрытии.

Спойлер


{
LimitOpenPriceBuy = NormalizeDouble(hi1 + PriceFilter * Point,Digits);

onepriceBuy = LimitOpenPriceBuy ;

datetime vioo = TimeCurrent() + NumberCandl * 5 * 60;


tp = NormalizeDouble( LimitOpenPriceBuy + TakeProfit * Point,Digits);


ticket = OrderSend(Symbol(),OP_BUYSTOP,Lots,LimitOpenPriceBuy,Sleepage,0,tp,"_",Magic,vioo,Green);


if(ticket Print ( " Не удалось открыть отложенный ордер на продажу" );



//-------------------------------------------------------------------------------------------
}
//------------------------------------------------------------------------------------------






//

//

//

//


//-------------------------------------+
// Проверяем на закрытие
//-------------------------------------+
// Закрытие продаж
//-------------------------------------+


if (CountSell() > 0 )

{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderMagicNumber() == Magic && OrderType() == OP_SELL && OrderSymbol() == Symbol() )
{


if ( Bid
Bid >= hi1 )





{
if(!OrderClose(OrderTicket(),OrderLots(),Ask,Sleepage,Black))
Print("Ошибка закрытия ордера на продажу");
}
}
}
}
}




//------------------------+
// Закрытие покупок
//------------------------+



if(CountBuy() > 0 )

{
for( int i = OrdersTotal()-1; i >= 0; i-- )
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderMagicNumber() == Magic && OrderType() == OP_BUY && OrderSymbol() == Symbol() )

{


if ( Bid >= NormalizeDouble ( onepriceBuy + ( CloseDelta * Point),5) &&
Bid



{
if(!OrderClose(OrderTicket(),OrderLots(),Bid,Sleepage,Black))
Print("Ошибка закрытия ордера на покупку");
}
}
}
}
}

Изменено 13 июня, 2018 пользователем 0ll

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

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