Яндекс.Метрика
ГлавнаяПостроение системы › Предсказание чего угодно с использованием Python

Предсказание чего угодно с использованием Python

bayes-retgurns-1080x571

Небольшая статья с ресурса http://www.talaikis.com/ о построении простой стратегии, использующую наивный байесовский классификатор при создании процесса возврата к среднему. Весь код в статье приведен на языке Python.

Это достаточно большая область исследований, но расскажем все очень кратко. Мы попытаемся найти взаимоотношение между  временными сериями  (в данном случае возьмем в качестве сигнала взаимный фонд XLF из финансового сектора, сдвинутый по времени на 1 день назад), а нашей целью будет фьючерс S&P500 в форме CFD. Будем входить в длинную позицию по этой бумаге при нулевой вероятности приращения. Логически нулевая вероятность ни о чем не говорит, другими словами, будем покупать возврат к среднему.

1. Получение данных

Y = read_mongo(dbase, "S&P5001440")
X = read_mongo(dbase, syms[s]).shift()

#готовим набор данных
res = pd.concat([X.CLOSE, Y.CLOSE], axis=1, join_axes=[X.index]).pct_change().dropna()
res.columns = ['X', 'Y']

 

2. Далее мы конструируем матрицу ошибок.Если сигнал растет и S&P500 растет - это истинное положительное значение, если сигнал вверх, а S&P500 -вниз, это ложное положительное значение, то же для отрицательных сигналов. Мы делаем это двумя способами:

#матрица ошибок
res['true_positive'] = np.where(np.where((res['X'] > 0), res['Y'], 0) > 0, res['Y'], 0) 
res['false_positive'] = np.where((np.where((res['X'] > 0), res['Y'], 0) < 0), res['Y'], 0)
res['true_negative'] = np.where((res['X'] < 0) & (res['Y'] < 0), res['Y'], 0)
res['false_negative'] = np.where((res['X'] < 0) & (res['Y'] > 0), res['Y'], 0)

 

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

#скользящая сумма сигналов
w = 10
res['true_positive_sum'] = pd.rolling_sum(res['true_positive'].astype(bool), window=w) 
res['false_positive_sum'] = pd.rolling_sum(res['false_positive'].astype(bool), window=w)
res['true_negative_sum'] = pd.rolling_sum(res['true_negative'].astype(bool), window=w)
res['false_negative_sum'] = pd.rolling_sum(res['false_negative'].astype(bool), window=w)

 

4. Теперь попытаемся определить вероятность сигналов обоих направлений. Для этого используем простую формулу частот:

P(E)=\frac{n(E)}{n(S)}

смысл которой в том, что вероятность события равна числу желаемых событий , деленных на число всех возможных событий:

res['accuracy'] =  (res['true_positive_sum'] + res['true_negative_sum']) / (res['true_positive_sum'] + \
            res['true_negative_sum'] + res['false_positive_sum'] + res['false_negative_sum'])

plt.plot(res['accuracy'])
plt.axhline(0.5, color = 'r', xmax=5)
plt.show()

signal-accuracy-1080x580

 

5. Вычислим вероятности противоположных событий:

res['true_positive_ratio'] =  res['true_positive_sum'] /(res['true_positive_sum'] + res['false_negative_sum'])
res['false_positive_ratio'] = res['false_positive_sum'] / (res['false_positive_sum'] + res['true_negative_sum'])
res['true_negative_ratio'] = 1 - res['true_positive_ratio']
res['false_negative_ratio'] = 1 - res['false_positive_ratio']

6. Сейчас мы можем вычислить сигналы и прибыльность. Будем использовать десятикратное плечо при расчете прибыли. Код ниже дан для ситуации " вход в лонг при отрицательной вероятности":

res['signal'] = np.where(res['true_negative_ratio'] >= 1, 1, 0)
res['returns'] = res['signal'].shift() * res['Y'] * 10.0

В заглавии статьи показан график кумулятивной прибыли по сравнению со стратегией "купил и держи" ( линия зеленого цвета).

Ниже - график просадок:

bayes-drawdown-1080x572

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

1 Комментарии[ Ваш комментарий ]

  1. Хорошая демонстрация чистого мышления.

    Однако как обычно у любителей классификации очень сложно оценить ожидаемый доход.

Сообщение

Обратите внимание: вы можете использоватьHTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>