Rosh, falkov, спасибо за ссылки - оказывается, я ту статью читал в свое время, она писалась "для чайников", так что там термины нестрогие и ООП больше для антуражу, конечно )).
А вот количества функций реально не хватает. Вон в соседней ветке человек просит по кнопке менять символы. Просьба редкая, в общую функциональность включать незачем. Текущими средствами языка - делать сложно. А дать ему CreateChart(symbol) - и пусть на коленке ваяет, что ему нужно.
Quod Licet: Фактически, то же самое, что сейчас приходится делать при необходимости onclose отследить - ведя массив открытых ордеров, сверяя его с реальным - и по результатам расхождения вызывая те же пользовательские on_open, on_close - но со спрятанными неаппетитными кишками.
Ведь подобие init тоже можно реализовать в start, заведя булевскую переменную first_run и выделив в start отдельный блок работы "при первом проходе". Но куда удобней, когда init лежит отдельно. Так же и с onclose.
А я эмулирую onclose проверяя историю ордеров. Мне кажется это экономнее. Хотя не проверял.
int AccTotal=OrdersHistoryTotal();
if (AccTotal != preAccTotal) {
// Здесь перебор только появившихся после предыдущего тика ордеров
for (i= preAccTotal; i<AccTotal; i++) {
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) {
Print("Ошибка при доступе к исторической базе (",GetLastError(),")");
}
...
} // for (i= preAccTotal; i<AccTotal; i++)
preAccTotal = AccTotal;
} // if (AccTotal != preAccTotal)
Но с onclose конечно проще было бы. А вот init, мне кажется, была введена совсем не для того, чтобы избавить пользователя от first_run, потому что во время выполнения init не гарантируются правильные значения предопределённых переменных, например Bars и Point.
"А я эмулирую onclose проверяя историю ордеров" - ага, элегантный вариант. У меня просто в массиве хранятся доп.данные, и по нему все равно приходится бегать с другими целями, так что on_open, on_close получаются "бесплатным побочным эффектом" - но встроенную реализацию все равно бы приветствовал.
(кстати, уж сколько копий сломано об OrderUserInfo с дополнительными пользовательскими данными об ордерах - ну понятно, нагрузка на сервер, но можно ведь сделать некое кэширование, если не прозрачное, так функцию SaveUserInfosToServer, запретить ее вызывать чаще раза в сутки )) - и овцы сыты и волки целы)
Rosh, мерси за ссылку (впрочем, почему-то не открывается (( ) - полагаю, каждый в этом треде, кому приспичивало, тем или иным образом подобную функцию написал и пользуется. Я больше ратую за приятную унификацию часто возникающих задач, чем за то, что подобную функцию нельзя написать ).
Candid - да, тут в голове пробежало одно соображение: в истории есть подводный камень - она зависит от действий пользователя, и может быть загружена не полностью (была пара таких веток). Я глубоко эту тему не копал, но сильно подозреваю, что если пользователь в процессе торговли выберет фильтрацию истории в интерфейсе - количество HistoryTotal поменяется, и скрипт сбойнет. Не уверен, что так будет - но обратите внимание на всякий случай.
Rosh - ага, открыл ссылку - с контрольной суммой интересное решение ) - оно, правда, скорее на сам факт смены заточено, чем на отслеживание конкретного ордера - но интересно придумано.
Воистину, "голь на выдумки хитра" - уже три разных варианта со своими плюсами и минусами, и сколько можно еще напридумывать... )))
Раз тут варианты обсуждаем, я прекрасно обхожусь без онклозов. Я смотрю есть у меня ордер или нет и всего делов. И ошибки не проверяю. Отправил команду серверу и из старта вышел. при следующем вызове снова смотрю, есть ордер или нет.
Candid - да, тут в голове пробежало одно соображение: в истории есть подводный камень - она зависит от действий пользователя, и может быть загружена не полностью (была пара таких веток). Я глубоко эту тему не копал, но сильно подозреваю, что если пользователь в процессе торговли выберет фильтрацию истории в интерфейсе - количество HistoryTotal поменяется, и скрипт сбойнет. Не уверен, что так будет - но обратите внимание на всякий случай.
Справедливое замечание. В принципе изменение настроек можно обработать запоминая тикет последнего обработанного ордера. А вот ситуация, когда ордер исчезнет из списка открытых и не появится в истории опасна и в этом подходе вроде не лечится. То есть если onclose нужно предпринимать критически важные действия, он не годится. Исходно же конструкция предназначена для сбора статистики - onclose сбрасываем на диск данные по этому ордеру (у меня обычно данные по рынку на момент открытия и характеристики ордера типа времени жизни или максимальной просадки за время существования). В этом случае таким редким событием как потеря ордера для истории можно наверное пренебречь. Для сбора же статистики в тестере этой опасности вообще нет и решающей становится скорость работы.
Типа того )). Мартингейл - классический пример, когда мы в том или ином виде эмулируем on_close )).
---
Candid Ага, для статистики можно игнорировать, да и по большому счету, с трудом можно представить ситуацию (и причину), когда в режиме работы советника уменьшаешь историю вообще до нуля. Если сам себе не враг, конечно ))).
А вот количества функций реально не хватает. Вон в соседней ветке человек просит по кнопке менять символы. Просьба редкая, в общую функциональность включать незачем. Текущими средствами языка - делать сложно. А дать ему CreateChart(symbol) - и пусть на коленке ваяет, что ему нужно.
Фактически, то же самое, что сейчас приходится делать при необходимости onclose отследить - ведя массив открытых ордеров, сверяя его с реальным - и по результатам расхождения вызывая те же пользовательские on_open, on_close - но со спрятанными неаппетитными кишками.
Ведь подобие init тоже можно реализовать в start, заведя булевскую переменную first_run и выделив в start отдельный блок работы "при первом проходе". Но куда удобней, когда init лежит отдельно. Так же и с onclose.
А я эмулирую onclose проверяя историю ордеров. Мне кажется это экономнее. Хотя не проверял.
int AccTotal=OrdersHistoryTotal(); if (AccTotal != preAccTotal) { // Здесь перебор только появившихся после предыдущего тика ордеров for (i= preAccTotal; i<AccTotal; i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Ошибка при доступе к исторической базе (",GetLastError(),")"); } ... } // for (i= preAccTotal; i<AccTotal; i++) preAccTotal = AccTotal; } // if (AccTotal != preAccTotal)Но с onclose конечно проще было бы.
А вот init, мне кажется, была введена совсем не для того, чтобы избавить пользователя от first_run, потому что во время выполнения init не гарантируются правильные значения предопределённых переменных, например Bars и Point.
(кстати, уж сколько копий сломано об OrderUserInfo с дополнительными пользовательскими данными об ордерах - ну понятно, нагрузка на сервер, но можно ведь сделать некое кэширование, если не прозрачное, так функцию SaveUserInfosToServer, запретить ее вызывать чаще раза в сутки )) - и овцы сыты и волки целы)
Rosh, мерси за ссылку (впрочем, почему-то не открывается (( ) - полагаю, каждый в этом треде, кому приспичивало, тем или иным образом подобную функцию написал и пользуется. Я больше ратую за приятную унификацию часто возникающих задач, чем за то, что подобную функцию нельзя написать ).
Rosh - ага, открыл ссылку - с контрольной суммой интересное решение ) - оно, правда, скорее на сам факт смены заточено, чем на отслеживание конкретного ордера - но интересно придумано.
Воистину, "голь на выдумки хитра" - уже три разных варианта со своими плюсами и минусами, и сколько можно еще напридумывать... )))
Это что, проверка связи? :)
Справедливое замечание. В принципе изменение настроек можно обработать запоминая тикет последнего обработанного ордера. А вот ситуация, когда ордер исчезнет из списка открытых и не появится в истории опасна и в этом подходе вроде не лечится. То есть если onclose нужно предпринимать критически важные действия, он не годится. Исходно же конструкция предназначена для сбора статистики - onclose сбрасываем на диск данные по этому ордеру (у меня обычно данные по рынку на момент открытия и характеристики ордера типа времени жизни или максимальной просадки за время существования). В этом случае таким редким событием как потеря ордера для истории можно наверное пренебречь. Для сбора же статистики в тестере этой опасности вообще нет и решающей становится скорость работы.
Типа того )). Мартингейл - классический пример, когда мы в том или ином виде эмулируем on_close )).
---
Candid Ага, для статистики можно игнорировать, да и по большому счету, с трудом можно представить ситуацию (и причину), когда в режиме работы советника уменьшаешь историю вообще до нуля. Если сам себе не враг, конечно ))).