Кодирование известной торговой стратегии на Python.
Технические стратегии есть во всем Интернете. 99,99% из них не работают или работают всего несколько недель. К сожалению, рынки постоянно меняются, и большинство стратегий устаревают. Даже стратегии, которые я использовал в прошлом, были изменены, чтобы соответствовать текущим условиям. В этой статье обсуждается и тестируется известная стратегия, найденная в Интернете, которая использует RSI и стохастический осциллятор.
Я только что выпустил новую книгу после успеха предыдущей книги. Он содержит расширенные индикаторы и стратегии следования за трендом, а также страницу GitHub, посвященную постоянно обновляемому коду. Кроме того, в этой книге представлены оригинальные цвета после оптимизации затрат на печать. Если вы чувствуете, что это вас интересует, не стесняйтесь посетить приведенную ниже ссылку Amazon, или, если вы предпочитаете купить версию в формате PDF, вы можете связаться со мной на LinkedIn.
Стохастический осциллятор
Стохастический осцилляторищет зоны перепроданности и перекупленности, включая максимумы и минимумы, используя формулу нормализации, как показано ниже:
Уровень перекупленности — это область, в которой рынок воспринимается как крайне бычий и обязательно консолидируется. Уровень перепроданности — это область, в которой рынок воспринимается как крайне медвежий и обязательно отскочит. Следовательно, стохастический осциллятор является противоположным индикатором, который стремится сигнализировать о реакции экстремальных движений.
def stochastic_oscillator(data, lookback, high, low, close, where, slowing = False, smoothing = False, slowing_period = 1, smoothing_period = 1): data = adder(data, 1) for i in range(len(data)): try: data[i, where] = (data[i, close] - min(data[i - lookback + 1:i + 1, low])) / (max(data[i - lookback + 1:i + 1, high]) - min(data[i - lookback + 1:i + 1, low])) except ValueError: pass data[:, where] = data[:, where] * 100 if slowing == True and smoothing == False: data = ma(data, slowing_period, where, where + 1) if smoothing == True and slowing == False: data = ma(data, smoothing_period, where, where + 1) if smoothing == True and slowing == True: data = ma(data, slowing_period, where, where + 1) data = ma(data, smoothing_period, where, where + 2) data = jump(data, lookback) return data
Индекс относительной силы
Впервые представленный Дж. Уэллсом Уайлдером-младшим, RSI является одним из самых популярных и универсальных технических индикаторов. В основном используется как противоположный индикатор, где экстремальные значения сигнализируют о реакции, которую можно использовать. Как правило, мы используем следующие шаги для расчета RSI по умолчанию:
- Рассчитайте изменение цен закрытия по сравнению с предыдущими.
- Отделите положительные чистые изменения от отрицательных чистых изменений.
- Вычислите сглаженное скользящее среднее положительных чистых изменений и абсолютных значений отрицательных чистых изменений.
- Разделите сглаженные положительные изменения на сглаженные отрицательные изменения. Мы будем называть этот расчет Относительной Силой — RS.
- Примените формулу нормализации, показанную ниже, для каждого временного шага, чтобы получить RSI.
На приведенном выше графике часовые значения GBPUSD показаны черным цветом с 13-периодным RSI. В целом мы можем отметить, что RSI имеет тенденцию отскакивать близко к 25, в то время как он имеет тенденцию останавливаться около 75. Чтобы закодировать RSI в Python, нам нужен массив OHLC, состоящий из четырех столбцов, которые охватывают цены открытия, максимума, минимума и закрытия.
def adder(data, times): for i in range(1, times + 1): new = np.zeros((len(data), 1), dtype = float) data = np.append(data, new, axis = 1) return data def deleter(data, index, times): for i in range(1, times + 1): data = np.delete(data, index, axis = 1) return data def jump(data, jump): data = data[jump:, ] return data def ma(data, lookback, close, where): data = adder(data, 1) for i in range(len(data)): try: data[i, where] = (data[i - lookback + 1:i + 1, close].mean()) except IndexError: pass data = jump(data, lookback) return data def ema(data, alpha, lookback, what, where): alpha = alpha / (lookback + 1.0) beta = 1 - alpha data = ma(data, lookback, what, where) data[lookback + 1, where] = (data[lookback + 1, what] * alpha) + (data[lookback, where] * beta) for i in range(lookback + 2, len(data)): try: data[i, where] = (data[i, what] * alpha) + (data[i - 1, where] * beta) except IndexError: pass return data def rsi(data, lookback, close, where): data = adder(data, 5) for i in range(len(data)): data[i, where] = data[i, close] - data[i - 1, close] for i in range(len(data)): if data[i, where] > 0: data[i, where + 1] = data[i, where] elif data[i, where] < 0: data[i, where + 2] = abs(data[i, where]) lookback = (lookback * 2) - 1 # From exponential to smoothed data = ema(data, 2, lookback, where + 1, where + 3) data = ema(data, 2, lookback, where + 2, where + 4) data[:, where + 5] = data[:, where + 3] / data[:, where + 4] data[:, where + 6] = (100 - (100 / (1 + data[:, where + 5]))) data = deleter(data, where, 6) data = jump(data, lookback) return data
Если вас также интересуют более технические индикаторы и стратегии, то моя книга может вас заинтересовать:
Создание и обратное тестирование стратегии
Стратегия состоит из трех индикаторов:
- Индекс относительной силы за 14 периодов.
- 14-периодный стохастический осциллятор с замедлением и сглаживанием на уровне 5.
- Экспоненциальная скользящая средняя с периодом 200.
Давайте быстро обсудим скользящие средние, прежде чем перейти к определению правил стратегии и ее тестированию на исторических данных.
Скользящие средние помогают нам подтверждать тренд и управлять им. Они являются наиболее известными техническими индикаторами, и это из-за их простоты и проверенного опыта повышения ценности анализа. Мы можем использовать их, чтобы найти уровни поддержки и сопротивления, стопы и цели, а также понять основной тренд. Эта универсальность делает их незаменимым инструментом в нашем торговом арсенале.
Код для экспоненциального скользящего среднего, который является взвешенным типом, можно записать следующим образом:
def ema(data, alpha, lookback, what, where): alpha = alpha / (lookback + 1.0) beta = 1 - alpha data = ma(data, lookback, what, where) data[lookback + 1, where] = (data[lookback + 1, what] * alpha) + (data[lookback, where] * beta) for i in range(lookback + 2, len(data)): try: data[i, where] = (data[i, what] * alpha) + (data[i - 1, where] * beta) except IndexError: pass return data
Условия стратегии следующие:
- Покупка (покупка) всякий раз, когда на RSI появляется скрытая бычья дивергенция, которая будет первым триггером. Затем мы будем искать положительное пересечение между стохастическим осциллятором и его скользящей средней (коэффициент сглаживания). Наконец, все это должно быть сделано, пока рынок находится выше своей экспоненциальной скользящей средней с периодом 200.
- Короткая продажа (продажа) всякий раз, когда на RSI появляется медвежья скрытая дивергенция, которая будет первым триггером. Затем мы будем искать отрицательное пересечение между стохастическим осциллятором и его скользящей средней (коэффициент сглаживания). Наконец, все это должно быть сделано, пока рынок находится ниже экспоненциальной скользящей средней с периодом 200.
Что такое скрытая дивергенция? Естественно, когда цены растут и формируют новые вершины, в то время как основанный на цене индикатор формирует более низкие вершины, происходит ослабление, и может появиться возможность изменить уклон с длинной позиции на короткую. Это то, что мы называем нормальной дивергенцией. Мы знаем это:
- Когда цены достигают более высоких максимумов, а индикатор показывает более низкие максимумы, это называется медвежьей дивергенцией, и рынок может остановиться.
- Когда цены формируют более низкие минимумы, а индикатор показывает более высокие минимумы, это называется бычьей дивергенцией, и рынок может показать некоторый потенциал роста.
Скрытое расхождение можно рассматривать как зеркальное отражение нормального расхождения. Вот как:
- Когда цены делают более низкие максимумы, а индикатор показывает более высокие максимумы, это называется скрытой медвежьей дивергенцией, и рынок может остановиться и продолжить снижение.
- Когда цены формируют более высокие минимумы, в то время как индикатор показывает более низкие минимумы, это называется бычьей скрытой дивергенцией, и рынок может показать некоторый потенциал роста.
А что такое положительный и отрицательный крест? Всякий раз, когда стохастический осциллятор превосходит свою 5-периодную скользящую среднюю, происходит положительное пересечение, что является бычьим сигналом, и всякий раз, когда стохастический осциллятор пробивает свою 5-периодную скользящую среднюю, происходит отрицательное пересечение, что является медвежьим сигналом.
Ниже приведен код сигналов стратегии.
def hidden_divergence(data, close, rsi_col, width, buy, sell): data = adder(data, 10) for i in range(len(data)): try: if data[i, rsi_col] < 50 and data[i - 1, rsi_col] > 50: for a in range(i + 1, i + width): if data[a, rsi_col] > 50: for r in range(a + 1, a + width): if data[r, rsi_col] < 50 and \ data[r, rsi_col] < data[i, rsi_col] and data[r, close] > data[i, close]: data[r, buy] = 1 break else: break else: break except IndexError: pass for i in range(len(data)): try: if data[i, rsi_col] > 50 and data[i - 1, rsi_col] < 50: for a in range(i + 1, i + width): if data[a, rsi_col] < 50: for r in range(a + 1, a + width): if data[r, rsi_col] > 50 and \ data[r, rsi_col] > data[i, rsi_col] and data[r, close] < data[i, close]: data[r, sell] = -1 break else: break else: break except IndexError: pass return data my_data = hidden_divergence(my_data, 3, 5, 60, 8, 9) for i in range(len(my_data)): if my_data[i, 8] == 1: for a in range(i + 1, i + 50): try: if my_data[a, 6] > my_data[a, 7] and my_data[a - 1, 6] < my_data[a - 1, 7] and my_data[a, 3] > my_data[a, 4]: my_data[a, 10] = 1 break except IndexError: pass if my_data[i, 9] == -1: for a in range(i + 1, i + 50): try: if my_data[a, 6] < my_data[a, 7] and my_data[a - 1, 6] > my_data[a - 1, 7] and my_data[a, 3] < my_data[a, 4]: my_data[a, 11] = -1 break except IndexError: pass
Давайте посмотрим на пример сигналов, наложенных на графики. Имейте в виду, что субъективная интерпретация стратегии очень затрудняет осмысленное ретроспективное тестирование, особенно потому, что наш разум иногда предпочитает не учитывать определенные расхождения.
И, наконец, давайте протестируем эту стратегию, используя простые условия:
- Отсутствие управления рисками. Мы будем открывать и закрывать на основе следующего сигнала.
- Проверенный актив — USDJPY.
- Купля-продажа близка к завершению.
Наш вывод об этой стратегии заключается в том, что сигналы могут быть довольно редкими, но у этой стратегии следования за трендом есть потенциал.
Если вы хотите получать больше статей о торговых стратегиях, рассмотрите возможность подписки на мой ЕЖЕДНЕВНЫЙ информационный бюллетень (доступен бесплатныйплан) по ссылке ниже. В нем представлены мои статьи на Medium, другие торговые стратегии, уроки кодирования, связанные с исследованиями и анализом, а также подписчики получают бесплатную копию моей первой книги в формате PDF. Вы можете ожидать 5–7 статей в неделю с платной подпиской и 1–2 статей в неделю с бесплатным планом. Это помогло бы мне продолжить делиться своими исследованиями. Спасибо!
Не забывайте всегда проводить бэк-тесты. Вы всегда должны верить, что другие люди неправы. Мои индикаторы и стиль торговли могут подойти мне, но не вам.
Я твердо верю в то, что нельзя кормить с ложечки. Я учился, делая, а не копируя. Вы должны получить идею, функцию, интуицию, условия стратегии, а затем разработать (даже лучше) ее самостоятельно, чтобы протестировать и улучшить ее, прежде чем принимать решение о ее реализации или ликвидации. Мой выбор не предоставлять конкретные результаты обратного тестирования должен побудить читателя глубже изучить стратегию и больше работать над ней.
Последнее слово
Недавно я начал сбор NFT, который направлен на поддержку различных гуманитарных и медицинских целей. Общество Света — это набор ограниченных предметов коллекционирования, которые помогут сделать мир немного лучше, поскольку при каждой продаже процент от этого будет отправлен непосредственно на благотворительность, связанную с аватаром. Как я всегда говорю, нет ничего лучше, чем маркированный список, чтобы обозначить преимущества покупки этих NFT:
- Высокая потенциальная выгода: концентрируя оставшиеся средства от продаж на маркетинге и продвижении Общества Света, я стремлюсь максимально увеличить их ценность на вторичном рынке. рынок. Помните, что торговля на вторичном рынке также означает, что часть роялти будет передана той же благотворительной организации.
- Коллекция произведений искусства и диверсификация портфолио. Иметь коллекцию аватаров, символизирующих добрые дела, очень приятно. Инвестирование не обязательно должно быть связано только с эгоистичными потребностями, хотя нет ничего плохого в том, чтобы инвестировать, чтобы заработать деньги. Но как насчет того, чтобы инвестировать, зарабатывая деньги, помогая другим и собирая произведения искусства?
- Пожертвования на предпочитаемые цели. Это гибкий способ выделения различных средств на ваши благотворительные цели.
- Бесплатная копия моей книги в формате PDF: любой покупатель любого NFT получит бесплатную копию моей последней книги, указанной в ссылке на статью.