<jupyter_start><jupyter_text>* 请在环境变量中设置`DB_URI`指向数据库<jupyter_code>import os
import numpy as np
import pandas as pd
from cvxpy import *
from cvxopt import *
from alphamind.api import *
from alphamind.cython.optimizers import QPOptimizer<jupyter_output><empty_output><jupyter_text>Data Preparing--------------------------<jupyter_code>risk_penlty = 0.5
ref_date = '2018-02-08'

engine = SqlEngine(os.environ['DB_URI'])
universe = Universe('ashare_ex')
codes = engine.fetch_codes(ref_date, universe)

risk_cov, risk_exposure = engine.fetch_risk_model(ref_date, codes)
factor = engine.fetch_factor(ref_date, 'EPS', codes)

total_data = pd.merge(factor, risk_exposure, on='code').dropna()
all_styles = risk_styles + industry_styles + macro_styles

risk_exposure_values = total_data[all_styles].values.astype(float)
special_risk_values = total_data['srisk'].values.astype(float)
risk_cov_values = risk_cov[all_styles].values

sec_cov_values_full = risk_exposure_values @ risk_cov_values @ risk_exposure_values.T / 10000  + np.diag(special_risk_values ** 2) / 10000
signal_full = total_data['EPS'].values
n = 200

sec_cov_values = sec_cov_values_full[:n, :n]
signal = signal_full[:n]<jupyter_output><empty_output><jupyter_text>Optimizing Weights-------------------------------------<jupyter_code>%%time
w = Variable(n)

lbound = 0.
ubound = 1. / n * 20

risk = sum_squares(multiply(special_risk_values[:n] / 100., w)) + quad_form((w.T * risk_exposure_values[:n]).T, risk_cov_values[:n, :n] / 10000.)

objective = Minimize(risk_penlty * risk  - signal * w)
constraints = [w >= lbound,
               w <= ubound,
               sum(w) == 1,]

prob = Problem(objective, constraints)
%%time
prob.solve(verbose=True)
prob.status, prob.value
%%time
prob.solve(verbose=True, solver='ECOS')
prob.status, prob.value
%%time
P = matrix(sec_cov_values)
q = -matrix(signal)

G = np.zeros((2*n, n))
h = np.zeros(2*n)
for i in range(n):
    G[i, i] = 1.
    h[i] = 1. / n * 20
    G[i+n, i] = -1.
    h[i+n] = 0.
    
G = matrix(G)
h = matrix(h)
    
A = np.ones((1, n))
b = np.ones(1)

A = matrix(A)
b = matrix(b)

sol = solvers.qp(P, q, G, h, A, b)
%%time
lbound = np.zeros(n)
ubound = np.ones(n) * 20 / n
cons_matrix = np.ones((1, n))
clb = np.ones(1)
cub = np.ones(1)
qpopt = QPOptimizer(signal,
                    None,
                    lbound,
                    ubound,
                    cons_matrix,
                    clb,
                    cub,
                    1.,
                    risk_cov_values[:n, :n] / 10000.,
                    risk_exposure_values[:n],
                    special_risk_values[:n] * special_risk_values[:n] / 10000.)
qpopt.feval()
qpopt.status()<jupyter_output><empty_output><jupyter_text>Performace Timing-------------------------<jupyter_code>import datetime as dt
def time_function(py_callable, n):
    start = dt.datetime.now()
    val = py_callable(n)
    return (dt.datetime.now() - start).total_seconds(), val
def cvxpy(n):
    w = Variable(n)

    lbound = 0.
    ubound = 0.01
    
    risk = sum_squares(multiply(special_risk_values[:n] / 100., w)) + quad_form((w.T * risk_exposure_values[:n]).T, risk_cov_values[:n, :n] / 10000.)

    objective = Minimize(risk_penlty * risk  - signal * w)
    constraints = [w >= lbound,
                   w <= ubound,
                   sum(w) == 1,]

    prob = Problem(objective, constraints)
    prob.solve(verbose=False, solver='ECOS')
    return prob.value
def cvxopt(n):
    P = matrix(sec_cov_values)
    q = -matrix(signal)

    G = np.zeros((2*n, n))
    h = np.zeros(2*n)
    for i in range(n):
        G[i, i] = 1.
        h[i] = 0.01
        G[i+n, i] = -1.
        h[i+n] = 0.

    G = matrix(G)
    h = matrix(h)

    A = np.ones((1, n))
    b = np.ones(1)

    A = matrix(A)
    b = matrix(b)
    
    solvers.options['show_progress'] = False
    sol = solvers.qp(P, q, G, h, A, b)
    return sol['primal objective']
def ipopt(n):
    lbound = np.zeros(n)
    ubound = np.ones(n) * 0.01
    cons_matrix = np.ones((1, n))
    clb = np.ones(1)
    cub = np.ones(1)
    qpopt = QPOptimizer(signal, None, lbound, ubound, cons_matrix, clb, cub, 1.,
                        risk_cov_values[:n, :n] / 10000.,
                        risk_exposure_values[:n],
                        special_risk_values[:n] * special_risk_values[:n] / 10000.)
    return qpopt.feval()
n_steps = list(range(200, 3201, 200))
cvxpy_times = [None] * len(n_steps)
cvxopt_times = [None] * len(n_steps)
ipopt_times = [None] * len(n_steps)
print("{0:<8}{1:>12}{2:>12}{3:>12}".format('Scale(n)', 'cvxpy', 'cvxopt', 'ipopt'))

for i, n in enumerate(n_steps):
    sec_cov_values = sec_cov_values_full[:n, :n]
    signal = signal_full[:n]
    cvxpy_times[i], val1 = time_function(cvxpy, n)
    cvxopt_times[i], val2 = time_function(cvxopt, n)
    ipopt_times[i], val3 = time_function(ipopt, n)
    
    np.testing.assert_almost_equal(val1, val2, 4)
    np.testing.assert_almost_equal(val2, val3, 4)
    
    print("{0:<8}{1:>12.4f}{2:>12.4f}{3:>12.4f}".format(n, cvxpy_times[i], cvxopt_times[i], ipopt_times[i]))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1684313725490196, 'fraction_numerical': 0.028823529411764706, 'mean_word_length': 2.8761398176291793, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '43692', 'license': 'MIT', 'n_tokens_mistral': 2133, 'n_tokens_neox': 1973, 'n_words': 376, 'path': 'notebooks/Example 10 - Quadratic Optimizer Comparison with CVXOPT.ipynb', 'repo_name': 'iLampard/alpha-mind', 'size': '5100'}