-
Notifications
You must be signed in to change notification settings - Fork 213
/
bnn.py
64 lines (47 loc) · 1.72 KB
/
bnn.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from .. import tools
from ..algo import Algo
class BNN(Algo):
"""Nearest neighbor based strategy. It tries to find similar sequences of price in history and
then maximize objective function (that is profit) on the days following them.
Reference:
L. Gyorfi, G. Lugosi, and F. Udina. Nonparametric kernel based sequential
investment strategies. Mathematical Finance 16 (2006) 337–357.
"""
PRICE_TYPE = "ratio"
REPLACE_MISSING = True
def __init__(self, k=5, l=10):
"""
:param k: Sequence length.
:param l: Number of nearest neighbors.
"""
super().__init__(min_history=k + l - 1)
self.k = k
self.l = l
def init_weights(self, columns):
m = len(columns)
return np.ones(m) / m
def step(self, x, last_b, history):
# find indices of nearest neighbors throughout history
ixs = self.find_nn(history, self.k, self.l)
# get returns from the days following NNs
J = history.iloc[[history.index.get_loc(i) + 1 for i in ixs]]
# get best weights
return tools.bcrp_weights(J)
def find_nn(self, H, k, l):
"""Note that nearest neighbors are calculated in a different (more efficient) way than shown
in the article.
param H: history
"""
# calculate distance from current sequence to every other point
D = H * 0
for i in range(1, k + 1):
D += (H.shift(i - 1) - H.iloc[-i]) ** 2
D = D.sum(1).iloc[:-1]
# sort and find nearest neighbors
D = D.sort_values()
return D.index[:l]
if __name__ == "__main__":
tools.quickrun(BNN())