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

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

#1776


я наверно неправильно задал вопрос...по идее в функции CountSell нужно поменять OrdersTotal на OrdersHistoryTotal и MODE_TRADES на MODE_HISTORY...ведь так???

Тут вопрос тонкий. Я бы сделал простой счётчик типа dayCount++;, поставил после открытия ордера, потом в любом месте сброс: если today != iTime(NULL, PERIOD_D1,0) dayCount = 0;
Но если Вы хотите через MODE_HISTORY, то в цикле надо смотреть чтоб OrderOpenTime() > today (как определить сег. дату писал выше). И цикл по закрытым ордерам с конца - обязательно! - до 0. Сделаете наоборот - пожалеете...
#1777



я наверно неправильно задал вопрос...по идее в функции CountSell нужно поменять OrdersTotal на OrdersHistoryTotal и MODE_TRADES на MODE_HISTORY...ведь так???

Тут вопрос тонкий. Я бы сделал простой счётчик типа dayCount++;, поставил после открытия ордера, потом в любом месте сброс: если today != iTime(NULL, PERIOD_D1,0) dayCount = 0;
Но если Вы хотите через MODE_HISTORY, то в цикле надо смотреть чтоб OrderOpenTime() > today (как определить сег. дату писал выше). И цикл по закрытым ордерам с конца - обязательно! - до 0. Сделаете наоборот - пожалеете...

честно говоря вы ввергли меня в ступор :(...но лучше буду задавать глупые вопросы, но получу ответы , чем буду сидеть в неведении...
int CountHistorySell()
{
int daycount = 0;
datetime today = iTime(NULL, PERIOD_D1, 0);
for (int trade = OrdersHistoryTotal() - 1; trade >= 0; trade--)
{
if (OrderSelect(trade, SELECT_BY_POS, MODE_HISTORY))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == OP_SELL)
{
if (OrderOpenTime() > today)
daycount++;
}
}
}
return (daycount);
}

по вашим словам я так понял надо сделать так....только не судите строго...я пока еще полный ноль...
С ув.
#1778

В общем правильно, но Вы пошли по 2 варианту ;)
я бы это исключил: "&& OrderType() == OP_SELL", или Вам по каждой стороне ограничивать нужно?

#1779


В общем правильно, но Вы пошли по 2 варианту ;)
я бы это исключил: "&& OrderType() == OP_SELL", или Вам по каждой стороне ограничивать нужно?

да, мне именно надо по каждой стороне...если Вас не затруднит уважаемый Oll, не могли бы вы написать первый вариант, о чем вы говорили...
С ув.
#1780
kempo Вариант с пересчётом по истории плох тем, что Ваш бот на каждом тике (подозреваю) будет пересчитывать открытые ордера да ещё 2 раза, а если ордеров много? - повиснет. Кстати Вам надо добавить выход из цикла если дата открытия позже:
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == OP_SELL)
{
if (OrderOpenTime() > today)
daycount++;
else break;
}
в общем этот вариант очень грузит терминал (имхо).

Моё первое предложение немного сложнее, но быстрее в разы:
глобальные переменные: buycount = 0, sellcount = 0;
в теле старт:
static datetime new_Day;
if (new_Day {
new_Day =iTime(NULL,PERIOD_D1,0);
buycount = sellcount = 0;
}
далее в блоке принятия решения на открытие (проверка условий) добавляете условие: buycount далее при открытии ордера (там, где стопы ставите) buycount++;

вот и всё. удачи.
#1781

""далее при открытии ордера (там, где стопы ставите) buycount++;"" на счет этой строчки, мы получается пишем buycount++ внизу????


void OpenBuyOrder()
{
mlots = GetLots();

if (AutoSL) sl = CalcSL(OP_BUY);
else sl = ND(Bid - StopLoss*Point);

tp = ND(Ask + TakeProfit*Point);

ticket = OrderSendReliable(Symbol(), OP_BUY, mlots, Ask, Slippage, 0, 0, comment, Magic, 0, Blue);
if(ticket > 0)
{
OrderModifyReliable(OrderTicket(), OrderOpenPrice(), sl, tp, 0);
buycount++;
}

так правильно??

#1782


""далее при открытии ордера (там, где стопы ставите) buycount++;"" на счет этой строчки, мы получается пишем buycount++ внизу????

разницы нет. можно и так.
#1783

Добрый день ув. Oll ... а можно ли в условие на совершении сделки прописать просто
CurrHour = TimeHour(TimeCurrent());
CurrMin = TimeMinute(TimeCurrent());

if (CurrHour >= StartHour && CurrMin >= StartMin && CurrHour а дальше условия сделки...??

Изменено 17 января, 2015 пользователем kempo

#1784
kempo у Вас нормально получается. Так можно и по другому тоже - пробуйте...
#1785

Ув. Oll, возникла проблема, никак не могу ее решить...суть такая...я прописал, чтобы сделки открывались только с 8:00-18:00, при этом покупки должны быть только выше хая 32 свечей (15мин график),начиная с 00:00, продажи -ниже лоу 32 свечей...Но у меня почему-то открываются сделки только в бай, и в 00:00, а должны в 08:00..В чем может быть проблема, кусок кода:

if (new_Day {
new_Day = iTime(NULL,PERIOD_D1,0);
}
BarShift = iBarShift(Symbol(), 0, new_Day); //нахожу номер бара на текущем графике
low = Low[iLowest(Symbol(),0,MODE_LOW, 32, BarShift - 32)]; //ищу лоу в промежутке 10 баров
high = High[iHighest(Symbol(), 0, MODE_HIGH, 32, BarShift - 32)];

CurrHour = TimeHour(TimeCurrent());
CurrMin = TimeMinute(TimeCurrent());

if (CurrHour >= StartHour && CurrMin >= StartMin && CurrHour {
if(CountBuy() == 0 && buycount == 0 && gann > 0 && xo1 > 0 && cci1 > 0 && Ask > high)
{
OpenBuyOrder(); // открываем ордер на покупку
}

// условие на продажу
if(CountSell() == 0 && sellcount == 0 && gann == 0 && xo2 {
OpenSellOrder(); // открываем ордер на покупку
}

Изменено 18 января, 2015 пользователем kempo

#1786
kempo есть несколько вопросов:
- если BarShift это №бара начала дня, то что это: iLowest(Symbol(),0,MODE_LOW, 32, BarShift - 32) ? (не критично)
- если StartMin > 0, например 20, то с нуля до 20 мин каждого часа бот будет отдыхать. (не критично)
- не знаю что такое gann, но gann == 0 для селла - не жестковато? (критично)
- вот это - && CurrMin
Да фильтр по времени надо переделывать... весь. Я в прошлый раз недоглядел.
попробуйте так (если хотите):
MqlDateTime curTime;
TimeCurrent(curTime);
curTime.hour > StartHour ...
#1787

привет
посмотрел видео уроки, начал писать свой советник
обратил внимание, что когда автор создает советник по шаблону у него есть функция Start где и описывается главная логика, у меня при создании советника создает функция OnTick

почитал документация, понял отличие OnTick на каждый тик, Start типа одноразового запуска
а вот вопрос, что такое одноразовый запуск

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

а если Start он один раз проверит и будет ждать следующий H1 или один раз проверил и все на этом, пока не перезапустишь советник?

читал тут http://docs.mql4.com/basis/function/events

#1788

1. я хотел получить самую низшую точку первых 32 свечей дня
2. я и вправду здесь начудил
3. я вызывал значения инди GannHilo через iCustom, получилось так, что gann==0 - это тренд вниз , gann == 1 - тренд бычий
4. получается мне лучше вообще не использовать минуты
5. получается по вашей переделке, мне нужно просто удалить все строки расчета времени и вписать ваши??и еще один вопрос: curTime.hour-эту переменную надо объявлять, или она уже объявлена???(MqlDateTime curTime;)

С ув.

#1789

начну не по-порядку
- MqlDateTime curTime; - это и есть объявление, читай справку.
- чтоб получить мах первых 32 свечей дня надо следить за текущим временем. если BarShift - 32 т.е. надо ограничитель времени выписывать до определения мах/мин
- про ганна понял
- 4. минуты можно использовать, но осторожно и использовать скобки в логике
- 5. нет я привёл отвлечённый пример. Вам надо придумать алгоритм работы со временем.

#1790
GoodPointMas видео писалось на старом билде В новом билде Старт осталась только в скриптах и стала одноразовой, т.е. после отработки Старт скрипт выгружается.
Вообще отличий много почитайте в интернете много инфы.
#1791

Ув. Oll немного трудновато мне далось ваше пояснение...на просторах интернета набрел на чувака с такой же проблемой... по его аналогии поправил свой код, но что-то опять у меня не сходится...

int start()
{
static datetime new_Day;
if (new_Day {
new_Day = iTime(NULL,PERIOD_D1,0);
buycount = sellcount = 0;
}
//---------------------------------------------------------------------------------------------------------
int start = 0;
int StartTime = StartHour * 60 + StartMin;
int StopTime = CloseHour * 60 + CloseMin;
int CurrentMinutesFromDayStart = Hour()*60 + Minute(); // Текущее время в минутах от начала дня
if (CurrentMinutesFromDayStart > StopTime)
{
datetime ts = new_Day + StopTime * 60; // конец временного диапазона в секундах от 01.01.1970
start = iBarShift(Symbol(), 0, ts, false); // смещение бара, которому принадлежит ts
}
int count = 0; // Сколько баров до StartTime
if (CurrentMinutesFromDayStart > StartTime)
{
ts = new_Day + StartTime * 60; // начало временного диапазона в секундах от 01.01.1970
count = iBarShift(Symbol(), 0, ts, false); // смещение бара, которому принадлежит ts
count = count - start; // Сколько баров длится временной интервал
low = Low[iLowest(Symbol(),0,MODE_LOW, count, start)]; //ищу лоу в промежутке баров
high = High[iHighest(Symbol(), 0, MODE_HIGH, count, start)];
}
else
{
high = -1;
low = -1;
}


вывел через Print результаты поиска max/min:

Print("Текущее время в минутах=",CurrentMinutesFromDayStart," Максимум с ",StartTime," минуты по ",StopTime," минуту =",DoubleToStr(high,Digits));

2015.01.19 15:10:04.379 2014.01.31 12:15 ATR-2 GBPUSD,M15: Текущее время в минутах=735 максимум с 0 минуты по 0 минуту =1.66677
2015.01.19 15:10:04.368 2014.01.31 12:00 ATR-2 GBPUSD,M15: Текущее время в минутах=720 максимум с 0 минуты по 0 минуту =1.66677
2015.01.19 15:10:04.356 2014.01.31 11:45 ATR-2 GBPUSD,M15: Текущее время в минутах=705 максимум с 0 минуты по 0 минуту =1.66677
2015.01.19 15:10:04.346 2014.01.31 11:30 ATR-2 GBPUSD,M15: Текущее время в минутах=690 максимум с 0 минуты по 0 минуту =1.66677
2015.01.19 15:10:04.337 2014.01.31 11:15 ATR-2 GBPUSD,M15: Текущее время в минутах=675 максимум с 0 минуты по 0 минуту =1.66677

Получается что бот опять ищет непонятно на каком промежутке времени

#1792
kempo мне вот тоже непонятно... что Вы хотите сделать. Код выше - вымучен - так быть не должно, он должен быть лёгким и красивым...
Напишу для Вас алгоритм, как я понял Вы хотите определить мах/мин последних 8 часов предыдущего дня и после 8-00 сегодня входить на пробой:
static datetime new_Day;
if (new_Day {
new_Day = iTime(NULL,PERIOD_D1,0);
buycount = sellcount = 0;
//Здесь определяем мин/мах однократно
low = Low [iLowest (_Symbol,0, MODE_LOW , 32, 0)]; //ищу лоу в промежутке баров
high = High[iHighest(_Symbol,0, MODE_HIGH, 32, 0)];
}
if (curtime.hour * 60 + curtime.minute > CurrentMinutesFromDayStart &&
curtime.hour * 60 + curtime.minute {
//Здесь условия на вход

}
else
{
//Здесь на выход или чего-там у Вас
}
#1793

if (curtime.hour * 60 + curtime.minute > CurrentMinutesFromDayStart &&
curtime.hour * 60 + curtime.minute
а Вы не перепутали???мне кажется, или Вы сравниваете текущее время с текущим временем?

#1794

Да перепутал... Поставьте нужное ограничение.

#1795

Прошу прощения за назойливость ...но Вы не так меня поняли...я хочу входить в покупки/продажи выше хая/ниже лоу, образованных за первые 8 часов дня, т е. с 00:00 до 08:00

ЗЫ: прогнал в тестере, вообще странные входы получаются, и опять только покупки

Посмотрел в коде, проблема продаж связана с ганном

Изменено 19 января, 2015 пользователем kempo

#1796

...я хочу входить в покупки/продажи выше хая/ниже лоу, образованных за первые 8 часов дня, т е. с 00:00 до 08:00

Тогда Вам не нужен блок "начало дня" всё переместите в блок "рабочее время". только определение мин/мах нужно делать однократно - подумайте, может флаг или по времени...
По поводу только бай - смотрите условие на открытие, проверьте ганна, уменьшите кол-во условий...
#1797

MqlDateTime curTime;
TimeCurrent(curTime);
if (curTime.hour * 60 + curTime.min == StartTime)
{
low = Low [iLowest (Symbol(), 0, MODE_LOW , 32, 0)]; //ищу лоу в промежутке баров
high = High[iHighest(Symbol(), 0, MODE_HIGH, 32, 0)];
}
if (curTime.hour * 60 + curTime.min > StartTime && curTime.hour * 60 + curTime.min {

if(CountBuy() == 0 && buycount == 0 && Ask > high)
{
OpenBuyOrder(); // открываем ордер на покупку
}

// условие на продажу
if(CountSell() == 0 && sellcount == 0 && Bid {
OpenSellOrder(); // открываем ордер на покупку
}
}

получается после Ваших исправлений примерно так...Но он все равно отказывается торговать.... и если убрать условие Ask > high(Bid

Изменено 19 января, 2015 пользователем kempo

#1798
kempo - отдохните, чайку попейте... :d

... только определение мин/мах нужно делать однократно - подумайте, может флаг или по времени...


и с новыми силами продолжайте копать.
У Вас экстремум пересчитывается на каждом тике! и Вы ждёте, чтоб цена за него перепрыгнула?
#1799

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

#1800
kempo меня "доканать" практически невозможно :d Если полистаете эту ветку, то убедитесь.
Я не даю (стараюсь) здесь конкретных решений, потому-что ветка называется "Обучение языку ...". Т.е. я подсказываю или даю направление в котором рыть, но если у Вас не получается, то так и пишите: "Сдаюсь - реши мою задачку!" или "Непонял - объясните подробнее!".
По поводу моего предыдущего поста, если не поняли: Вы на каждом тике рассчитываете новый экстремум и ждёте его пересечения.
Это как в притче про осла (цена) и морковь на удочке (экстремум) - они не пересекутся...

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

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