А что непонятно? За время работы функции Start пришло несколько тиков -- все поломалось. Тема уже избита.
Насчет Ваших проблем:
datetime LastTime; bool IsFirstRun; int init() { LastTime = 0; IsFirstRun = true; } int start() { if(Time[0] == LastTime) { return(0); } LastTime = Time[0]; if(IsFirstRun) { IsFirstRun = false; return(0); } Print(TimeHour(TimeCurrent()); // нужная обработка }
Мой бай -- что-то непонятно?
void OpenBuy(int MN, int Target, int Loss, double Lot) { int count = 0; while (count < TimesToRepeat) { WaitForContext(); RefreshRates(); double TP = DoubleIf(Target > 0, Ask + Target*Point, 0); double SL = DoubleIf(Loss > 0, Ask - Loss*Point, 0); double LotsToBid = DoubleIf(Lot == 0, GetLotsToBid(RiskPercentage), Lot); int res = OrderSend(Symbol(), OP_BUY, LotsToBid, Ask, Slippage, SL, TP, NULL, MN, 0, Blue); if (res > 0) return; } }
т.е. безопасно
Volume[0]>=1
Все правильно, это нормально, так как за один раз может придти сразу 2 или 3 тика, вместо одного, на новостях и больше. К сожалению ни каналы связи, ни оборудование не позволяет передавать всегда данные строго по одному тику, часто тики приходят склеенными, поэтому при вашем условиии не всегда открываются сделки. В тестере это прокатывает, потомучто идет моделирование каждого тика. В реале не катит.
А что непонятно? За время работы функции Start пришло несколько тиков -- все поломалось. Тема уже избита.
Насчет Ваших проблем:
Мой бай -- что-то непонятно?
datetime LastTime; bool IsFirstRun; int init() { LastTime = 0; IsFirstRun = true; } int start() { if(Time[0] == LastTime) { return(0); } LastTime = Time[0]; if(IsFirstRun) { IsFirstRun = false; return(0); } Print(TimeHour(TimeCurrent()); // нужная обработка }
Эта конструкция, как я и писал, не работает если в терминале стоит несколько советников на одном инструменте.
Если эти советники попытаются одновременно выставить ордера терминал виснет (привет Metaquotes).
А что непонятно? За время работы функции Start пришло несколько тиков -- все поломалось. Тема уже избита.
Нет не "За время работы функции Start пришло несколько тиков".
Я проверял и на быстром рынке и на медленно.
Тиков с определенными номерами вообще НЕБЫЛО.
Не то что бы их не было в природе, они, возможно, были у ДЦ, просто они не попали в мой терминал.
Кстати, я не вижу в этом ничего плохого или странного.
Я просто провел исследование и предложил выход из положения.
Естественно один из возможных выходов.
Как вариант, можно предусмотреть контроль и выставление флага в глобальных переменных. Первый успел, захватил флаг. Закончил обработку, очистил. Следующий так же поступает.
Тогда достаточен контроль открытия нового бара по времени и проверка флага.
Как вариант, можно предусмотреть контроль и выставление флага в глобальных переменных. Первый успел, захватил флаг. Закончил обработку, очистил. Следующий так же поступает.
Тогда достаточен контроль открытия нового бара по времени и проверка флага.
Можно, но тогда нужно провести еще одно исследование относительно скорости
обработки глобальных переменных терминалом в привязке с одновременно выполняющимися
советниками. Ведь они выполняются "параллельно" в разных потоках. И тут уже вылазят
возможные архитектурные проблемы: количество процессоров, другие параллельные потоки
скорость процессора и т.п.
Все было бы проще, если бы советники выполнялись по очереди.
Пришел тик - выполнился первый советник, затем второй и т.д.
Тогда и этой темы не было бы.
Но старую добрую архитектуру Big Loop сейчас программисты не уважают.
Им подавай видимость "реального" параллелизма. Но параллелизм то у нас
очень условный, даже если стоит N процессоров. Поэтому и появляются зависания
от того, что при видимости параллелизма возникают большие проблемы с синхронизацией.
(Извините, это у меня отголоски моей основной работы.)
Но я допускаю, что с глобальными переменными все окажется нормально.
Эта конструкция, как я и писал, не работает если в терминале стоит несколько советников на одном инструменте.
Если эти советники попытаются одновременно выставить ордера терминал виснет (привет Metaquotes).
WaitForContext();
Ничо не знаю, у мну по 10 советников тестируется без проблем.
Это мне напоминает одного моего программиста, который, на любые претензии говорил - "А у меня все работает".
Но после того, как пару раз съездил в другой город к заказчику, уволился и со временем завязал с программированием.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
- позволяет быстро оптимизировать стратегию при большом количестве изменяемых параметров;
- позволяет в конечное время выбрать лучшую стратегию и определить критерии качества для их оценки;
- позволяет контролировать выполнение эксперта при помощи параллельного прохождения в тестере стратегий;
- позволяет быстро проводить дооптимизацию при необходимости.
Она идеально работает в тестере стратегий.
Сначала я грешил, что это происходит из-за реквот или отсутствия связи и потратил много времени для улучшения процедур выставления ордеров. Но это практически не помогло. Часть ордеров, по-прежнему, не выставлялась.
Тогда я добавил отладочную операцию.
Это меня несколько удивило, и я написал маленький эксперт,и увидел, что виной оказалась конструкция if(Volume[0]==1)
который и подтвердил мою догадку:
- значения Volume, которые получает терминал на каждом тике, не всегда начинаются с 1;
- значения Volume содержат разрывы.
То есть, последовательность Volume с начала бара может иметь такой вид: 2,5,6,7,10,11,12…
И действительно эксперт перестал пропускать начало бара. Ура!
Но вот проблема. Каждый раз когда я перекомпилирую советник, перезапускаю терминал, то есть сбрасываю переменную LastTime в 0, советник считает что пришел новый день (извините, новый бар) и, как ни в чем не бывало, начинает работу, даже если уже половина периода прошла. Конечно, следующий бар советник отработает как надо. Но проблема первого запуска остается.
Что же, не будем унывать. Простейший способ – запускать терминал и перекомпилировать советник приблизительно на начале нового бара или … сделать еще одну небольшую доработку.
Так я и сделал и приступил к новому этапу тестирования.
К сожалению, на этом мои проблемы не закончились. Спустя достаточно непродолжительное время я заметил, что терминал иногда начал зависать. Причем, ничего не успевая записать в log файл.
Проанализировав ситуацию, я выяснил, что же изменилось с последнего раза. В терминале появилось несколько советников, торгующих на одном и том же инструменте, но по разным стратегиям. Такая своеобразная хеджевая система. Тем не менее, разные алгоритмы выставления ордеров не помешало разным экспертам иногда выставлять ордера в начале одного и того же бара. Это и стало причиной периодического зависания терминала (привет Metaquotes).
Ну, раз причина ясна, – приступим к ее устранению.
Первым делом я пытался придумать какой-нибудь механизм проверки, основанный на занятости торгового потока, при помощи функции
, но быстро отбросил эту идею, ведь советники же выполняются одновременно, поэтому они одновременно получают ответ, что поток свободен или занят.
После еще нескольких экспериментов с синхронизацией через файл, глобальные переменные и что то еще, я пришел к простой конструкции, которая решила все перечисленные проблемы с реальной торговлей.
Устанавливая переменную StartTick в разных экспертах в разные значения (это можно делать вручную или лучше в самом теле эксперта), я устранил зависание терминала и практически полностью сохранил идентичность с работой эксперта в тестере стратегий.
Например.
Зачем же тогда external, спросите вы, достаточно int StartTick=5.
Можно и так, но тогда мы не сможем протестировать советник в режиме «по ценам открытия», ведь тестер генерирует только Voleme[0]=1. Соответственно для тестирования эту переменную нужно выставить в окне «Свойства эксперта» в закладке «входные параметры» в StartTick=1. Или дополнить код:
Вот собственно и все. Тестируется уже более месяца. Проблем нет. Идентичность с тестером стратегий почти полная.
Например:
Цель этой функции не выставить ордер, во что бы то ни стало, а уменьшить влияние реквот и кратковременного пропадания связи не зайдя при этом в бесконечный цикл, не делая длительных пауз и не завесив терминал.
Функции для SELL и отложенных ордеров аналогичны.