Библиотека ExpInd.dll : Эмуляция индикаторных буферов для советника

 

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

Что умеет библиотека:

1. Создавать индикаторные буферы (количество ограничено только памятью вашего компа и/или вашей извращенностью)

2. Записывать/Читать значения из буферов

3. Смещать значения в буфере в ручном или автоматическом режиме

4. Диагностировать ошибки (GetLastError)

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

Подробности:

Буферы реализуются по принципу кольца. Это означает, что новое значение будет записано вместо самого старого, содержащегося в буфере. Но, согласитесь, редкий индикатор лазит в историю на 500 и более баров, а если и лазит, то ничто не мешает создать буфер на 1000 и более элементов.

Прежде чем работать с буфером, его нужно создать. Функция, создающая буфер, возвращает его ID. Этот ID применяется в функциях чтения/записи.

Запись и чтение данных производятся соответствующими функциями. Количество параметров в функциях сведено к функциональному минимуму. Функции имеют защиту от дурака и защиту от кулхацкера, так что писануть чего-нить в случайное место или читануть чего-нить из случайного места не выйдет. 

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

Функции библиотеки:

uint EI_Buffer(uint _elements)

Создает буфер на заданное количество элементов _elements.

В случае успешного создания возвращает ID буфера, иначе 0.

bool EI_Set(uint _buffer, uint _index, double _val, bool _autoshift = true)

Записывает в заданный буфер _buffer значение _val по индексу _index. Параметр _autoshift отвечает за автоматическое смещение значений буфера после операции записи. По-умолчанию смещение включено. Автоматическое смещение обнуляет значение по 0-му индексу. (Подробнее на скринах и в примерах.)

В случае успешной записи возвращает true, иначе false и устанавливает номер последней ошибки.

Для простоты восприятия такая аналогия со стандартными буферами: EI_Set(Buffer, i, Close[j])  <= аналогично => Buffer[i] = Close[j]

bool EI_Shift(uint _buffer)

Производит принудительное смещение значений буфера _buffer и обнуляет значение по 0-му индексу. 

double EI_Get(uint _buffer, uint _index)

Возвращает прочитанное значение из буфера _buffer по индексу _index.

uint EI_GetLastError(void)

Возвращает номер последней ошибки.

Ошибка N1 - Неверный ID буфера.

Ошибка N2 - Несуществующий индекс буфера.


Полевые испытания:

Во всех испытаниях создается буфер на 5 элементов. Такое количество элементов позволит наглядно продемонстрировать все особенности работы с библиотекой.

Испытание 1. Демонстрация записи в буфер с автоматическим смещением. (смотрим на скрин снизу вверх)

Не забываем, что после записи и смещения производится обнуление значения по 0-му индексу.

Запись со смещением

Испытание 2. Демонстрация записи в буфер без автоматического смещения. Демонстрация принудительного смещения. (смотрим скрин снизу вверх)

Различие в том, что запись значений производится без автоматического смещения EI_Set(Buffer, 0, Open[0], false). В результате видно, что значение записано по 0-му индексу.

Далее вызывается функция принудительного смещения EI_Shift(Buffer). В результате значения смещаются назад, а 0-й элемент обнуляется.

Запись без смещения. Принудительное смещение.

Испытание 3. Демонстрация защиты от дурака и/или кулхацкера.

Выполняется 3 вызова функции EI_Set(...): два ошибочных, один верный.

Первый ошибочный вызов заключается в обработке неверного ID буфера: можно заметить, что ID буфера увеличен на единицу (Buffer+1).

Второй ошибочный вызов заключается в обработке неверного индекса (мы же помним, что для испытаний создан буфер на 5 элементов): задан несуществующий индекс 10.

Третий вызов верный и ошибок не содержит.

Защита от дурака и/или кулхацкера.

#import-секция:

#import"ExpInd.dll"
   uint     EI_Buffer(uint _elements);
   bool     EI_Set(uint _buffer, uint _index, double _val, bool _autoshift = true);
   bool     EI_Shift(uint _buffer);
   double   EI_Get(uint _buffer, uint _index);
   uint     EI_GetLastError(void);
#import

Начинка прикрепленного архива:

- Библиотека ExpInd.dll

- Тестовые примеры (3 файла)

- Текстовый файл с #import-секцией

Файлы:
ExpInd.zip  20 kb
 

Спасибо, что делитесь.

Но чем это решение лучше нескольких готовых и нативных?

 
Andrey Khatimlianskii:

Спасибо, что делитесь.

Но чем это решение лучше нескольких готовых и нативных?

Позволю себе побыть немного евреем. А зачем столько готовых решений? Почему всем не хватает одного решения?

Альтернативный выбор, имхо, не есть плохо.

 
AdjusterAdviser:

Альтернативный выбор, имхо, не есть плохо.

Если он дает какие-то преимущества

 
Andrey Khatimlianskii:

Если он дает какие-то преимущества

Разумеется. Только не каждый способен вкурить, что использование классов для разных реализаций банальных кольцевых буферов - не есть преимущество. )

 
AdjusterAdviser:

Разумеется. Только не каждый способен вкурить, что использование классов для разных реализаций банальных кольцевых буферов - не есть преимущество. )

Ну, разумеется, только ваша dll даст всем вкурить истинный кайф.

 
Andrey Khatimlianskii:

Ну, разумеется, только ваша dll даст всем вкурить истинный кайф.

Я рад, что вы это осознали.

 
AdjusterAdviser:

Я рад, что вы это осознали.

Как жаль что вы не поняли издёвки...

 
Alexey Viktorov:

Как жаль что вы не поняли издёвки...

Вы в этом уверены? )

 
AdjusterAdviser:

Вы в этом уверены? )

А вы откровенно спросите у Андрея)))))))))))))))

 
Alexey Viktorov:

А вы откровенно спросите у Андрея)))))))))))))))

Сказали бы уже прямо, а то все вокруг да около.

Причина обращения: