English 中文 Español Deutsch 日本語 Português
preview
Индикатор силы и направления тренда на 3D-барах

Индикатор силы и направления тренда на 3D-барах

MetaTrader 5Трейдинг |
1 274 25
Yevgeniy Koshtenko
Yevgeniy Koshtenko

Введение

Казалось бы, что нового можно найти в привычных свечах? Всё уже открыто, посчитано, оцифровано. Но стоило взглянуть на рынок под другим углом, как он раскрылся совершенно неожиданной стороной.

Представьте, что вы смотрите на график не как на плоскую картинку, а как на живой, дышащий организм. Где каждый бар — это не просто прямоугольник с тенями, а объемная структура, пульсирующая в такт рыночному сердцебиению. Именно так родилась идея 3D-баров. Сначала это был просто эксперимент с визуализацией — хотелось как-то иначе взглянуть на привычные данные. Но чем глубже я погружался в исследования, тем отчетливее проявлялись удивительные закономерности.

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

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

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


Структура базового тензора состояния рынка

Знаете, как в детстве мы складывали кубик Рубика? Сначала кажется — полный хаос. Но стоит поймать принцип, и все грани начинают складываться в единую картину. Так же и здесь. Я начал собирать данные в трехмерную структуру — тензор. Звучит сложно, но по сути — это просто способ увидеть, как цена, объем и время влияют друг на друга.

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

Представьте, что каждая свеча — это не просто набор значений open-high-low-close, а живой организм. У него есть объем, как масса тела. Есть импульс — как движение. И есть внутренняя структура — как ДНК. Когда я начал смотреть на данные под таким углом, все встало на свои места.

В итоге получился вот такой "кубик":

  • Одна грань — классические ценовые данные
  • Вторая — объемы, но не просто количество сделок, а их внутренняя структура
  • Третья — временные циклы, которые я долго не мог поймать

Самое удивительное началось, когда я запустил первый тест этой модели. График... он буквально ожил. Там, где раньше я видел просто линии, теперь проступала четкая объемная структура. И она двигалась! Как будто пульсировала в такт каким-то внутренним ритмам рынка.

Но главное — эта структура начала показывать странные узоры. Сначала я принял их за артефакты визуализации. Но чем больше данных прогонял через модель, тем четче проступала закономерность. Эти узоры появлялись незадолго до сильных движений цены. Как будто рынок... предупреждал о своих намерениях?

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


Нормализация данных по методу Ганна

Наткнулся я на работы Ганна совершенно случайно. Листал архивные PDF'ки в поисках совсем другого материала, и вдруг зацепился взглядом за его странные графики. Квадраты, углы, какие-то спирали... Первая мысль была — очередной рыночный мистик. Но что-то заставило меня копнуть глубже. Я написал статью про методы Ганна.

И знаете что? Под всей этой геометрической мишурой скрывалась потрясающе элегантная идея нормализации данных. Ганн интуитивно нащупал то, до чего я пытался дойти математическим путем — принцип масштабной инвариантности рынка.

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

Оказалось, если правильно отмасштабировать временные интервалы, рынок начинает проявлять почти кристаллическую структуру. Как будто смотришь на снежинку под микроскопом — каждый новый масштаб показывает те же узоры, только в другом размере.

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

Это было похоже на настройку музыкального инструмента. Знаете это чувство, когда струны наконец начинают звучать в унисон? Примерно то же самое я испытал, когда увидел первые результаты. График больше не рассыпался на отдельные элементы — он начал дышать, как единое целое.

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

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


Расчет объемной компоненты тренда

Вот тут начинается самое интересное. После нормализации данных я столкнулся с неожиданной проблемой — классические объемные индикаторы просто "не видели" ключевые моменты разворота тренда. Помню, как неделю убил на попытки модифицировать OBV и MFI. Результат был... так себе.

А потом, копаясь в исходниках одного древнего индикатора (автора уже и не найти), наткнулся на интересный подход к расчету объемного профиля. Идея была простой до гениальности — смотреть не на абсолютные значения объема, а на их отношение к скользящей средней. Вот мой код:

def _calculate_components(self, df: pd.DataFrame) -> pd.DataFrame:
    # Базовые компоненты
    df['volatility'] = df['close'].pct_change().rolling(20).std()
    df['momentum'] = df['close'].pct_change(5)
    
    # Вот оно, ключевое место - объемный профиль
    df['volume_ma'] = df['tick_volume'].rolling(20).mean()
    df['volume_trend'] = df['tick_volume'] / df['volume_ma']
    
    # Сила тренда как производная трех компонент
    df['trend_force'] = df['volatility'] * df['volume_trend'] * abs(df['momentum'])

Смотрите, что тут происходит. Вместо того, чтобы просто суммировать объемы, мы создаем что-то вроде "объемного ускорения". Когда объем резко возрастает относительно своей средней — это первый звоночек. Но самое интересное начинается, когда мы накладываем на это волатильность и моментум.

Я перепробовал кучу периодов для скользящих средних. 10, 15, 25... В итоге, именно 20 баров дали наилучший баланс между чувствительностью и стабильностью сигналов. 

Но настоящий "вау-эффект" случился, когда я добавил коэффициент торговых сессий:

# Коэффициенты активности разных сессий
df['session_coef'] = 1.0
hour = df.index.hour
        
df.loc[(hour >= 0) & (hour < 8), 'session_coef'] = 0.7    # Азиатская
df.loc[(hour >= 8) & (hour < 16), 'session_coef'] = 1.0   # Европейская
df.loc[(hour >= 16) & (hour < 24), 'session_coef'] = 0.9  # Американская

График буквально ожил. Теперь каждый всплеск объема рассматривался в контексте текущей торговой сессии. Знаете, как в природе есть приливы и отливы? Так и тут — каждая сессия имеет свой характер, свою "силу притяжения".

Но самое важное — эта формула начала показывать то, что я назвал "предвестниками". За несколько баров до сильного движения объемный профиль начинал формировать характерный паттерн. Как будто рынок "набирает дыхание" перед прыжком.

А дальше встал вопрос, как все это правильно визуализировать...


Ценовая динамика в трехмерном пространстве

Мне потребовалось немало времени, чтобы найти правильный способ визуализации всего этого безумия. Первые попытки построить 3D-график в MatPlotLib больше напоминали новогоднюю елку, нежели что-то полезное для трейдинга. Plotly тоже не сразу поддался — графики получались либо слишком загруженными, либо упускали важные детали.

И тут мне помог случай. Играл с дочкой в конструктор, строили что-то типа моста, и вдруг понял — нам не нужна вся эта навороченная 3D-графика. Достаточно правильно расположить проекции! Вот что у меня получилось:

def create_visualization(self, df: pd.DataFrame = None):
    if df is None:
        df = self.analyze_market()
    
    df = df.reset_index()
            
    # Три проекции нашего "моста"
    fig = make_subplots(rows=3, cols=1, 
                       shared_xaxes=True,
                       subplot_titles=('Price', 'Trend Force', 'Trend Direction'),
                       row_heights=[0.5, 0.25, 0.25],
                       vertical_spacing=0.05)

    # Основной график - классические свечи
    fig.add_trace(
        go.Candlestick(
            x=df['time'],
            open=df['open'],
            high=df['high'],
            low=df['low'],
            close=df['close'],
            name='OHLC'
        ),
        row=1, col=1
    )

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

# Сила тренда - наша основная фишка
    fig.add_trace(
        go.Scatter(
            x=df['time'],
            y=df['trend_force_adjusted'],
            mode='lines',
            line=dict(color='blue', width=2),
            name='Trend Force'
        ),
        row=2, col=1
    )

    # Опорные уровни
    fig.add_hline(y=3, line_dash="dash", line_color="yellow", row=2, col=1)
    fig.add_hline(y=6, line_dash="dash", line_color="green", row=2, col=1)

Эти уровни (3 и 6) я нащупал эмпирическим путем. Когда сила тренда пробивает уровень 6, это почти всегда означает сильное движение. Уровень 3 — что-то вроде зоны турбулентности, где тренд может как усилиться, так и развернуться.

Но настоящая магия происходит в нижнем окне:

# Направление тренда как производная силы
    fig.add_trace(
        go.Bar(
            x=df['time'],
            y=df['trend_direction'] * df['trend_force_adjusted'],
            name='Trend Direction',
            marker_color=np.where(df['trend_direction'] > 0, 'green', 'red')
        ),
        row=3, col=1
    )

Здесь мы видим не просто направление тренда, а его силу в динамике. Когда зеленые столбики растут на фоне высокого значения Trend Force — это мощный сигнал к покупке. И наоборот, растущие красные на фоне силы выше 6 — верный знак продавать.

Но вернемся к земле. После визуализации встал вопрос о временных циклах...


Временная составляющая и торговые сессии

Знаете, что меня всегда удивляло в классическом техническом анализе? То, как легко все забывают о времени. Да-да, о банальном времени! Смотрят на графики, считают индикаторы, но упускают простой факт — рынок живет в разных часовых поясах.

Первый звоночек прозвенел, когда я заметил странную закономерность — мои сигналы работали намного лучше в европейскую сессию. Сначала списал на случайность. Но потом начал копать глубже, и вот что обнаружил:

# Смотрите, как просто оказалось учесть влияние сессий
hour = df.index.hour

# Азиатская сессия - самая спокойная
asian_mask = (hour >= 0) & (hour < 8)
df.loc[asian_mask, 'session_coef'] = 0.7    

# Европа - пик активности
european_mask = (hour >= 8) & (hour < 16)
df.loc[european_mask, 'session_coef'] = 1.0  

# Америка - всё ещё активно, но уже не так сильно
american_mask = (hour >= 16) & (hour < 24)
df.loc[american_mask, 'session_coef'] = 0.9

Эти коэффициенты я подобрал буквально на коленке, тестируя разные варианты. Помню, как целую ночь просидел, гоняя бэктесты с разными значениями. Жена уже спать звала, а я всё никак не мог оторваться от монитора — настолько захватывающие результаты получались.

Но самое интересное началось, когда я наложил эти коэффициенты на объемный профиль. Внезапно всё встало на свои места! Оказалось, что один и тот же объем в разные сессии имеет совершенно разный "вес":

  • В азиатскую сессию даже небольшой всплеск объема может быть значимым
  • В европейскую нужны гораздо более существенные отклонения
  • А на стыке сессий происходит что-то совсем интересное...

Но настоящий прорыв случился, когда я добавил еще один компонент — "межсессионные переходы". Заметил, что за 30-40 минут до открытия новой сессии индикатор начинает вести себя... странно. Как будто рынок готовится к приходу новых игроков. И вот тут-то...


Интегральный показатель силы тренда

Иногда самые важные открытия происходят из-за досадных ошибок. В моем случае всё началось с бага в коде. Я случайно перемножил не те переменные, и график показал какую-то дикую аномалию. Первым порывом было всё переписать, но что-то заставило меня присмотреться внимательнее...

Оказалось, я случайно создал то, что потом назвал "интегральным показателем". Смотрите:

def _calculate_components(self, df: pd.DataFrame) -> pd.DataFrame:
    # Вот она, та самая "ошибка" - перемножение трех компонент
    df['trend_force'] = df['volatility'] * df['volume_trend'] * abs(df['momentum'])
    
    # Нормализация результата в диапазон от 3 до 9
    df['trend_force_norm'] = self.scaler.fit_transform(
        df['trend_force'].values.reshape(-1, 1)
    ).flatten()
    
    # Финальная корректировка с учетом сессий
    df['trend_force_adjusted'] = df['trend_force_norm'] * df['session_coef']

Знаете, что тут происходит? Волатильность умножается на объемный тренд и абсолютное значение моментума. В теории это должно было дать полный хаос. А на практике... На практике получился удивительно чёткий индикатор силы тренда!

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

Самое интересное началось, когда я добавил нормализацию через MinMaxScaler. Диапазон от 3 до 9 выбрал почти наугад — просто показалось, что так график будет читаться удобнее. И внезапно обнаружил, что эти числа создают почти идеальные уровни для принятия решений:

  • Ниже 3 — рынок "спит"
  • От 3 до 6 — начинается движение
  • Выше 6 — тренд набрал полную силу

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

Но главное открытие ждало впереди. Оказалось, что этот показатель не просто измеряет силу тренда — он способен предсказывать развороты...


Определение направления будущего движения

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

И вот однажды ночью (почему все важные открытия случаются именно ночью?) я заметил странную закономерность. Перед сильными разворотами тренда показатель силы начинал... нет, не падать, как можно было бы подумать. Он начинал колебаться особым образом:

# Определение направления тренда
df['trend_direction'] = np.sign(df['momentum'])

# Тут магия и начинается
df['direction_strength'] = df['trend_direction'] * df['trend_force_adjusted']

# Ищем паттерны разворота
df['reversal_pattern'] = np.where(
    (df['trend_force_adjusted'] > 6) &  # Сильный тренд
    (df['direction_strength'].diff().rolling(3).std() > 1.5),  # Нестабильность направления
    1, 0
)

Смотрите, что происходит: когда сила тренда превышает уровень 6 (помните нашу нормализацию?), но при этом направление становится нестабильным, — это почти всегда предвещает разворот!

Я потратил две недели, перепроверяя это наблюдение на разных таймфреймах и инструментах. Работало везде, но особенно четко на H1 и H4. Как будто именно на этих таймфреймах рынок "думает" наиболее рационально.

Но настоящий инсайт пришел, когда я наложил на это объемный профиль:

df['volume_confirmation'] = np.where(
    (df['reversal_pattern'] == 1) &
    (df['volume_trend'] > df['volume_trend'].rolling(20).mean() * 1.5),
    'Strong',
    'Weak'
)

И тут всё встало на свои места! Оказалось, что не все развороты одинаковы. Когда паттерн совпадает с сильным превышением объема над средним — это почти гарантированный разворот. А если объем не поддерживает — скорее всего, просто коррекция.

Помню, как показал эти результаты своему бывшему преподавателю по статистике. Он долго вглядывался в формулы, потом поднял на меня глаза и спросил: "А вы проверяли это на данных до 2020 года?" Я кивнул. "И после?" Снова кивнул. "Хм... Знаете, в этом что-то есть. Это противоречит случайному блужданию, но... чертовски похоже на правду!"

Конечно, без ложных срабатываний не обходилось. Но для этого у меня уже была готова система фильтрации...


Визуализация сигналов на графике

Когда все компоненты индикатора были готовы, встал вопрос — как показать это трейдеру? Не каждый же будет разбираться в формулах и таблицах. Намучался я с этим знатно, пока не пришла идея с трехуровневой визуализацией.

Первые попытки в чистом MatPlotLib были... скажем так, не очень. Глаза сломаешь, пока поймешь, где сигнал. Перепробовал с десяток библиотек, пока не остановился на Plotly. Вот что в итоге получилось:

def create_visualization(self, df: pd.DataFrame = None):
    if df is None:
        df = self.analyze_market()
    
    fig = make_subplots(rows=3, cols=1, 
                       shared_xaxes=True,
                       subplot_titles=('Price', 'Trend Force', 'Trend Direction'),
                       row_heights=[0.5, 0.25, 0.25],
                       vertical_spacing=0.05)

    # Основной график - свечи с подсветкой сигналов
    fig.add_trace(
        go.Candlestick(
            x=df['time'],
            open=df['open'],
            high=df['high'],
            low=df['low'],
            close=df['close'],
            name='OHLC',
            hoverlabel=dict(
                bgcolor='white',
                font=dict(size=12)
            )
        ),
        row=1, col=1
    )

Но главная фишка — в интерактивности. Навел курсор на свечу — сразу видишь все параметры: и силу тренда, и объемы, и направление. А цветовая схема... Тут я неделю подбирал оттенки, чтобы глаза не уставали:

fig.add_trace(
        go.Scatter(
            x=df['time'],
            y=df['trend_force_adjusted'],
            mode='lines',
            line=dict(color='blue', width=2),
            name='Trend Force',
            hovertemplate="<br>".join([
                "Time: %{x}",
                "Force: %{y:.2f}",
                "<extra></extra>"
            ])
        ),
        row=2, col=1
    )

Отдельная история — визуализация направления тренда. Сделал её в виде баров, где высота показывает силу, а цвет — направление:

fig.add_trace(
        go.Bar(
            x=df['time'],
            y=df['trend_direction'] * df['trend_force_adjusted'],
            name='Trend Direction',
            marker_color=np.where(df['trend_direction'] > 0, 'green', 'red'),
        ),
        row=3, col=1
    )

Помню реакцию своего друга-трейдера, когда показал ему финальную версию. Он минут пять молча щелкал по графику, потом говорит: "Слушай, а ведь теперь даже новичок разберется, куда рынок идет!"

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


Пробуем к реализации индикатор силы тренда в MetaTrader 5

После успехов с Python-версией индикатора встал логичный вопрос — как перенести это в MetaTrader 5?

Задача оказалась... интересной. MQL5, конечно, мощный язык, но без pandas и numpy пришлось изрядно поизворачиваться. Вот что у меня получилось:

//+------------------------------------------------------------------+
//|                                          TrendForceIndicator.mq5 |
//+------------------------------------------------------------------+
#property copyright "Your Name"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   3

// Буферы для отрисовки
double TrendForceBuffer[];
double DirectionBuffer[];
double SignalBuffer[];

// Входные параметры
input int    InpMAPeriod = 20;     // Период сглаживания
input int    InpMomentumPeriod = 5; // Период для моментума
input double InpSignalLevel = 6.0;  // Уровень сигнала

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
    // Настройка индикатора
    SetIndexBuffer(0, TrendForceBuffer, INDICATOR_DATA);
    SetIndexBuffer(1, DirectionBuffer, INDICATOR_DATA);
    SetIndexBuffer(2, SignalBuffer, INDICATOR_DATA);
    
    // Стили отрисовки
    PlotIndexSetString(0, PLOT_LABEL, "Trend Force");
    PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE);
    PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrBlue);
    
    PlotIndexSetString(1, PLOT_LABEL, "Direction");
    PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_HISTOGRAM);
    
    PlotIndexSetString(2, PLOT_LABEL, "Signal");
    PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_LINE);
    PlotIndexSetInteger(2, PLOT_LINE_COLOR, clrRed);
    
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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 &tick_volume[],
                const long &volume[],
                const int &spread[])
{
    // Проверка на достаточность данных
    if(rates_total < InpMAPeriod) return(0);
    
    // Расчет компонентов
    int start = (prev_calculated > 0) ? prev_calculated - 1 : 0;
    
    for(int i = start; i < rates_total; i++)
    {
        // Волатильность
        double volatility = 0.0;
        if(i >= InpMAPeriod)
        {
            double sum = 0.0;
            for(int j = 0; j < InpMAPeriod; j++)
            {
                double change = (close[i-j] - close[i-j-1]) / close[i-j-1];
                sum += change * change;
            }
            volatility = MathSqrt(sum / InpMAPeriod);
        }
        
        // Моментум
        double momentum = 0.0;
        if(i >= InpMomentumPeriod)
        {
            momentum = (close[i] - close[i-InpMomentumPeriod]) / close[i-InpMomentumPeriod];
        }
        
        // Объемный тренд
        double volume_ma = 0.0;
        if(i >= InpMAPeriod)
        {
            for(int j = 0; j < InpMAPeriod; j++)
            {
                volume_ma += tick_volume[i-j];
            }
            volume_ma /= InpMAPeriod;
        }
        
        double volume_trend = volume_ma != 0 ? (double)tick_volume[i] / volume_ma : 0;
        
        // Сессионный коэффициент
        MqlDateTime dt;
        TimeToStruct(time[i], dt);
        double session_coef = GetSessionCoefficient(dt.hour);
        
        // Расчет силы тренда
        TrendForceBuffer[i] = NormalizeTrendForce(volatility * MathAbs(momentum) * volume_trend) * session_coef;
        DirectionBuffer[i] = momentum > 0 ? TrendForceBuffer[i] : -TrendForceBuffer[i];
        
        // Сигнальная линия
        SignalBuffer[i] = InpSignalLevel;
    }
    
    return(rates_total);
}

//+------------------------------------------------------------------+
//| Получение коэффициента сессии                                    |
//+------------------------------------------------------------------+
double GetSessionCoefficient(int hour)
{
    if(hour >= 0 && hour < 8)   return 0.7;  // Азиатская сессия
    if(hour >= 8 && hour < 16)  return 1.0;  // Европейская сессия
    if(hour >= 16 && hour < 24) return 0.9;  // Американская сессия
    return 1.0;
}

//+------------------------------------------------------------------+
//| Нормализация показателя силы тренда                              |
//+------------------------------------------------------------------+
double NormalizeTrendForce(double force)
{
    // Простая нормализация в диапазон [3, 9]
    double max_force = 0.01;  // Подобрано эмпирически
    return 3.0 + 6.0 * (MathMin(force, max_force) / max_force);
}

Самым сложным было воспроизвести поведение pandas rolling windows. В MQL5 всё приходится считать циклами, зато производительность выше — индикатор работает заметно быстрее Python-версии.


Заключение

В конце этого долгого исследования хочется поделиться несколькими важными наблюдениями. Перенос алгоритма с Python на MQL5 открыл неожиданные возможности для оптимизации. То, что изначально казалось недостатком (отсутствие привычных библиотек), превратилось в преимущество — код стал работать быстрее и эффективнее.

Самым сложным было найти баланс между точностью сигналов и скоростью работы индикатора. Каждый дополнительный параметр, каждая новая проверка — это дополнительная нагрузка на систему. Но в итоге удалось достичь оптимального соотношения: индикатор обрабатывает тиковые данные практически в реальном времени, при этом сохраняя высокую точность сигналов.

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

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

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

И самое главное — я убедился, что даже в таком, казалось бы, досконально изученном инструментарии, как технический анализ, всегда есть место для инноваций. Нужно только не бояться смотреть на привычные вещи под новым углом и быть готовым к неожиданным открытиям.

Прикрепленные файлы |
Последние комментарии | Перейти к обсуждению на форуме трейдеров (25)
Bogard_11
Bogard_11 | 11 янв. 2025 в 17:10
Vitaly Muzichenko #:

Зато вам очень помогает, и всем остальным гуру-трейдинга.

Вот тут мы входим, а тут выходим и зарабатываем 100500пп с каждого трейда, и так в течении всего прошлого периода.

Знаете в чем проблема всех кодеров? Они забыли как ищутся закономерности.

У всех всё по шаблону - сейчас мы загоним в код какую то идею, и машина нам найдет Грааль! И так 100500 раз по кругу. ))

А взять и проверить ручками, посчитать на калькуляторе... Не, не барское это дело, в дырке ковыряться... ))

Поэтому вы и не понимаете, что рынок ходит по обычным законам физики - угол падения равен углу отражения. Граальная система описана 100 лет назад. Как работала так и работает. Но чтобы её понять, нужно потратить приличное кол-во времени работы с историей, для поиска всех математических связей. И особенно перестроением своего мышления.

Даже первый импульс в себе несет информацию о будущих уровнях разворота. Погрешность на фунте обычно не более 2-5 пунктов.

Vitaly Muzichenko
Vitaly Muzichenko | 11 янв. 2025 в 17:23
Bogard_11 #:

Знаете в чем проблема всех кодеров? Они забыли как ищутся закономерности.

У всех всё по шаблону - сейчас мы загоним в код какую то идею, и машина нам найдет Грааль! И так 100500 раз по кругу. ))

А взять и проверить ручками, посчитать на калькуляторе... Не, не барское это дело, в дырке ковыряться... ))

Поэтому вы и не понимаете, что рынок ходит по обычным законам физики - угол падения равен углу отражения. Граальная система описана 100 лет назад. Как работала так и работает. Но чтобы её понять, нужно потратить приличное кол-во времени работы с историей, для поиска всех математических связей. И особенно перестроением своего мышления.

Даже первый импульс в себе несет информацию о будущих уровнях разворота. Погрешность на фунте обычно не более 2-5 пунктов.

Через кодинг проходит несколько сотен различных систем от разных пользователей, ты их тестируешь и видишь все недостатки и преимущества.

Это не вручную ковырять, пропуская некоторые закономерности. Машина никогда и ничего не упустит, в этом её преимущество.

А то, что работало 100 лет назад, перестало работать с усовершенствованием технологий.

Вы можете представить, как-бы раньше пипсовали, когда сделки совершались в телефонном режиме или телеграммой к брокеру?

Bogard_11
Bogard_11 | 11 янв. 2025 в 18:20
Vitaly Muzichenko #:

А то, что работало 100 лет назад, перестало работать с усовершенствованием технологий.

А поподробнее можно, почему перестало работать? Кто-то из брокеров или маркетмейкеров отменил законы физики и математики?!

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

Bogard_11
Bogard_11 | 11 янв. 2025 в 18:29
Vitaly Muzichenko #:

Через кодинг проходит несколько сотен различных систем от разных пользователей, ты их тестируешь и видишь все недостатки и преимущества.

Это не вручную ковырять, пропуская некоторые закономерности. Машина никогда и ничего не упустит, в этом её преимущество.

Чтобы что-то закодить правильно, надо сначала ручками найти ВСЕ закономерности. Машина может и не ошибается, только вот будет искать только то, что вы в неё заложили, т.е. то что вы без машины нашли самостоятельно! Меня иногда поражает фанатичная вера в способности ИИ!! )))

Вы закодили на поиск в тексте букв А, Б и В. Т.к. вы их или нашли случайно, или вам кто-то подсказал. НО! В алфавите есть и другие буквы, а вы про них не знаете... Что вам выдаст машина?

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

imcapec
imcapec | 27 янв. 2025 в 12:09
Bogard_11 #:

Чтобы что-то закодить правильно, надо сначала ручками найти ВСЕ закономерности. Машина может и не ошибается, только вот будет искать только то, что вы в неё заложили, т.е. то что вы без машины нашли самостоятельно! Меня иногда поражает фанатичная вера в способности ИИ!! )))

Вы закодили на поиск в тексте букв А, Б и В. Т.к. вы их или нашли случайно, или вам кто-то подсказал. НО! В алфавите есть и другие буквы, а вы про них не знаете... Что вам выдаст машина?

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

Числовой ряд не меняется. меняются запятые в нем.

Алгоритм Большого взрыва и Большого сжатия — BBBC (Big Bang - Big Crunch) Алгоритм Большого взрыва и Большого сжатия — BBBC (Big Bang - Big Crunch)
В статье представлен метод Big Bang - Big Crunch, который имеет две ключевые фазы: циклическое создание случайных точек и их сжатие к оптимальному решению. Этот подход сочетает исследование и уточнение, позволяя постепенно находить лучшие решения и открывая новые возможности в области оптимизации.
Возможности Мастера MQL5, которые вам нужно знать (Часть 27): Скользящие средние и угол атаки Возможности Мастера MQL5, которые вам нужно знать (Часть 27): Скользящие средние и угол атаки
Угол атаки (Angle of Attack) — популярный показатель, значение крутизны (steepness) которого, как считается, тесно связано с силой преобладающего тренда. Мы рассмотрим, как он обычно трактуется и применяется, и выясним, есть ли изменения, которые можно было бы внести в способ его измерения для улучшения торговой системы.
Нейросети в трейдинге: Мультимодальный агент, дополненный инструментами (FinAgent) Нейросети в трейдинге: Мультимодальный агент, дополненный инструментами (FinAgent)
Предлагаем познакомиться с фреймворком мультимодального агента для финансовой торговли FinAgent, который предназначен для анализа данных разных типов, отражающих рыночную динамику и исторические торговые паттерны.
Нейросети в трейдинге: Агент с многоуровневой памятью (Окончание) Нейросети в трейдинге: Агент с многоуровневой памятью (Окончание)
Продолжаем начатую работу по созданию фреймворка FinMem, который использует подходы многоуровневой памяти, имитирующие когнитивные процессы человека. Это позволяет модели не только эффективно обрабатывать сложные финансовые данные, но и адаптироваться к новым сигналам, значительно повышая точность и результативность инвестиционных решений в условиях динамично изменяющихся рынков.