Ejemplo n.º 1
0
                          axis=1)

            C = self.X.ix[c.index[c >= self.rho] + 1]

            if C.shape[0] == 0:
                b = np.ones(m) / float(m)
            else:
                b = self.optimal_weights(C)

            return b

    def optimal_weights(self, X):
        X = np.mat(X)

        n, m = X.shape
        P = 2 * matrix(X.T * X)
        q = -3 * matrix(np.ones((1, n)) * X).T

        G = matrix(-np.eye(m))
        h = matrix(np.zeros(m))
        A = matrix(np.ones(m)).T
        b = matrix(1.)

        sol = solvers.qp(P, q, G, h, A, b)
        return np.squeeze(sol['x'])


# use case
if __name__ == '__main__':
    tools.quickrun(CORN())
Ejemplo n.º 2
0
# -*- coding: utf-8 -*-
from universal.algo import Algo
from universal.algos import CRP
import universal.tools as tools
import numpy as np


class BCRP(CRP):
    """ Best Constant Rebalanced Portfolio = Constant Rebalanced Portfolio constructed
    with hindsight. It is often used as benchmark.

    Reference:
        T. Cover. Universal Portfolios, 1991.
        http://www-isl.stanford.edu/~cover/papers/paper93.pdf
    """
    def weights(self, X):
        """ Find weights which maximize return on X in hindsight! """
        self.b = tools.bcrp_weights(X)
        return super(BCRP, self).weights(X)


if __name__ == '__main__':
    tools.quickrun(BCRP())
Ejemplo n.º 3
0
    forever.  """

    PRICE_TYPE = 'raw'

    def __init__(self, b=None):
        """
        :params b: Portfolio weights at start. Default are uniform.
        """
        super(BAH, self).__init__()
        self.b = b

    def weights(self, S):
        """ Weights function optimized for performance. """
        b = np.ones(S.shape[1]) / S.shape[1] if self.b is None else self.b

        # weights are proportional to price times initial weights
        w = S * b

        # normalize
        w = w.div(w.sum(axis=1), axis=0)

        # shift
        w = w.shift(1)
        w.ix[0] = 1. / S.shape[1]

        return w


if __name__ == '__main__':
    tools.quickrun(BAH())
Ejemplo n.º 4
0
        leverage = max(self.leverage, 1. / m)
        stretch = (leverage - 1. / m) / (1. - 1. / m)
        self.W = (self.W - 1. / m) * stretch + 1. / m

    def step(self, x, last_b):
        # calculate new wealth of all CRPs
        self.S = np.multiply(self.S, self.W * np.matrix(x).T)
        b = self.W.T * self.S

        return b / sum(b)

    def plot_leverage(self, S, leverage=np.linspace(1, 10, 10), **kwargs):
        """ Plot graph with leverages on x-axis and total wealth on y-axis.
        :param S: Stock prices.
        :param leverage: List of parameters for leverage.
        """
        wealths = []
        for lev in leverage:
            self.leverage = lev
            wealths.append(self.run(S).total_wealth)

        ax = pd.Series(wealths, index=leverage, **kwargs).plot(**kwargs)
        ax.set_xlabel('Leverage')
        ax.set_ylabel('Total Wealth')
        return ax


if __name__ == '__main__':
    data = tools.dataset('sp500')
    tools.quickrun(UP(), data)
Ejemplo n.º 5
0
    def step(self, x, last_b, history):
        # calculate return prediction
        x_pred = self.predict(x, history.iloc[-self.window:])
        b = self.update(last_b, x_pred, self.eps)
        return b
        

    def predict(self, x, history):
        """ Predict returns on next day. """
        return (history / x).mean()
            

    def update(self, b, x, eps):
        """ Update portfolio weights to satisfy constraint b * x >= eps
        and minimize distance to previous weights. """
        x_mean = np.mean(x)
        lam = max(0., (eps - np.dot(b, x)) / np.linalg.norm(x - x_mean)**2)
        
        # limit lambda to avoid numerical problems
        lam = min(100000, lam)
        
        # update portfolio
        b = b + lam * (x - x_mean)
        
        # project it onto simplex
        return tools.simplex_proj(b)

    
if __name__ == '__main__':
    tools.quickrun(OLMAR())
    
Ejemplo n.º 6
0
        # lambda from equation 7
        foo = (V - x_upper * x.T * np.sum(sigma, axis=1)) / M**2
        a = 2 * theta * V * foo
        b = foo + 2 * theta * V * (eps - log(M))
        c = eps - log(M) - theta * V
        
        a,b,c = a[0,0], b[0,0], c[0,0]

        lam = max(0, 
                  (-b + sqrt(b**2 - 4 * a * c)) / (2. * a),
                  (-b - sqrt(b**2 - 4 * a * c)) / (2. * a))
        # bound it due to numerical problems
        lam = min(lam, 1E+7)
        
        # update mu and sigma
        mu = mu - lam * sigma * (x - x_upper) / M
        sigma = inv(inv(sigma) + 2 * lam * theta * diag(x)**2)
        """
        tmp_sigma = inv(inv(sigma) + theta*lam/U_sqroot*diag(xt)^2);
        % Don't update sigma if results are badly scaled.
        if all(~isnan(tmp_sigma(:)) & ~isinf(tmp_sigma(:)))
            sigma = tmp_sigma;
        end
        """ 
        return mu, sigma    
    
    
# use case
if __name__ == '__main__':
    tools.quickrun(CWMR())
Ejemplo n.º 7
0
    PRICE_TYPE = 'raw'
    REPLACE_MISSING = True

    def __init__(self, window=5, eps=10., tau=0.001):
        """
        :param window: Lookback window.
        :param eps: Constraint on return for new weights on last price (average of prices).
            x * w >= eps for new weights w.
        :param tau: Precision for finding median. Recommended value is around 0.001. Strongly
                    affects algo speed.
        """
        super(RMR, self).__init__(window, eps)
        self.tau = tau

    def predict(self, x, history):
        """ find L1 median to historical prices """
        y = history.mean()
        y_last = None
        while y_last is None or norm(y - y_last) / norm(y_last) > self.tau:
            y_last = y
            d = norm(history - y)
            y = history.div(d, axis=0).sum() / (1. / d).sum()
        return y / x


if __name__ == '__main__':
    tools.quickrun(RMR())



Ejemplo n.º 8
0
    def update(self, b, x, eps, C):
        """ Update portfolio weights to satisfy constraint b * x <= eps
        and minimize distance to previous weights. """
        x_mean = np.mean(x)
        le = max(0., np.dot(b, x) - eps)
        
        if self.variant == 0:
            lam = le / np.linalg.norm(x - x_mean)**2
        elif self.variant == 1:
            lam = min(C, le / np.linalg.norm(x - x_mean)**2)
        elif self.variant == 2:
            lam = le / (np.linalg.norm(x - x_mean)**2 + 0.5 / C)
            
        # limit lambda to avoid numerical problems
        lam = min(100000, lam)
        
        # update portfolio
        b = b - lam * (x - x_mean)
        
        # project it onto simplex
        return tools.simplex_proj(b)
    

if __name__ == '__main__':
    tools.quickrun(PAMR())





Ejemplo n.º 9
0
    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.sort()
        return D.index[:l]


if __name__ == '__main__':
    tools.quickrun(BNN())
Ejemplo n.º 10
0
    Reference:
        Li Gao, Weiguo Zhang
        Weighted Moving Averag Passive Aggressive Algorithm for Online Portfolio Selection, 2013.
        http://ieeexplore.ieee.org/xpl/login.jsp?tp=&arnumber=6643896
    """

    PRICE_TYPE = 'ratio'

    def __init__(self, window=5, **kwargs):
        """
        :param w: Windows length for moving average.
        :param kwargs: Additional arguments for PAMR.
        """
        super(WMAMR, self).__init__(**kwargs)

        if window < 1:
            raise ValueError('window parameter must be >=1')
        self.window = window

    def step(self, x, last_b, history):
        xx = history[-self.window:].mean()
        # calculate return prediction
        b = self.update(last_b, xx, self.eps, self.C)
        return b


# use case
if __name__ == '__main__':
    tools.quickrun(WMAMR())
Ejemplo n.º 11
0
                    for (i=0; i<Nc[1]; i++) {
                        float total_claim=0.;
                        for (j=0; j<Nc[1]; j++) {
                            total_claim += claim[i][j];
                        }
                        if(total_claim != 0){
                            for (j=0; j<Nc[1]; j++) {
                                transfer[i][j] = W2(t,i) * claim[i][j] / total_claim;
                            }
                        }

                    }

                    for (i=0; i<Nc[1]; i++) {
                        W2(t+1,i) = W2(t,i);
                        for (j=0; j<Nc[1]; j++) {
                            W2(t+1,i) += transfer[j][i] - transfer[i][j];
                        }
                    }
                }
                """
                return weave.inline(code, ['c', 'mu', 'w'])

            get_weights_c(CORR, EX, weights)

        return weights


if __name__ == '__main__':
    tools.quickrun(Anticor())
Ejemplo n.º 12
0
    PRICE_TYPE = 'raw'

    def __init__(self, b=None):
        """
        :params b: Portfolio weights at start. Default are uniform.
        """
        super(BAH, self).__init__()
        self.b = b

    def weights(self, S):
        """ Weights function optimized for performance. """
        b = np.ones(S.shape[1]) / S.shape[1] if self.b is None else self.b
        
        # weights are proportional to price times initial weights
        w = S * b

        # normalize
        w = w.div(w.sum(axis=1), axis=0)

        # shift
        w = w.shift(1)
        w.ix[0] = 1./S.shape[1]

        return w
            

if __name__ == '__main__':
    tools.quickrun(BAH())
    
    
    
Ejemplo n.º 13
0
            
            C = self.X.ix[c.index[c >= self.rho] + 1]
            
            if C.shape[0] == 0:
                b = np.ones(m) / float(m)
            else:
                b = self.optimal_weights(C)
                
            return b
            
    def optimal_weights(self, X):
        X = np.mat(X)
        
        n,m = X.shape
        P = 2 * matrix(X.T * X)
        q = -3 * matrix(np.ones((1,n)) * X).T
        
        G = matrix(-np.eye(m))
        h = matrix(np.zeros(m))
        A = matrix(np.ones(m)).T
        b = matrix(1.)
        
        sol = solvers.qp(P, q, G, h, A, b)
        return np.squeeze(sol['x'])
        


# use case
if __name__ == '__main__':
    tools.quickrun(CORN())
Ejemplo n.º 14
0
        else:
            data.plot(logy=False)

        if show_3d:
            assert dim == 3, '3D plot works for exactly 3 assets.'
            plt.figure()
            fun = lambda b: CRP(b).run(data).total_wealth
            ternary.plot_heatmap(fun, steps=20, boundary=True)

        elif dim == 2:
            x, y = _crp(data)
            s = pd.Series(y, index=x)
            s.plot(ax=axes[1], logy=True)
            plt.title('CRP performance')
            plt.xlabel('weight of {}'.format(data.columns[0]))

        elif dim > 2:
            fig, axes = plt.subplots(ncols=dim - 1, nrows=dim - 1)
            for i in range(dim - 1):
                for j in range(i + 1, dim):
                    x, y = _crp(data[[i, j]])
                    ax = axes[i][j - 1]
                    ax.plot(x, y)
                    ax.set_title('{} & {}'.format(data.columns[i],
                                                  data.columns[j]))
                    ax.set_xlabel('weights of {}'.format(data.columns[i]))


if __name__ == '__main__':
    result = tools.quickrun(CRP())
    print(result.information)
Ejemplo n.º 15
0
    Reference:
        Li Gao, Weiguo Zhang
        Weighted Moving Averag Passive Aggressive Algorithm for Online Portfolio Selection, 2013.
        http://ieeexplore.ieee.org/xpl/login.jsp?tp=&arnumber=6643896
    """

    PRICE_TYPE = 'ratio'
    
    def __init__(self, window=5, **kwargs):
        """
        :param w: Windows length for moving average.
        :param kwargs: Additional arguments for PAMR.
        """
        super(WMAMR, self).__init__(**kwargs)
        
        if window < 1:
            raise ValueError('window parameter must be >=1')
        self.window = window
        
            
    def step(self, x, last_b, history):
        xx = history[-self.window:].mean()
        # calculate return prediction
        b = self.update(last_b, xx, self.eps, self.C)
        return b
    
    
# use case
if __name__ == '__main__':
    tools.quickrun(WMAMR())
Ejemplo n.º 16
0
class EG(Algo):
    """ Exponentiated Gradient (EG) algorithm by Helmbold et al. 

    Reference:
        Helmbold, David P., et al. 
        "On‐Line Portfolio Selection Using Multiplicative Updates." 
        Mathematical Finance 8.4 (1998): 325-347.
    """

    def __init__(self, eta=0.05):
        """
        :params eta: Learning rate. Controls volatility of weights.
        """
        super(EG, self).__init__()
        self.eta = eta


    def init_weights(self, m):
        return np.ones(m) / m


    def step(self, x, last_b):
        b = last_b * np.exp(self.eta * x / sum(x * last_b))
        return b / sum(b)


if __name__ == '__main__':
    data = tools.dataset('nyse_o')
    tools.quickrun(EG(eta=0.5), data)
Ejemplo n.º 17
0
            data.plot(ax=axes[0], logy=True)
        else:
            data.plot(logy=False)
        
        if show_3d:
            assert dim == 3, '3D plot works for exactly 3 assets.'
            plt.figure()
            fun = lambda b: CRP(b).run(data).total_wealth
            ternary.plot_heatmap(fun, steps=20, boundary=True)
            
        elif dim == 2:
            x,y = _crp(data)
            s = pd.Series(y, index=x)
            s.plot(ax=axes[1], logy=True)
            plt.title('CRP performance')
            plt.xlabel('weight of {}'.format(data.columns[0]))
            
        elif dim > 2:
            fig, axes = plt.subplots(ncols=dim-1, nrows=dim-1)
            for i in range(dim-1):
                for j in range(i + 1, dim):
                    x,y = _crp(data[[i,j]])
                    ax = axes[i][j-1] 
                    ax.plot(x,y)
                    ax.set_title('{} & {}'.format(data.columns[i], data.columns[j]))
                    ax.set_xlabel('weights of {}'.format(data.columns[i]))


if __name__ == '__main__':
    result = tools.quickrun(CRP())
    print(result.information)
Ejemplo n.º 18
0
                    for (i=0; i<Nc[1]; i++) {
                        float total_claim=0.;
                        for (j=0; j<Nc[1]; j++) {
                            total_claim += claim[i][j];
                        }
                        if(total_claim != 0){
                            for (j=0; j<Nc[1]; j++) {
                                transfer[i][j] = W2(t,i) * claim[i][j] / total_claim;
                            }
                        }

                    }

                    for (i=0; i<Nc[1]; i++) {
                        W2(t+1,i) = W2(t,i);
                        for (j=0; j<Nc[1]; j++) {
                            W2(t+1,i) += transfer[j][i] - transfer[i][j];
                        }
                    }
                }
                """
                return weave.inline(code, ['c', 'mu', 'w'])

            get_weights_c(CORR, EX, weights)

        return weights


if __name__ == '__main__':
    tools.quickrun(Anticor())
Ejemplo n.º 19
0
        
        P = matrix((sigma - r*mu*mu.T + (n*r)**2) / (1+r))
        q = matrix(-mu)
        G = matrix(-np.eye(n))
        h = matrix(np.zeros(n))
        
        sol = solvers.qp(P, q, G, h)
        return np.squeeze(sol['x'])
    
    
    def plot_fraction(self, S, fractions=np.linspace(0.,2.,10), **kwargs):
        """ Plot graph with Kelly fraction on x-axis and total wealth on y-axis. 
        :param S: Stock prices.
        :param fractions: List (ndarray) of fractions used.
        """
        wealths = [] 
        for fraction in fractions:
            self.fraction = fraction
            wealths.append(self.run(S).total_wealth)
            
        ax = pd.Series(wealths, index=fractions, **kwargs).plot(**kwargs)
        ax.set_xlabel('Kelly Fraction')
        ax.set_ylabel('Total Wealth')
        return ax


# use case
if __name__ == '__main__':
    tools.quickrun(Kelly())

Ejemplo n.º 20
0
# -*- coding: utf-8 -*-
from universal.algo import Algo
from universal.algos import CRP
import universal.tools as tools
import numpy as np


class BCRP(CRP):
    """ Best Constant Rebalanced Portfolio = Constant Rebalanced Portfolio constructed
    with hindsight. It is often used as benchmark.

    Reference:
        T. Cover. Universal Portfolios, 1991.
        http://www-isl.stanford.edu/~cover/papers/paper93.pdf
    """

    def weights(self, X):
        """ Find weights which maximize return on X in hindsight! """
        self.b = tools.bcrp_weights(X)
        return super(BCRP, self).weights(X)


if __name__ == '__main__':
    tools.quickrun(BCRP())
    
Ejemplo n.º 21
0
        return np.ones(m) / m

    def step(self, x, last_b, history):
        # calculate return prediction
        x_pred = self.predict(x, history.iloc[-self.window:])
        b = self.update(last_b, x_pred, self.eps)
        return b

    def predict(self, x, history):
        """ Predict returns on next day. """
        return (history / x).mean()

    def update(self, b, x, eps):
        """ Update portfolio weights to satisfy constraint b * x >= eps
        and minimize distance to previous weights. """
        x_mean = np.mean(x)
        lam = max(0., (eps - np.dot(b, x)) / np.linalg.norm(x - x_mean)**2)

        # limit lambda to avoid numerical problems
        lam = min(100000, lam)

        # update portfolio
        b = b + lam * (x - x_mean)

        # project it onto simplex
        return tools.simplex_proj(b)


if __name__ == '__main__':
    tools.quickrun(OLMAR())
Ejemplo n.º 22
0
    def step(self, r, p):
        # calculate gradient
        grad = np.mat(r / np.dot(p, r)).T
        # update A
        self.A += grad * grad.T
        # update b
        self.b += (1 + 1. / self.beta) * grad

        # projection of p induced by norm A
        pp = self.projection_in_norm(self.delta * self.A.I * self.b, self.A)
        return pp * (1 - self.eta) + np.ones(len(r)) / float(len(r)) * self.eta

    def projection_in_norm(self, x, M):
        """ Projection of x to simplex indiced by matrix M. Uses quadratic programming.
        """
        m = M.shape[0]

        P = matrix(2 * M)
        q = matrix(-2 * M * x)
        G = matrix(-np.eye(m))
        h = matrix(np.zeros((m, 1)))
        A = matrix(np.ones((1, m)))
        b = matrix(1.)

        sol = solvers.qp(P, q, G, h, A, b)
        return np.squeeze(sol['x'])


if __name__ == '__main__':
    tools.quickrun(ONS())
Ejemplo n.º 23
0
    def step(self, r, p):
        # calculate gradient
        grad = np.mat(r / np.dot(p, r)).T
        # update A
        self.A += grad * grad.T
        # update b
        self.b += (1 + 1./self.beta) * grad
        
        # projection of p induced by norm A
        pp = self.projection_in_norm(self.delta * self.A.I * self.b, self.A)
        return pp * (1 - self.eta) + np.ones(len(r)) / float(len(r)) * self.eta  
        
    def projection_in_norm(self, x, M):
        """ Projection of x to simplex indiced by matrix M. Uses quadratic programming.
        """
        m = M.shape[0]
        
        P = matrix(2*M)
        q = matrix(-2 * M * x)
        G = matrix(-np.eye(m))
        h = matrix(np.zeros((m,1)))
        A = matrix(np.ones((1,m)))
        b = matrix(1.)
        
        sol = solvers.qp(P, q, G, h, A, b)
        return np.squeeze(sol['x'])
        

if __name__ == '__main__':
    tools.quickrun(ONS())
    
Ejemplo n.º 24
0
    def step(self, x, last_b):
        # calculate return prediction
        b = self.update(last_b, x, self.eps, self.C)
        return b

    def update(self, b, x, eps, C):
        """ Update portfolio weights to satisfy constraint b * x <= eps
        and minimize distance to previous weights. """
        x_mean = np.mean(x)
        le = max(0., np.dot(b, x) - eps)

        if self.variant == 0:
            lam = le / np.linalg.norm(x - x_mean)**2
        elif self.variant == 1:
            lam = min(C, le / np.linalg.norm(x - x_mean)**2)
        elif self.variant == 2:
            lam = le / (np.linalg.norm(x - x_mean)**2 + 0.5 / C)

        # limit lambda to avoid numerical problems
        lam = min(100000, lam)

        # update portfolio
        b = b - lam * (x - x_mean)

        # project it onto simplex
        return tools.simplex_proj(b)


if __name__ == '__main__':
    tools.quickrun(PAMR())