Привет, Хабр!
Осцилляторы — это технические индикаторы, которые колеблются в пределах заданного диапазона, обычно от 0 до 100, и используются для определения состояния перекупленности или перепроданности рынка.
Осцилляторы способны предсказывать возможные изменения трендов до того, как эти изменения произойдут.
Принцип работы осцилляторов основан на сравнении текущей цены актива с его ценовыми уровнями за определенный период. Например, если текущая цена находится близко к верхнему диапазону за последний период, осциллятор покажет высокие значения, указывая на перекупленность. И наоборот, если цена находится близко к нижнему диапазону, это указывает на перепроданность.
Осцилляторы могут использоваться в различных рыночных условиях, включая трендовые и боковые рынки. В трендовых рынках осцилляторы помогают находить точки входа в направлении основного тренда, а в боковых — выявлять моменты разворота.
Relative Strength Index (RSI)
RSI был разработан Дж. Уэллсом Уайлдером и представлен в его книге "New Concepts in Technical Trading Systems" в 1978 году. RSI является осциллятором, который измеряет скорость и изменение ценовых движений актива, оценивая условия его перекупленности или перепроданности. Он колеблется между значениями от 0 до 100 и помогает трейдерам определять моменты для покупки или продажи активов.
Расчет RSI включает два шага:
-
Расчет относительной силы (RS):
-
Расчет самого RSI:
Стандартный период для расчета RSI составляет 14 дней. Например, если актив закрылся выше за 7 из последних 14 дней с средним приростом 1%, а остальные 7 дней закрылись ниже со средней потерей 0.8%, то начальное значение RS будет 1.25 (1% / 0.8%). Далее применяется формула для получения RSI.
Значения RSI интерпретируются так:
Выше 70 — актив перекуплен, возможно, будет коррекция вниз.
Ниже 30 — актив перепродан, возможно, ожидается рост цены.
RSI помогает трейдерам выявлять перекупленные и перепроданные состояния рынка, что может сигнализировать о возможных разворотах трендов. Например, если RSI превышает 70, это указывает на перекупленность актива, что может привести к его коррекции. Наоборот, если RSI падает ниже 30, это сигнализирует о перепроданности, что может привести к росту цены.
Дивергенции RSI происходят, когда тренд цен актива и тренд самого RSI расходятся, что может указывать на ослабление текущего тренда и возможный разворот.
Бычья дивергенция возникает, когда цена делает новый минимум, а RSI формирует более высокий минимум. Это указывает на ослабление нисходящего тренда и возможный разворот вверх.
Медвежья дивергенция происходит, когда цена делает новый максимум, а RSI формирует более низкий максимум. Это сигнализирует о слабости восходящего тренда и возможном развороте вниз.
Примеры кода для расчета RSI
Python
import pandas as pd
def calculate_rsi(data, period=14):
delta = data['Close'].diff()
gain = (delta.where(delta > 0, 0)).fillna(0)
loss = (-delta.where(delta < 0, 0)).fillna(0)
avg_gain = gain.rolling(window=period).mean()
avg_loss = loss.rolling(window=period).mean()
rs = avg_gain / avg_loss
rsi = 100 - (100 / (1 + rs))
return rsi
# Example usage
data = pd.DataFrame({
'Close': [45.15, 46.23, 45.56, 46.33, 45.86, 46.71, 47.24, 46.69, 47.28, 47.88, 48.07, 47.86, 47.33, 47.59]
})
data['RSI'] = calculate_rsi(data)
print(data)
JavaScript
function calculateRSI(closes, period = 14) {
let gains = [];
let losses = [];
for (let i = 1; i < closes.length; i++) {
let change = closes[i] - closes[i - 1];
gains.push(change > 0 ? change : 0);
losses.push(change < 0 ? -change : 0);
}
let avgGain = gains.slice(0, period).reduce((a, b) => a + b, 0) / period;
let avgLoss = losses.slice(0, period).reduce((a, b) => a + b, 0) / period;
let rs = avgGain / avgLoss;
let rsi = [100 - (100 / (1 + rs))];
for (let i = period; i < gains.length; i++) {
avgGain = (avgGain * (period - 1) + gains[i]) / period;
avgLoss = (avgLoss * (period - 1) + losses[i]) / period;
rs = avgGain / avgLoss;
rsi.push(100 - (100 / (1 + rs)));
}
return rsi;
}
// example
let closes = [45.15, 46.23, 45.56, 46.33, 45.86, 46.71, 47.24, 46.69, 47.28, 47.88, 48.07, 47.86, 47.33, 47.59];
console.log(calculateRSI(closes));
R
calculate_rsi <- function(prices, n = 14) {
deltas <- diff(prices)
seed <- deltas[1:n]
up <- seed[seed >= 0]
down <- -seed[seed < 0]
up[is.na(up)] <- 0
down[is.na(down)] <- 0
avg_gain <- sum(up) / n
avg_loss <- sum(down) / n
rs <- avg_gain / avg_loss
rsi <- 100 - (100 / (1 + rs))
rsi_values <- c(rep(NA, n), rsi)
for (i in (n+1):length(deltas)) {
delta <- deltas[i]
gain <- ifelse(delta > 0, delta, 0)
loss <- ifelse(delta < 0, -delta, 0)
avg_gain <- (avg_gain * (n - 1) + gain) / n
avg_loss <- (avg_loss * (n - 1) + loss) / n
rs <- avg_gain / avg_loss
rsi <- 100 - (100 / (1 + rs))
rsi_values <- c(rsi_values, rsi)
}
return(rsi_values)
}
# example
prices <- c(45.15, 46.23, 45.56, 46.33, 45.86, 46.71, 47.24, 46.69, 47.28, 47.88, 48.07, 47.86, 47.33, 47.59)
rsi <- calculate_rsi(prices)
print(rsi)
Стохастический осциллятор
Стохастический осциллятор был разработан Джорджем Лейном в конце 1950-х годов. Это технический индикатор, который измеряет отношение текущей цены закрытия к диапазону цен за определенный период времени. Основная идея стохастического осциллятора заключается в том, что в восходящем тренде цены закрытия обычно находятся ближе к верхней границе диапазона, а в нисходящем тренде — ближе к нижней границе.
Стохастический осциллятор состоит из двух основных компонентов: линии %K и линии %D.
-
%K линия рассчитывается по формуле
где:— текущая цена закрытия,
— самая низкая цена за последние N периодов,
— самая высокая цена за последние N периодов.
%D линия представляет собой скользящее среднее линии %K за три периода:
По дефолту используют период в 14 дней для %K и 3 дня для %D, но эти параметры могут быть изменены в зависимости от предпочтений.
Значения стохастического осциллятора колеблются от 0 до 100. Уровни выше 80 указывают на перекупленность актива, а уровни ниже 20 — на его перепроданность.
Перекупленность: когда осциллятор превышает 80, это может указывать на возможный разворот вниз. Трейдеры используют это как сигнал для продажи.
Перепроданность:когда осциллятор падает ниже 20, это может указывать на возможный разворот вверх. Это сигнал для покупки.
Стохастический осциллятор хорош в условиях бокового рынка, где он помогает выявлять краткосрочные колебания. В трендовых рынках осциллятор может оставаться в зоне перекупленности или перепроданности длительное время, что требует доп. индикаторов для подтверждения сигналов.
Дивергенции стохастического осциллятора возникают, когда направление осциллятора не совпадает с направлением цены актива.
Примеры рассчетов в коде
Python
import pandas as pd
def calculate_stochastic_oscillator(data, k_period=14, d_period=3):
low_min = data['Low'].rolling(window=k_period).min()
high_max = data['High'].rolling(window=k_period).max()
data['%K'] = 100 * ((data['Close'] - low_min) / (high_max - low_min))
data['%D'] = data['%K'].rolling(window=d_period).mean()
return data
# example
data = pd.DataFrame({
'High': [127.01, 128.48, 128.43, 128.72, 128.22, 128.43, 128.72, 128.21, 128.35, 128.75, 128.37, 128.57, 128.88, 128.78],
'Low': [125.36, 126.41, 126.74, 126.82, 126.32, 126.74, 126.82, 126.41, 126.35, 126.82, 126.41, 126.72, 126.92, 126.72],
'Close': [126.45, 127.98, 127.98, 128.43, 127.38, 127.68, 128.43, 127.88, 127.88, 128.28, 127.78, 128.15, 128.43, 128.23]
})
data = calculate_stochastic_oscillator(data)
print(data[['%K', '%D']])
JavaScript
function calculateStochasticOscillator(highs, lows, closes, kPeriod = 14, dPeriod = 3) {
let stochastics = [];
let percentK = [];
let percentD = [];
for (let i = 0; i < closes.length; i++) {
if (i >= kPeriod - 1) {
let highMax = Math.max(...highs.slice(i - kPeriod + 1, i + 1));
let lowMin = Math.min(...lows.slice(i - kPeriod + 1, i + 1));
let k = ((closes[i] - lowMin) / (highMax - lowMin)) * 100;
percentK.push(k);
if (percentK.length >= dPeriod) {
let d = percentK.slice(-dPeriod).reduce((a, b) => a + b) / dPeriod;
percentD.push(d);
} else {
percentD.push(null);
}
} else {
percentK.push(null);
percentD.push(null);
}
stochastics.push({
K: percentK[percentK.length - 1],
D: percentD[percentD.length - 1]
});
}
return stochastics;
}
// example
let highs = [127.01, 128.48, 128.43, 128.72, 128.22, 128.43, 128.72, 128.21, 128.35, 128.75, 128.37, 128.57, 128.88, 128.78];
let lows = [125.36, 126.41, 126.74, 126.82, 126.32, 126.74, 126.82, 126.41, 126.35, 126.82, 126.41, 126.72, 126.92, 126.72];
let closes = [126.45, 127.98, 127.98, 128.43, 127.38, 127.68, 128.43, 127.88, 127.88, 128.28, 127.78, 128.15, 128.43, 128.23];
console.log(calculateStochasticOscillator(highs, lows, closes));
R
calculate_stochastic <- function(highs, lows, closes, k_period = 14, d_period = 3) {
K <- rep(NA, length(closes))
D <- rep(NA, length(closes))
for (i in seq(k_period, length(closes))) {
high_max <- max(highs[(i - k_period + 1):i])
low_min <- min(lows[(i - k_period + 1):i])
K[i] <- ((closes[i] - low_min) / (high_max - low_min)) * 100
}
for (i in seq((k_period + d_period - 1), length(closes))) {
D[i] <- mean(K[(i - d_period + 1):i], na.rm = TRUE)
}
return(data.frame(K = K, D = D))
}
# example
highs <- c(127.01, 128.48, 128.43, 128.72, 128.22, 128.43, 128.72, 128.21, 128.35, 128.75, 128.37, 128.57, 128.88, 128.78)
lows <- c(125.36, 126.41, 126.74, 126.82, 126.32, 126.74, 126.82, 126.41, 126.35, 126.82, 126.41, 126.72, 126.92, 126.72)
closes <- c(126.45, 127.98, 127.98, 128.43, 127.38, 127.68, 128.43, 127.88, 127.88, 128.28, 127.78, 128.15, 128.43, 128.23)
stochastic <- calculate_stochastic(highs, lows, closes)
print(stochastic)
Оба индикатора могут быть использованы в сочетании с другими инструментами технического анализа для повышения точности сигналов. Например, использование RSI и стохастического осциллятора вместе с трендовыми линиями, скользящими средними или уровнями поддержки и сопротивления часто улучшает торговые стратегии.
Больше инструментов для анализа данных эксперты из OTUS разбирают в рамках практических онлайн-курсов. Подробнее в каталоге.
Format-X22
Осталось только понять где тренд, а где бок. Потому что в зависимости от этого один и тот же сигнал говорит нам о том что надо купить на тренде, но продать если боковик. И при переходе из одного состояния в другое сначала идут потери, а только потом смена стратегии. Но самое веселье начнется когда тренд пошел после боковика, ты это понял, начал работать с индикатором уже как с трендовым… а тренд уже и закончился… и снова череда потерь.
Главное научиться этот период определять. И вот ты определил, подобрал размер, посчитал по истории, получил результат, занес денег, и… а рынок изменился и тебе нужен уже другой диапазон. Только поймешь ты это уже после потерь. А если менять стратегию на первую же неудачную сделку, то потери будут ещё больше - метание туда-сюда ломает риск-менеджмент.
Не существует способов достоверно предсказывать смену трендов и боковиков на основе периодов времени - любое совпадение это временная корелляция. Рынок не подчиняется законам подобранным по истории числам. Чем больше констант - тем ниже точность стратегии. Ну а про «используйте для трендов так, а для боковиков сяк» это вообще из области казино, лудомании и скама. Опасайтесь таких технологий, даже если интуитивно кажется что оно работает. Это временные корелляции.
iShrimp
Граница между закономерностью и шумом очень тонка. Если дать трейдеру для анализа график случайного блуждания, то он сможет в нём найти буквально всё - тренды, коридоры, пики, линии поддержки и т.д. Он может попытаться "спрогнозировать" дальнейшее поведение графика. Но мы-то знаем, что грош цена этим предсказаниям, а он - нет. Все выявленные им предикторы являются случайностью, шумом. Так же и в реальных рыночных графиках бо́льшая часть предикторов - шум.