Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Этого в документации НЕТУ!!! Следовательно это сочинения на вольную тему. Равно как и моё заявление об автоматической инициализации, даже круче. Моё хоть с оговоркой было...
Абсолютно всё описать в документации невозможно.
Получили "prev_calculate==0" - значит нужно пройтись по всему индикаторному буферу. Если "prev_calculate!=0" значит в этом случае считаем только или самый правый бар или несколько новых (используем limit):
{
//---
if(prev_calculated==0)
{
Print("prev_calculated==0");
for(int i=0;i<rates_total;i++)
{
//--- здесь принудительно каждому элементу массива присваиваем значение (мне лень писать эти массивы :) )
}
return(rates_total);
}
//--- экономный пересчёт только самого правого бара или новых баров
int limit=rates_total-prev_calculated+1;
//--- а ниже нужно использовать цикл для обсчета самого правого бара или новых баров
for(int i=0;i<limit;i++)
{
ExtBuffer[i]=чевой-то там;
}
Абсолютно всё описать в документации невозможно.
Получили "prev_calculate==0" - значит нужно пройтись по всему индикаторному буферу. Если "prev_calculate!=0" значит в этом случае считаем только или самый правый бар или несколько новых (используем limit):
{
//---
if(prev_calculated==0)
{
Print("prev_calculated==0");
for(int i=0;i<rates_total;i++)
{
//--- здесь принудительно каждому элементу массива присваиваем значение (мне лень писать эти массивы :) )
}
return(rates_total);
}
//--- экономный пересчёт только самого правого бара или новых баров
int limit=rates_total-prev_calculated+1;
//--- а ниже нужно использовать цикл для обсчета самого правого бара или новых баров
for(int i=0;i<limit;i++)
{
ExtBuffer[i]=чевой-то там;
}
Какое значение??? Мне не нужны никакие значения кроме самого правого бара. НО!!! Потом когда этот самый правый смещается влево эти засунутые туда данные надо сохранить...
Не обязательно писать все буферы, а один можно было и написать с учётом моих пожеланий. Если это первый запуск - вся история должна быть пустой. Если-же обнуление prev_calculated произошло в следствии подкачки истории то ВСЁ что было в буфер засунуто должно остаться в неизменном виде. Пусть даже появятся дыры.
Предварительные выводы:
Чё ахинею нести? Если такую инициализацию засунуть в OnCalculate то обнуляется на ура без каких либо циклов. Но если обнуляется prev_calculated то обнуляет все данные которые были накоплены в процессе работы...
Какое значение??? Мне не нужны никакие значения кроме самого правого бара. НО!!! Потом когда этот самый правый смещается влево эти засунутые туда данные надо сохранить...
...
Я уже предлагал способ:
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
prev_calculated
Karputov Vladimir, 2016.10.18 15:11
Извините за задержку с ответом. Единственный вариант сохранения рассчитанных значений для данного таймфрейма - это сохранять в файл. При этом нужно озаботиться синхронизацией - чтобы при чтении из файла данные разместились по своим барам. Самое логичное - это синхронизация по времени открытия бара, но здесь могут быть нюансы: например время открытия бара (сохранённое в файл) было 2016.09.05. 25:02, а теперь на графике есть бар у которого время равно 2016.09.05. 25:01.Индикатор - это не база данных и не хранилище.
Поэтому если индикатор отображает данные которые потом не могут быть рассчитаны на истории, то остаётся только сохранять индикаторный буфер в файл, а потом (в случае подкачки истории) проводить чтение и синхронизировать файл и бары.Я уже предлагал способ:
Индикатор - это не база данных и не хранилище.
Поэтому если индикатор отображает данные которые потом не могут быть рассчитаны на истории, то остаётся только сохранять индикаторный буфер в файл, а потом (в случае подкачки истории) проводить чтение и синхронизировать файл и бары.... и желательно без записи в файл или тем более в GV.
Владимир, раз вы выделили этот топик спецом под prev_calculated, сделайте его полезным именно по этой теме. Во-первых, надо обозначить проблему в которую обычно упираются с этой переменной. Если вам эти проблемы не знакомы, я сформулирую
---
а - хоть в справке и написано
использовать её именно для этого нельзя - в любой момент может показать фигу. Причина в том (написано в справке + сказано разработчиками), что переменная обнуляется при изменении контрольной суммы, обычно - из-за подкачки истории
---
б - использовать prev_calculated == 0 в кач-ве флага первого запуска OnCalculate тоже нельзя. По той же причине
---
в - и как флаг подкачки истории prev_calculated == 0 тоже использовать нельзя
---
Чтобы уменьшить износ граблей пользователями, сформулировать желательно кратко и однозначно: если подкачки истории не случилось на текущем вызове OnCalculate, то prev_calculated содержит кол-во баров обработанных на предыдущем. Если случилось - она обнуляется
---
Все 3 перечисленных затыка можно обойти с помощью костылей. Но раз в MT5 костылей быть не может по определению, вы бы, Владимир, сочинили бы красивое решение для этих 3х задач. Некрасивое примерно такое:
#property indicator_buffers 0
#property indicator_plots 0
struct BROWNIE {
int i_Prew_Calculated; // кол-во посчитанных баров
bool b_First_Run; // флаг первого запуска
bool b_History_Updated; // флаг обновления истории
BROWNIE() {
i_Prew_Calculated = WRONG_VALUE;
b_First_Run = true;
b_History_Updated = false;
}
void f_Reset(bool b_Reset_First_Run = true) {
i_Prew_Calculated = WRONG_VALUE;
if(b_Reset_First_Run) b_First_Run = true;
b_History_Updated = false;
}
void f_Update(int i_New_Prew_Calculated = WRONG_VALUE) {
if(i_New_Prew_Calculated > -1) {
b_History_Updated = i_New_Prew_Calculated == 0 && i_Prew_Calculated > WRONG_VALUE;
if(b_First_Run) b_First_Run = false;
if(i_Prew_Calculated == WRONG_VALUE) i_Prew_Calculated = i_New_Prew_Calculated;
else if(i_New_Prew_Calculated > 0) i_Prew_Calculated = i_New_Prew_Calculated;
}
}
};
BROWNIE go_Brownie;
int OnInit(void) {return(INIT_SUCCEEDED);}
void OnDeinit(const int reason) {
go_Brownie.f_Reset(reason != REASON_CHARTCHANGE);
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &Time[],
const double &Open[],
const double &High[],
const double &Low[],
const double &Close[],
const long &TickVolume[],
const long &Volume[],
const int &Spread[]
) {
if(go_Brownie.b_First_Run) {/* обработка 1го запуска */}
if(go_Brownie.b_History_Updated) {/* обработка обновления истории */}
go_Brownie.f_Update(prev_calculated);
return(rates_total);
}
Disclaimer: код - голая идея, на графике не гонял
В OnDeinit прописан образец - обработка для индикатора, который буферов не использует, ему пофиг на ТФ и символ, при каждой смене ТФ/символа начинать всё с нуля не нужно. Напр, работает с существующими граф.элементами, выводит инфу о состоянии счёта, ордерах и тд
---
Кстати
то остаётся только сохранять индикаторный буфер в файл, а потом (в случае подкачки истории) проводить чтение и синхронизировать файл и бары.
... и желательно без записи в файл или тем более в GV.
Может Вам это подойдет?
В подробности не вникал, но такое решается оной строкой кода. Копирование массива самого в себя со сдвигом индекса.
ArrayCopy(arr, arr, 0, 1, 4);
// и дальнейшее заполнение 4го индекса массива.