Commit 0dce4df3 authored by Dr.李's avatar Dr.李

added linear programming builder

parent bf2585a3
...@@ -15,6 +15,7 @@ from alphamind.benchmarks.portfolio.rankbuild import benchmark_build_rank ...@@ -15,6 +15,7 @@ from alphamind.benchmarks.portfolio.rankbuild import benchmark_build_rank
from alphamind.benchmarks.portfolio.rankbuild import benchmark_build_rank_with_group from alphamind.benchmarks.portfolio.rankbuild import benchmark_build_rank_with_group
from alphamind.benchmarks.portfolio.percentbuild import benchmark_build_percent from alphamind.benchmarks.portfolio.percentbuild import benchmark_build_percent
from alphamind.benchmarks.portfolio.percentbuild import benchmark_build_percent_with_group from alphamind.benchmarks.portfolio.percentbuild import benchmark_build_percent_with_group
from alphamind.benchmarks.portfolio.linearbuild import benchmark_build_linear
from alphamind.benchmarks.settlement.simplesettle import benchmark_simple_settle from alphamind.benchmarks.settlement.simplesettle import benchmark_simple_settle
from alphamind.benchmarks.settlement.simplesettle import benchmark_simple_settle_with_group from alphamind.benchmarks.settlement.simplesettle import benchmark_simple_settle_with_group
...@@ -51,6 +52,8 @@ if __name__ == '__main__': ...@@ -51,6 +52,8 @@ if __name__ == '__main__':
benchmark_build_percent_with_group(30, 50000, 0.1, 3) benchmark_build_percent_with_group(30, 50000, 0.1, 3)
benchmark_build_percent(50000, 20, 0.1) benchmark_build_percent(50000, 20, 0.1)
benchmark_build_percent_with_group(50000, 20, 0.1, 300) benchmark_build_percent_with_group(50000, 20, 0.1, 300)
benchmark_build_linear(100, 3, 3, 100)
benchmark_build_linear(1000, 30, 30, 10)
benchmark_simple_settle(3000, 10, 1000) benchmark_simple_settle(3000, 10, 1000)
benchmark_simple_settle_with_group(3000, 10, 1000, 30) benchmark_simple_settle_with_group(3000, 10, 1000, 30)
benchmark_simple_settle(30, 10, 50000) benchmark_simple_settle(30, 10, 50000)
......
# -*- coding: utf-8 -*-
"""
Created on 2017-5-5
@author: cheng.li
"""
import datetime as dt
import numpy as np
from scipy.optimize import linprog
from cvxopt import matrix
from cvxopt import solvers
from alphamind.portfolio.linearbuilder import linear_build
solvers.options['show_progress'] = False
def benchmark_build_linear(n_samples: int, n_risks: int, n_inds, n_loop: int) -> None:
print("-" * 60)
print("Starting portfolio construction by linear programming")
print("Parameters(n_samples: {0}, n_risks: {1}, n_inds: {2})".format(n_samples, n_risks, n_inds))
er = np.random.randn(n_samples)
risk_exp = np.random.randn(n_samples, n_risks)
bm = np.random.randint(n_inds, size=n_samples).astype(float)
bm /= bm.sum()
lbound = -0.04
ubound = 0.05
start = dt.datetime.now()
for _ in range(n_loop):
status, v, x = linear_build(er, lbound, ubound, risk_exp, bm, solver='ECOS')
impl_model_time = dt.datetime.now() - start
print('{0:20s}: {1}'.format('Implemented model (ECOS)', impl_model_time))
c = - er
bounds = [(lbound, ubound) for _ in range(n_samples)]
A_eq = np.ones((1, n_samples))
A_eq = np.vstack((A_eq, risk_exp.T))
b_eq = np.hstack((np.array([1.]), risk_exp.T @ bm))
start = dt.datetime.now()
for _ in range(n_loop):
res = linprog(c, A_eq=A_eq, b_eq=b_eq, bounds=bounds, options={'maxiter': 10000})
benchmark_model_time = dt.datetime.now() - start
print('{0:20s}: {1}'.format('Benchmark model (scipy)', benchmark_model_time))
np.testing.assert_array_almost_equal(x, res['x'])
c = matrix(-er)
A = matrix(A_eq)
b = matrix(b_eq)
G = matrix(np.vstack((np.diag(np.ones(n_samples)), -np.diag(np.ones(n_samples)))))
h = matrix(np.hstack((ubound * np.ones(n_samples), -lbound * np.ones(n_samples))))
solvers.lp(c, G, h, solver='glpk')
start = dt.datetime.now()
for _ in range(n_loop):
res2 = solvers.lp(c, G, h, A, b, solver='glpk')
benchmark_model_time = dt.datetime.now() - start
print('{0:20s}: {1}'.format('Benchmark model (glpk)', benchmark_model_time))
np.testing.assert_array_almost_equal(x, np.array(res2['x']).flatten())
if __name__ == '__main__':
benchmark_build_linear(1000, 30, 30, 1)
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on 2017-5-5
@author: cheng.li
"""
import numpy as np
import cvxpy
from cvxopt import solvers
solvers.options['glpk'] = {'msg_lev': 'GLP_MSG_OFF'}
def linear_build(er, lbound, ubound, risk_exposure, bm, risk_target=None, solver=None):
n, m = risk_exposure.shape
w = cvxpy.Variable(n)
if risk_target is None:
risk_target = np.zeros(m)
curr_risk_exposure = risk_exposure.T * (w - bm)
objective = cvxpy.Minimize(-w.T * er)
constraints = [w >= lbound,
w <= ubound,
curr_risk_exposure == risk_target,
cvxpy.sum_entries(w) == 1.]
prob = cvxpy.Problem(objective, constraints)
prob.solve(solver=solver)
return prob.status, prob.value, np.array(w.value).flatten()
if __name__ == '__main__':
er = np.arange(300)
bm = np.ones(300) * 0.00333333333
risk_exposure = np.random.randn(300, 10)
s, v, x = linear_build(er, 0., 0.01, risk_exposure, bm)
print(s)
print(x.sum())
print(x.min(), ',', x.max())
print((x - bm) @ risk_exposure)
# -*- coding: utf-8 -*-
"""
Created on 2017-5-5
@author: cheng.li
"""
import unittest
import numpy as np
from alphamind.portfolio.linearbuilder import linear_build
class TestLinearBuild(unittest.TestCase):
def test_linear_build(self):
er = np.random.randn(3000)
risk_exp = np.random.randn(3000, 30)
bm = np.random.randint(100, size=3000).astype(float)
bm /= bm.sum()
eplson = 1e-6
status, value, w = linear_build(er, 0., 0.01, risk_exp, bm)
self.assertEqual(status, 'optimal')
self.assertAlmostEqual(np.sum(w), 1.)
self.assertTrue(np.all(w <= 0.01 + eplson))
self.assertTrue(np.all(w >= -eplson))
calc_risk = (w - bm) @ risk_exp
expected_risk = np.zeros(risk_exp.shape[1])
np.testing.assert_array_almost_equal(calc_risk, expected_risk)
if __name__ == '__main__':
unittest.main()
\ No newline at end of file
...@@ -14,6 +14,7 @@ from alphamind.tests.data.test_standardize import TestStandardize ...@@ -14,6 +14,7 @@ from alphamind.tests.data.test_standardize import TestStandardize
from alphamind.tests.data.test_winsorize import TestWinsorize from alphamind.tests.data.test_winsorize import TestWinsorize
from alphamind.tests.portfolio.test_rankbuild import TestRankBuild from alphamind.tests.portfolio.test_rankbuild import TestRankBuild
from alphamind.tests.portfolio.test_percentbuild import TestPercentBuild from alphamind.tests.portfolio.test_percentbuild import TestPercentBuild
from alphamind.tests.portfolio.test_linearbuild import TestLinearBuild
from alphamind.tests.settlement.test_simplesettle import TestSimpleSettle from alphamind.tests.settlement.test_simplesettle import TestSimpleSettle
from alphamind.utilities import alpha_logger from alphamind.utilities import alpha_logger
from alphamind.utilities import TestRunner from alphamind.utilities import TestRunner
...@@ -25,6 +26,7 @@ if __name__ == '__main__': ...@@ -25,6 +26,7 @@ if __name__ == '__main__':
TestWinsorize, TestWinsorize,
TestRankBuild, TestRankBuild,
TestPercentBuild, TestPercentBuild,
TestLinearBuild,
TestSimpleSettle], TestSimpleSettle],
alpha_logger) alpha_logger)
runner.run() runner.run()
This source diff could not be displayed because it is too large. You can view the blob instead.
cvxopt >= 1.1.9
cvxpy >= 0.4.9
cython >= 0.25.2
numpy >= 1.12.1 numpy >= 1.12.1
numba >= 0.30.0 numba >= 0.30.0
scikit-learn >= 0.18.1 scikit-learn >= 0.18.1
......
...@@ -43,6 +43,7 @@ def generate_extensions(ext_modules, line_trace=False): ...@@ -43,6 +43,7 @@ def generate_extensions(ext_modules, line_trace=False):
extensions.append(ext) extensions.append(ext)
return extensions return extensions
if platform.system() != "Windows": if platform.system() != "Windows":
import multiprocessing import multiprocessing
n_cpu = multiprocessing.cpu_count() n_cpu = multiprocessing.cpu_count()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment