Регрессионные методы. Адаптивная фильтрация.


Эконометрические методы не оправдали наших надежд: среднеквадратическая ошибка прогноза цен акций оказалась равной 5 рублям, при том, что среднедневное колебание цены акции составляет лишь 4 рубля (мы говорим про 2009 год). Поэтому перейдем к более сложным методам прогноза. Перед дальнейшим чтением советую открыть справочник по высшей математике, потому что в теоретической части статьи будут использованы такие понятия как частная производная, градиент поля – нужно знать как они расчитываются.

Вначале поговорим о регрессии. Что это такое? Регрессия – это зависимость значений одной величины от другой. От функции отличие состоит в том, что при регрессии одному и тому же значению X может соответствовать несколько значений Y.

Существует еще понятие авторегрессии. Это регрессионная зависимость значений случайной последовательности от предшествующих значений. Общий вид линейной регрессии порядка m:

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

Линейная авторегрессия довольно проста и мало отличается от эконометрических методов. А вот линейная авторегрессия с адаптирующимися коэффициентами (с дрейфующими коэффициентами) – совсем другое дело. Другое ее название – адаптивная фильтрация.

Поясню подробнее. Алгоритм адаптивной фильтрации порядка m выгдядит следующим образом: выбираются коэффициеты w1, w2, …, wm (случайно), берутся последние m элементов последовательности xt-m+1, xt-m+2, …, xt и вычисляется прогнозное значение xt+1, после чего сравнив его с действительным значением xt+1 высчитывается ошибка прогноза et+1. Рассмотрим квадрат ошибки как функцию от коэффициентов w1, w2, …, wm:

Изменяя коэффициенты можно минимизировать величину ошибки для конкретного прогноза, но для того что бы оптимизировать фильтр для следующих прогнозов с учетом динамических свойств процесса воспользуемся методом наискорейшего спуска. Для этого выбрав начальные значения коэффициентов и получив ошибку проноза, найдем вектор приращений коэффициентов направленный в сторону наибольшего уменьшения величины ошибки. То есть изменим значения весовых коэффициентов на градиент квадрата ошибки пропорционально определенному коэффициенту (коэффициент адаптации): Wнов = Wстар – k*grad(et+12). Вычислим градиент с помощью частных производных:

Проверим метод адаптивной фильтрации на дневных котировках Газпрома за 2009 год. Для этого напишем программу для определения минимальной погрешности при различных значениях подстроечного коэффициента. Код приведен ниже:

# -*- coding: utf-8
import time
# подгружаем библиотеки
from quotes.ekonom import *

# начальные параметры
folder = 'data/'
qlist = 'quotes/mmvb.txt'
interval = 8

# финамовский номер газпрома
fnum = 16842

# загружаем котировки Газпрома из локальной базы
q = quote(interval,  fnum)
q.load(folder + str(q.symb) + '_' + str(interval) + '.csv')

# цены закрытия
x = q.cl

# класс реализующий адаптивный фильтр
class regrad(object):
	# при задании класса указываем размер окна (n)
	# и коэффициент подстройки
	def __init__(self, n, k):
		# размерность входного вектора предыдущих значений
		self.n = n
		# начальный размер весовых коэффициентов
		w0 = 1.0/n
		# весовые коэффициенты
		self.w = n * [w0]
		# подстроечный коэффициент
		self.k = k

	# подаем на вход массив из n элементов
	# на выходе прогноз (n+1)-го элемента
	def progn(self, x):
		s = 0.
		for i in xrange(len(x)):
			s += self.w[i] * x[i]
		return s

	# метод настройки - на вход массив n элементов
	# и реальное значение (n+1)-го элемента
	# на выходе - величина ошибки
	def tune(self, x, xr):
		xp = self.progn(x)
		e = (xr - xp)**2
		for i in xrange(self.n):
			self.w[i] += 2*self.k*e*x[i]
		return e ** 0.5

# задаем разменр окна
n = 10
# указываем любое большое значение
# это переменная для нахождения минимальной средней погрешности 
emin = 20000.
# проводим тысячу экпериментов...
for k in xrange(1000):
	# ... с различными коэффициентами подстройки
	a = float(k)/100000000000.
	# создаем фильтр
	r = regrad(n, a)
	# переменная для суммирования
	s = 0.
	# делаем 50 прогнозов
	for i in xrange(50):
		# суммируем ошибки
		s += r.tune(x[i:i+n], x[i+n])
	# находим среднюю ошибку 1-го прогноза
	s = s/50
	# если ошибка минимальна ...
	if s < emin:
		# ... запоминаем ее
		emin = s
	# удаляем объект класса
	del(r)

# выводим минимальную погрешность
print 'minimum', emin

Запускаем и видим, что …

… что даже с помощью адаптивной фильтрации невозможно дать пригодный для торговли прогноз для современного рынка. Хотя я не исключаю возможности применения данного метода на бОльших периодах, например, на недельных или месячных котировках.

, , , , ,



  1. #1 by lex on 1 Сентябрь 2010 - 5:07

    советую открыть справочник по высшей математике

    нифига ты живодер :)

  2. #3 by Александр on 30 Ноябрь 2010 - 2:25

    Ух ты, не много людей занимаются трейдингом изпод линукса, респект )

    Сам выбрал финам из-за того, что их торговая система на java и без проблем идет у меня под линем )

    • #4 by toly on 30 Ноябрь 2010 - 10:05

      Я торгую через ВТБ24 (QUIK запускаю wine’ом), а с Финама удобно котировки скачивать. Хотя по идее сами котировки должны различаться, потому что в ВТБ акции, а на Финаме – их форварды.

  3. #5 by Александр on 19 Февраль 2011 - 0:38

    Думаю точность прогнозов изрядно повысится если ввести дополнительный корректирующий коэффициент на выходе – новостной фон. Если совсем просто, то 1 – позитив :) , 0 – нейтральный :| , минус1 – негатив :(

    • #6 by Сергей on 26 Февраль 2013 - 13:00

      Здравствуйте, а вы не пробовали R language прикрутить к python? слышал что они хорошо дружат . вся статистика уже реализована в пакетах R, загрузка котировок с finam тоже есть (пакет rusquant).

      • #7 by toly on 26 Февраль 2013 - 13:09

        Сейчас трейдингом уже не занимаюсь – веб-разработка наше все ) Но про R слышал.

(никто не узнает)