как опубликовать советник в магазине ?

 

он бесплатный  ! всегда ошибка на все советники на тесте такой результат , разве он плохой за 23 год


 
Maksim Golovin:

он бесплатный  ! всегда ошибка на все советники на тесте такой результат , разве он плохой за 23 год


он плохой потому-что в нём ошибки..

маркет не гарантирует прибыльность, стабильность, виллу-на-гавайях.

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

У вас пока-что есть ошибки. 

----

"программа считает быстрее всех, но выдаёт какую-то фигню", это из этой-же оперы

 
Maksim Golovin:

он бесплатный  ! всегда ошибка на все советники на тесте такой результат , разве он плохой за 23 год


Если есть ошибки при тестировании - однозначно плохой !

 
Да и просадка больше 60% его тоже как-то не красит. А также сильно разные результаты за 2023 и за часть 2024 года.
 
Yuriy Bykov #:
Да и просадка больше 60% его тоже как-то не красит. А также сильно разные результаты за 2023 и за часть 2024 года.

Интересно, а скальперская панель-полуавтомат в маркете зайдет? Как там ее будут тестировать, ведь все от трейдера зависит.

 
Alexey Volchanskiy #:

Интересно, а скальперская панель-полуавтомат в маркете зайдет? Как там ее будут тестировать, ведь все от трейдера зависит.

скальперская панель с функцией "торговой панели" это крутая штука может быть для ручных трейдеров

только надо дизайн, цвет, функционал подобрать-скопировать, и стоимость - "панели"))

 
Alexey Volchanskiy #:

Интересно, а скальперская панель-полуавтомат в маркете зайдет? Как там ее будут тестировать, ведь все от трейдера зависит.

скальперы - тема!

как там кстати твоя статья ? :-)

хоть в блоге напиши её что-ли..

 
Maxim Kuznetsov #:

скальперы - тема!

как там кстати твоя статья ? :-)

хоть в блоге напиши её что-ли..

давай уж здесь. Сегодня обучал клиента MQL5, скинул ему эту старую заготовку про FIR и прочие ЦФ

Использование методов цифровой обработки сигналов в экспертах и индикаторах - ч.1 Цифровые фильтры

Для чего нужны цифровые фильтры. Характеристики цифровых фильтров

Два типа фильтров - КИХ и БИХ

Алгоритм КИХ-фильтра, анализ кода Simple MA

Почему индикатор Moving Average является набором цифровых фильтров

Анализ частотных характеристик.

Расчет коэффициентов КИХ.

Как устроен фильтр с бесконечной импульсной характеристикой БИХ.

Анализ кода Exponential MA, как БИХ фильтра.

Расчет коэффициентов БИХ.

Достоинства и недостатки использования КИХ и БИХ фильтров в индикаторах и экспертах

Введение

Эта статья рассчитана на программистов, не знакомых с базовыми понятиями цифровой обработки сигналов (далее ЦОС) или начинающих ее осваивать.

Как написал Стивен Хокинг в предисловии книги «Краткая история времени от большого взрыва до черных дыр»:«Мне сказали, что каждая включенная в книгу формула вдвое уменьшит число покупателей. Тогда я решил вообще обходиться без формул. Правда, в конце я все-таки написал одно уравнение - знаменитое уравнение Эйнштейна Е=mc^2. Надеюсь, оно не отпугнет половину моих потенциальных читателей».

Следуя этому мудрому совету, я тоже обойдусь без многоэтажных формул и сделаю упор на практическое применение. В конце концов, чтобы летать на самолете, совсем не обязательно досконально знать, как он устроен. Тем не менее, надо запастись терпением и усвоить минимум теории. Ну а тем, кому хочется сначала оценить, нужно ему это или нет, можно перейти к разделу кода и примеров и пощупать, что называется, руками.


Мы рассмотрим, как использовать методы цифровой обработки сигналов (далее ЦОС) для создания алгоритмов, которые можно использовать в программах на языке MQL5. Конкретно, будут рассмотрены цифровые фильтры (далее ЦФ) и их базовые характеристики. Будет написан и подробно прокомментирован класс ЦФ. Все листинги будут приведены на языке MQL5, но в большинстве случаев код будет работать и на MQL4. В конце статьи вы найдете список общеупотребительных сокращений по ЦОС, используемых в статье.


Мир ЦОС окружает нас повсюду, хотя большинство людей даже не подозревают об этом. Сотовые телефоны, цифровое телевидение, аудио и видео плееры, различные гаджеты, цифровая телефония, сжатие и обработка видео и звука, радиолокация и гидроакустика  - во всех этих областях широко используются алгоритмы ЦОС.

Сейчас выпускается огромное количество специализированных процессоров, аппаратно заточенных под алгоритмы ЦОС. Они имеют наборы команд, реализующие базовые алгоритмы обработки, к примеру, параллельное умножение векторов со сложением результатов или базовые операции быстрого преобразования Фурье.

В процессоры для персональных компьютеров также вводятся новые расширения команд, ускоряющие эти алгоритмы.

Для чего нужны цифровые фильтры. Характеристики цифровых фильтров.

Цифровые фильтры (далее ЦФ) ведут родословную от аналоговых фильтров, которые широко применяются в радиоэлектронике. Аналоговые фильтры используются, начиная с первых радиоприемников и передатчиков и представляют из себя схемы, состоящие из наборов катушек индуктивности, конденсаторов, резисторов и, как правило, усилительных элементов. Для аналоговых фильтров давно разработаны стандартные схемы каскадов и методы расчета компонентов.

ЦФ могут повторять структуры аналоговых фильтров и полностью копировать их характеристики. Но самое интересное, можно реализовать ЦФ с потрясающими параметрами, которые принципиально недостижимы в их аналоговых предках. И если 20-25 лет назад процессоры ЦОС были медленными и дорогими, то сейчас, с увеличением быстродействия, уменьшением размеров и цены, ЦФ заменили аналоговые фильтры в большинстве применений.

Д‌ля чего же нужны ЦФ? Основная область задач - изменение амплитудно-частотной характеристики (далее АЧХ) и фазо-частотной характеристики (далее ФЧX) сигнала. Кроме этого, существуют и другие применения, которые мы сейчас рассматривать не будем. Вместо этого разберемся с важнейшими для нас параметрами ЦФ. Для тех, кто знаком с электроникой, сразу уточняю - все, что я говорю, описано с точки зрения трейдинга. Итак, вот эти параметры:

Амплитудно-частотная характеристика (далее АЧХ)

Фазо-частотная характеристика (далее ФЧХ)

Переходная функция (далее ПФ)

Импульсная передаточная функция (далее ИПФ), еще называют импульсная характеристика

Амплитудно-частотная характеристика (АЧХ)‌

Должна быть знакома каждому, кто интересуется аудио-аппаратурой. Описывает зависимость ослабления амплитуды сигнала от его частоты при прохождении через фильтр. Традиционно показывается в виде графика, где по оси X задается частота, а по оси Y - амплитуда сигнала. 

Амплитуда обычно задается в децибелах и вычисляется, как AdB = 20*log(A), где


A - ослабление сигнала, отношение выходного сигнала к входному. Например, при ослаблении в 100 раз A = 0.01.

Adb - ослабление сигнала, выраженное в децибелах. Для A = 0.01 AdB будет равно -40 dB. В MQL эти величины можно высчитать, как:

void OnStart()

  {

   double A=0.01,AdB=0;

   AdB=20*MathLog10(A); // 20*(-2) == -40 dB  

   A=MathPow(10,AdB/20);

   Print("A=",DoubleToString(A,4),"   AdB=",DoubleToString(AdB,4)); // A=0.0100   AdB=-40.0000

  }

Частота может задаваться как в Герцах, так и в виде нормализованной частоты, как на рис. ***. Нормализованная частота обычно задается в диапазоне 0...1, где за единицу принимается частота дискретизации (далее ЧД). Такое представление удобно тем, что отсутствует жесткая привязка расчетов к ЧД, а для получения реальных значений частот достаточно умножить нормализованное значение на эту частоту. Что такое ЧД и нужна ли вообще дискретизация входных тиков по времени мы разберемся позже. А пока считайте, что фильтр работает по событию OnTimer с периодом, например, 1 сек, то есть ЧД будет равна 1/период == 1 Гц. При использовании нормализованной частоты появляется удобное свойство фильтра - не надо пересчитывать его коэффициенты при изменении ЧД, так как коэффициенты к ней не привязаны. 


FIR АЧХ


 рис. АЧХ фильтра КИХ нижних частот 12-го порядка. Fpass = 0.2, Fstop = 0.45, Apass = 3 dB, Astop = -40 dB 


где


Fpass - частота пропускания, меньше которой обеспечивается пропускание сигнала с погрешностью не более Apass.

Fstop - частота подавления, выше которой обеспечивается пропускание сигнала менее Astop.

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

Astop - гарантированный уровень подавления на частоте подавления и выше. 

‌Насчет количества коэффициентов ЦФ есть некоторые закономерности:


‌Чем меньше Apass, то есть меньше искажения в полезной полосе пропускания Fpass, тем больше длина массива коэффициентов.

Чем меньше Astop, то есть лучше подавление, тем больше длина массива коэффициентов. Не забываем, что (-60 dB < -40 dB) == true.

Чем ближе друг к другу Fpass и Fstop, то есть чем круче срез фильтра, тем больше длина массива коэффициентов.

В общем случае чем меньше частоты Fpass и Fstop, тем больше длина массива коэффициентов. 

А чем больше длина массива коэффициентов, тем большую задержку будет вносить фильтр. 

Фазо-частотная характеристика (ФЧХ)‌‌


На рис. *** ФЧХ показана коричневой линией. Она показывает фазовый сдвиг частот сигнала после прохождения через фильтр. Не вдаваясь в подробности, видим, что ФЧХ является прямой линией. Это хорошо, так как означает линейный фазовый сдвиг, а значит, форма сигнала после фильтра будет иметь минимальные искажения. Забегая вперед скажу, что у фильтров КИХ обычно линейная или очень близко к линейной ФЧХ, а у фильтров БИХ в принципе нельзя добиться линейности. У данного фильтра частота подавления 0.45, после нее видна интересная зигзагообразная фаза. Не надо пугаться, она находится в районе выше частоты подавления и никому не повредит. 

‌ AFR-PFR


АЧХ (синяя) и ФЧХ (коричневая) линии фильтра КИХ.  Fpass = 0.2, Fstop = 0.45, Apass = 3 dB, Astop = -40 dB


И для сравнения рассмотрим фазу фильтра БИХ.


PFR-IIR


АЧХ (синяя) и ФЧХ (коричневая) линии эллиптического фильтра БИХ,  Fpass = 0.2, Fstop = 0.45, Apass = 3 dB, Astop = -40 dB


Переходная функция, другое название переходная характеристика


До этого мы рассматривали параметры в частотно-фазовых областях и у вас мог возникнуть вопрос - а зачем все это нужно? Давайте посмотрим на переходную функцию, она ответит на этот вопрос. Она показывает форму сигнала после подачи импульса-ступеньки. Фактически, можно визуально оценить, как быстро отфильтрованный сигнал выйдет на уровень входной ступеньки, будет ли колебательный процесс. На рисунках на вход фильтра подается сигнал с амплитудой 1, задача фильтра сгладить эту ступеньку с минимальным выбросом выше единицы и как можно быстрее прийти к состоянию сигнала на выходе, равном единице. Разумеется, при тестировании мы можем подавать сигнал с любым интересующим нас значением. Немного позже мы посмотрим, как реагируют фильтры разных типов на реальные котировки.


transient response 


 рис.*** Переходная характеристика КИХ фильтра нижних частот 12-го порядка.


step_iir


рис.*** Переходная характеристика БИХ фильтра нижних частот.


Импульсная характеристика


Импульсная характеристика представляет реакцию фильтра на подачу одиночного импульса (например тика) с большой амплитудой. Оптимальный фильтр должен как можно сильнее подавить такой импульс и как можно быстрее успокоить колебания и вернутся в исходное состояние.


FIR 12 impulse response 


рис.*** Импульсная характеристика КИХ фильтра нижних частот 12-го порядка.




impulse_response_iir


рис.*** Импульсная характеристика БИХ фильтра нижних частот 12-го порядка.


Кроме того, как мы скоро увидим, для КИХ фильтра импульсная характеристика является его массивом коэффициентов! То есть, теоретически, вы можете нарисовать такую характеристику вручную, перевести ее в числа формата double и посмотреть, что из этого получится. Более того, если над импульсной характеристикой сделать преобразование Фурье, получим комплексный спектр, который содержит в себе АЧХ и ФЧХ. Выделить реальные значения АЧХ и ФЧХ из комплексного спектра также совсем несложно.


Прелесть цифровых фильтров состоит в их программной простоте. Для КИХ фильтров весь алгоритм занимает буквально несколько десяток строчек на языке MQL5. Все параметры фильтра изменяются через загрузку набора значений в массив коэффициентов. То есть для преобразования фильтра нижних частот (ФНЧ) в фильтр верхних частот (ФВЧ) нам не нужно переписывать код, достаточно загрузить соответствующий набор коэффициентов в массив. Аналогично, для изменения параметров Apass, Astop, Fpass, Fstop достаточно загрузить другие коэффициенты. На первый взгляд, это выглядит, как фантастика, но скоро мы в этом убедимся на практике. 


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



Два типа фильтров - КИХ и БИХ


Сейчас мы рассмотрим устройство двух типов фильтров, которые являются фундаментом всех алгоритмов фильтрации. Первый тип, это фильтр с Конечной Импульсной Характеристикой (далее КИХ), также вы встретите английское название FIR (Finite Impulse Response). Этот тип фильтров не не может быть реализован в аналоговом виде, в виде радио-схемы, только в виде математического алгоритма. КИХ фильтр не имеет обратных связей в своей структуре и в большинстве случаев имеет линейную фазу передачи сигнала. 


Второй тип - фильтры с Бесконечной Импульсной Характеристикой (далее БИХ), английская аббревиатура IIR (Infinite Impulse Response). Эти фильтры имеют в структуре обратные связи и, как ясно из названия, их импульсная характеристика является бесконечной, то есть их импульсная и переходная характеристика будут иметь бесконечные затухающие колебания после подачи тестового сигнала. Хорошим примером из аналогового мира является колебательный контур, обычные качели, колокол. Например, если толкнуть качели, они будут колебаться с определенной частотой и постепенно затухающим размахом. Само собой, в реальных условиях их колебания будут конечны. Качели в какой-то момент остановятся из-за трения, звук колокола и колебания контура сравняются с тепловым шумом. У реального цифрового БИХ-фильтра колебания тоже рано или поздно закончатся, так как формат числа double имеет ограниченную точность.


Рассмотрим структуру КИХ фильтра 4-го порядка.


fir4


рис. 1 Структура КИХ фильтра


Давайте разберемся, как работает эта магия. Сразу скажу, что на рисунке представлена условная схема, цель которой обеспечить максимально быстрое понимание устройства КИХ. В реальном оптимизированном коде, конечно, нет никаких сдвигов данных по элементам массива, так как это слишком затратная операция, нет и множества сумматоров.

В этой условной схеме есть сдвиговый массив типа double arr[4]. При поступлении нового тика данные в массиве сдвигаются слева направо на одну позицию. После этого входной тик и сдвинутые данные умножаются на свои коэффициенты фильтра c0-c4 и складываются в сумматорах. В результате получаем на выходе один отфильтрованный тик.

Напомню, что тип фильтра (ФНЧ, ФВЧ и др.), а также все его характеристики зависят только от коэффициентов с0-сХ и порядка фильтра. Общее правило очень простое - чем больше порядок, тем меньше будет переходная зона между полосой пропускания и полосой подавления Fstop - Fpass, тем меньшие колебания Apass в полосе пропускания можно обеспечить. Но с увеличением порядка линейно возрастает временная задержка фильтра и количество умножений и сложений на один тик. 


Теперь рассмотрим структуру БИХ фильтра. В отличии от КИХ фильтра с его простейшим алгоритмом БИХ фильтры могут иметь разные виды структур, иногда довольно сложные. Эти фильтры имеют обратные связи, то есть часть выходного сигнала подается на предшествующие звенья, они имеют не только сумматоры, но и сумматоры-вычитатели и два набора коэффициентов, a и b. Ниже я привел несколько примеров.


iir1


рис. *** Односекционный БИХ фильтр


iir4         


рис.*** Двухсекционный БИХ фильтр


                                                                   


Достоинством БИХ фильтров является, как правило, меньшее число умножителей и сумматоров при равных требованиях к АЧХ в сравнении с КИХ фильтрами. С другой стороны, они имеют нелинейную фазовую характеристику, более сложны в программной реализации и при больших порядках имеют длительный "звон" в ответ на входные импульсы.

При разработке фильтра для использования на современном ПК обычно используют КИХ фильтры, как наиболее универсальные и простые в расчетах. Если взять среднюю длину КИХ фильтра в пределах десятков-сотен порядков, то для алготрейдинга с частотой дискретизации 1-2 Гц получим десятки-сотни умножения и сложений в секунду, что для современных процессоров сущий пустяк.




Алгоритм КИХ-фильтра, анализ кода Simple MA

Как я уже писал, алгоритм КИХ-фильтра предельно простой и состоит из следующих шагов:


Каждый n-тик из тикового буфера умножается на свой n-коэффициент

Все полученные значения складываются в переменной-аккумуляторе.

Для чего нужен тиковый буфер? Давайте представим структуру КИХ-фильтра, показанную на рис.*** в более понятном виде.


FIR




 Как видно, входные тики Input ticks поступают на тиковый буфер Cell0-Cell4, где при каждом такте сдвигаются вправо. При этом данные из Cell4 теряются и замещаются значениями из Cell3, а в Cell0 помещается новый тик. Далее каждая ячейка Cell-n умножается на свой коэффициент Coeff-n и все результаты складываются в Parallel accumulator. Еще раз подчеркну, этот алгоритм полностью универсальный и подходит для всех типов фильтров. Все типы и параметры КИХ-фильтра определятся исключительно его коэффициентами!

С Coeff0-Coeff4 все понятно, это обычный масcив типа double. А вот со сдвиговым массивом Cell0-Cell4 все интереснее. Мы не можем физически сдвигать данные в массиве, это слишком затратно. Поэтому будем использовать массив с кольцевой индексацией. Вот часть кода, отвечающая за размещение входного тика в массиве.


#define TICK_BUF_SIZE 0x1000      // 4096

double  m_TickBuf[TICK_BUF_SIZE]; // ring-buffer for ticks store


// filter one tick

double  FilterTick(double tick)

  {

   static double acc;

   static int tbIdx;

   acc = 0;

   tbIdx = m_TickBufIdx;

   m_TickBuf[m_TickBufIdx] = tick;

   if (m_TickBufIdx == 0)

      m_TickBufIdx = TICK_BUF_MAX_IDX;

   else

      m_TickBufIdx--;

//.... some code.....

  }

Как видно, запись идет с уменьшением индекса, "справа-налево". Точно также организован и выходной буфер, только запись идет по возрастающим индексам..


Полная функция фильтрации одного тика с определением все необходимых переменных и дефайнов:


#define TICK_BUF_SIZE       0x1000              // 4096

#define TICK_BUF_MAX_IDX    (TICK_BUF_SIZE - 1) // 0xFFF

#define OUT_BUF_SIZE        0x10000             // 65536

#define OUT_BUF_MAX_IDX     (OUT_BUF_SIZE - 1)  // 0xFFFF   


double  m_TickBuf[TICK_BUF_SIZE]; // ring-buffer for ticks store

double  m_OutBuf[OUT_BUF_SIZE];   // output ring-buffer

double  m_Coeff[];                // coefficient array

int     m_CoeffSize;              // size of m_Coeff  

int     m_TickBufIdx;             // index of new tick placed in m_TickBuf

int     m_OutBufIdx;              // index of new tick placed in m_OutBuf


//+------------------------------------------------------------------+

//| filter one tick                                                                 |

//+------------------------------------------------------------------+

double  FilterTick(double tick)

  {

   static double acc;

   static int tbIdx;

   acc=0;

   tbIdx=m_TickBufIdx;

   m_TickBuf[m_TickBufIdx]=tick;

   if(m_TickBufIdx==0)

      m_TickBufIdx=TICK_BUF_MAX_IDX;

   else

      m_TickBufIdx--;

// filter one sample in cycle "for"

   for(int n=0; n<m_CoeffSize; n++)

     {

      acc+=m_TickBuf[tbIdx++]*m_Coeff[n];

      tbIdx &=TICK_BUF_MAX_IDX; 

      /* it was little optimization instead if

      if(tbIdx > TICK_BUF_MAX_IDX)

         tbIdx = 0;*/

     }

   m_OutBuf[m_OutBufIdx++]=acc;

   m_OutBufIdx &=OUT_BUF_MAX_IDX;

   return acc;

  }








В трейдинге мы имеем дело с цифровыми данными. Входящие тиковые данные имеют параметры, описанные в структуре MqlTick:


struct MqlTick 

  { 

   datetime     time;          // Time of the last prices update 

   double       bid;           // Current Bid price 

   double       ask;           // Current Ask price 

   double       last;          // Price of the last deal (Last) 

   ulong        volume;        // Volume for the current Last price 

   long         time_msc;      // Time of a price last update in milliseconds 

   uint         flags          // Tick flags 

  };

 Входной параметр цена bid и ask квантована по уровню с заранее заданной точностью, которую можно определить как:


double point = 0;       // point value

double tickSize = 0;    // minimum step of price

if(SymbolInfoDouble(_Symbol, SYMBOL_POINT, point) && SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE, tickSize))

   Print("Point = ", DoubleToString(point, _Digits), "  Minimum step of price = ", DoubleToString(tickSize, _Digits));

else    

   Print("Can't get value(s) for SYMBOL_POINT or SYMBOL_TRADE_TICK_SIZE command identifiers");

С квантованием цены по времени немного сложнее. Хотя в структуре MqlTick минимальное время измерения одна миллисекунда, котировка инструмента в реальной торговле может прийти в любой момент времени. Поэтому нужно самостоятельно квантовать тики по времени для последующей обработки. 

И тут мы сталкиваемся с двумя различными точками зрения. Одна из них гласит, что приход очередного тика является семплом независимо от времени его прихода.  А так, как на бирже возможна ситуация, когда в один момент времени приходят два абсолютно одинаковых тика, то при таком подходе будем иметь два одинаковых семпла в одно и то же время. B что делать в таком случае?

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

Я когда-то занимался программированием звуковых трактов цифровых телевизоров. В то время стандартная частота синхронизации для звука была 48 КГц (для DVD 96 КГц). А теперь представьте себе, что она начала прыгать от нуля до 300 КГц, к примеру. Уверяю, вместо музыки вы услышите рев, шум и свист.


Другой подход основан на том, что поток данных для обработки формируется из входных тиков путем периодической выборки с заданным периодом. Опять же, приведу пример из жизни. Зашел на Google Play в поисках программы-диктофона, читаю в описании "Supported frequencies: 8000 Hz, 11025 Hz, 16000 Hz, 22050 Hz, 44100 Hz". То есть, независимо от того, будем мы говорить, петь, орать, храпеть или молчать диктофон будет монотонно оцифровывать и писать звук на заданной частоте. Скорость оцифровки не зависит от характера данных.


Так же и в MQL5. Для этих целей оптимально использовать встроенный в язык миллисекундный таймер. Этот подход напоминает оцифровку музыки, когда с определенной частотой производится выборка и оцифровка значения аналогового сигнала. Например, для  Кгц в других форматах. Надо четко понимать, что при оцифровке с заданной частотой выборка происходит вне зависимости от количества поступающих тиков в минуту. То есть при высокочастотном входном потоке мы будем пропускать некоторые данные, при низкочастотном наоборот, будем дублировать старые тики, так как новые еще не успели поступить.

 
Весело, у клиента в гугл докс все вставилось с картинками, а тут, на движке из 90-х полная *опа 
 
Alexey Volchanskiy #:
давай уж здесь. Сегодня обучал клиента MQL5, скинул ему эту старую заготовку про FIR и прочие ЦФ

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

опять-же на форуме длинные тексты читать/писать тяжело, и неудобно выискивать обрывки по форуму

лучше в блог. 

Пора-бы уже закончить эпопею про "статью про скальпер", хоть так

 
Уважаемые модераторы, я не оформлял код, просто сделал копипасте из раздела неопубликованных статей