Commit ae63c24a authored by Dr.李's avatar Dr.李

fixed bug for mv optimizer

parent 857b3ce6
...@@ -230,8 +230,8 @@ def factor_analysis(factors: pd.DataFrame, ...@@ -230,8 +230,8 @@ def factor_analysis(factors: pd.DataFrame,
lbound, ubound, cons_exp, risk_lbound, risk_ubound = create_constraints(benchmark, **kwargs) lbound, ubound, cons_exp, risk_lbound, risk_ubound = create_constraints(benchmark, **kwargs)
cov = kwargs['cov'] cov = kwargs['cov']
if 'lambda' in kwargs: if 'lam' in kwargs:
lam = kwargs['lambda'] lam = kwargs['lam']
else: else:
lam = 1. lam = 1.
......
...@@ -209,33 +209,18 @@ class SqlEngine(object): ...@@ -209,33 +209,18 @@ class SqlEngine(object):
if __name__ == '__main__': if __name__ == '__main__':
db_url = 'mssql+pymssql://licheng:A12345678!@10.63.6.220/alpha?charset=cp936' db_url = 'mssql+pymssql://licheng:A12345678!@10.63.6.220/alpha?charset=cp936'
from alphamind.data.dbmodel.models import Uqer
import datetime as dt import datetime as dt
universe = Universe('custom', ['ashare']) universe = Universe('custom', ['zz500'])
engine = SqlEngine(db_url) engine = SqlEngine(db_url)
ref_date = '2017-07-21' ref_date = '2017-01-17'
codes = engine.fetch_codes(ref_date, universe) codes = engine.fetch_codes(ref_date, universe)
data = engine.fetch_data(ref_date, ['EPS'], codes, 905)
d1ret = engine.fetch_dx_return(ref_date, codes, horizon=0)
start = dt.datetime.now() missing_codes = [c for c in data['factor'].Code if c not in set(d1ret.Code)]
for i in range(100):
codes = engine.fetch_codes(ref_date, universe)
print(dt.datetime.now() - start)
print(codes)
print(len(codes))
universe = Universe('zz500', ['zz500'])
engine = SqlEngine(db_url)
ref_date = '2017-07-04'
start = dt.datetime.now()
for i in range(100):
codes = engine.fetch_codes(ref_date, universe)
print(dt.datetime.now() - start)
print(codes)
print(len(codes))
print(len(data['factor']))
print(len(d1ret))
print(missing_codes)
...@@ -5,69 +5,80 @@ Created on 2017-7-10 ...@@ -5,69 +5,80 @@ Created on 2017-7-10
@author: cheng.li @author: cheng.li
""" """
import datetime as dt import numpy as np
import pandas as pd import pandas as pd
from alphamind.analysis.factoranalysis import factor_analysis from alphamind.analysis.factoranalysis import factor_analysis
from alphamind.data.engines.sqlengine import risk_styles
from alphamind.data.engines.sqlengine import industry_styles
from alphamind.portfolio.constraints import Constraints
from alphamind.data.engines.sqlengine import SqlEngine from alphamind.data.engines.sqlengine import SqlEngine
from alphamind.data.engines.universe import Universe from alphamind.data.engines.universe import Universe
from alphamind.data.engines.sqlengine import industry_styles
from PyFin.api import bizDatesList from PyFin.api import bizDatesList
from PyFin.api import makeSchedule
engine = SqlEngine('mssql+pymssql://licheng:A12345678!@10.63.6.220/alpha') engine = SqlEngine('mssql+pymssql://licheng:A12345678!@10.63.6.220/alpha')
universe = Universe('custom', ['zz500']) universe = Universe('custom', ['zz500'])
dates = bizDatesList('china.sse', '2017-01-01', '2017-08-05')
factors = ['EPS', 'FEARNG', 'VAL', 'NIAP']
f_weights = np.array([1., 1., 1., 1.])
used_risk_styles = ['SIZE'] neutralize_risk = ['SIZE'] + industry_styles
constraint_risk = []
total_risks = used_risk_styles + industry_styles
build_type = 'risk_neutral'
def calculate_one_day(ref_date, factors, factor_weights, horizon_end=None): rets = []
print(ref_date)
for date in dates:
print(date)
ref_date = date.strftime('%Y-%m-%d')
codes = engine.fetch_codes(ref_date, universe) codes = engine.fetch_codes(ref_date, universe)
total_data = engine.fetch_data(ref_date, factors, codes, 905) data = engine.fetch_data(ref_date, factors, codes, 905, risk_model='short')
returns = engine.fetch_dx_return(ref_date, codes, 0)
factor_data = total_data['factor']
factor_df = factor_data[['Code', 'industry', 'weight', 'isOpen'] + total_risks + factors].dropna() total_data = pd.merge(data['factor'], returns, on=['Code']).dropna()
risk_cov = data['risk_cov']
dx_return = engine.fetch_dx_return(ref_date, codes, expiry_date=horizon_end)
factor_df = pd.merge(factor_df, dx_return, on=['Code']) total_risks = risk_cov.Factor
risk_cov = risk_cov[total_risks]
weights, _ = factor_analysis(factor_df[factors], risk_exp = total_data[total_risks]
factor_weights, stocks_cov = ((risk_exp.values @ risk_cov.values @ risk_exp.values.T) + np.diag(total_data.SRISK ** 2)) / 10000.
factor_df.industry.values,
None, f_data = total_data[factors]
detail_analysis=False,
benchmark=factor_df.weight.values, industry = total_data.industry_code.values
risk_exp=factor_df[total_risks].values, dx_return = total_data.dx.values
is_tradable=factor_df.isOpen.values.astype(bool), benchmark = total_data.weight.values
method=build_type) risk_exp = total_data[neutralize_risk].values
constraint_exp = total_data[constraint_risk].values
return ref_date, (weights.weight - factor_df.weight).dot(factor_df.dx) risk_exp_expand = np.concatenate((constraint_exp, np.ones((len(risk_exp), 1))), axis=1).astype(float)
risk_names = constraint_risk + ['total']
if __name__ == '__main__': risk_target = risk_exp_expand.T @ benchmark
from matplotlib import pyplot as plt lbound = 0.
ubound = 0.05 + benchmark
factors = ['BDTO', 'CFinc1', 'DivP', 'EPS', 'RVOL', 'DROEAfterNonRecurring']
factor_weights = [0.10, 0.30, 0.15, 0.18, 0.11, 0.35] constraint = Constraints(risk_exp_expand, risk_names)
biz_dates = makeSchedule('2015-01-01', '2017-07-07', '1w', 'china.sse') for i, name in enumerate(risk_names):
constraint.set_constraints(name, lower_bound=risk_target[i], upper_bound=risk_target[i])
ers = []
dates = [] try:
pos, analysis = factor_analysis(f_data,
for i, ref_date in enumerate(biz_dates[:-1]): f_weights,
ref_date = ref_date.strftime("%Y-%m-%d") industry,
try: dx_return,
ref_date, er = calculate_one_day(ref_date, factors, factor_weights, horizon_end=biz_dates[i+1]) benchmark=benchmark,
dates.append(ref_date) risk_exp=risk_exp,
ers.append(er) is_tradable=total_data.isOpen.values.astype(bool),
except Exception as e: method='mv',
print(str(e) + ": {0}".format(ref_date)) constraints=constraint,
cov=stocks_cov,
res = pd.Series(ers, index=dates) use_rank=100,
res.cumsum().plot() lam=100.,
plt.show() lbound=lbound,
ubound=ubound)
except:
rets.append(0.)
print("{0} is error!".format(date))
else:
rets.append(analysis.er[-1])
ret_series = pd.Series(rets, dates)
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"cells": [ "cells": [
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 1,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 2,
"metadata": { "metadata": {
"collapsed": true "collapsed": true
}, },
...@@ -26,8 +26,10 @@ ...@@ -26,8 +26,10 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 3,
"metadata": {}, "metadata": {
"collapsed": true
},
"outputs": [], "outputs": [],
"source": [ "source": [
"def time_function(py_callable, n):\n", "def time_function(py_callable, n):\n",
...@@ -66,13 +68,36 @@ ...@@ -66,13 +68,36 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 4,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Scale(n) time(ms) feval min(x) max(x) sum(x) x(0) + x(1)\n",
"200 18.01 -0.82 0.000000 0.010000 1.000000 0.015\n",
"400 23.02 -1.28 -0.000000 0.010000 1.000000 0.015\n",
"600 42.63 -1.54 -0.000000 0.010000 1.000000 0.015\n",
"800 62.04 -1.63 -0.000000 0.010000 1.000000 0.015\n",
"1000 76.57 -1.72 -0.000000 0.010000 1.000000 0.015\n",
"1200 108.73 -1.81 -0.000000 0.010000 1.000000 0.015\n",
"1400 136.22 -1.90 -0.000000 0.010000 1.000000 0.015\n",
"1600 166.64 -1.96 -0.000000 0.010000 1.000000 0.015\n",
"1800 197.72 -2.03 -0.000000 0.010000 1.000000 0.015\n",
"2000 258.51 -2.06 -0.000000 0.010000 1.000000 0.015\n",
"2200 291.34 -2.07 -0.000000 0.010000 1.000000 0.015\n",
"2400 348.30 -2.13 -0.000000 0.010000 1.000000 0.015\n",
"2600 398.31 -2.14 -0.000000 0.010000 1.000000 0.015\n",
"2800 462.13 -2.16 -0.000000 0.010000 1.000000 0.015\n",
"3000 547.84 -2.19 -0.000000 0.010000 1.000000 0.015\n"
]
}
],
"source": [ "source": [
"print(\"{0:<8}{1:>12}{2:>12}{3:>12}{4:>12}{5:>12}{6:>15}\".format('Scale(n)', 'time(ms)', 'feval', 'min(x)', 'max(x)', 'sum(x)', 'x(0) + x(1)'))\n", "print(\"{0:<8}{1:>12}{2:>12}{3:>12}{4:>12}{5:>12}{6:>15}\".format('Scale(n)', 'time(ms)', 'feval', 'min(x)', 'max(x)', 'sum(x)', 'x(0) + x(1)'))\n",
"\n", "\n",
"for n in range(200, 10200, 200):\n", "for n in range(200, 3200, 200):\n",
" elapsed, result = time_function(cvxpy_lp, n)\n", " elapsed, result = time_function(cvxpy_lp, n)\n",
" s = np.array(result[0].value).flatten()\n", " s = np.array(result[0].value).flatten()\n",
" print(\"{0:<8}{1:>12.2f}{2:>12.2f}{3:>12f}{4:>12f}{5:>12f}{6:>15}\".format(n, elapsed*1000, result[1].value, s.min(), s.max(), s.sum(), s[0] + s[1]))" " print(\"{0:<8}{1:>12.2f}{2:>12.2f}{3:>12f}{4:>12f}{5:>12f}{6:>15}\".format(n, elapsed*1000, result[1].value, s.min(), s.max(), s.sum(), s[0] + s[1]))"
...@@ -80,7 +105,7 @@ ...@@ -80,7 +105,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 7,
"metadata": { "metadata": {
"collapsed": true "collapsed": true
}, },
...@@ -105,13 +130,36 @@ ...@@ -105,13 +130,36 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 8,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Scale(n) time(ms) feval min(x) max(x) sum(x) x(0) + x(1)\n",
"200 19.01 -0.82 0.000000 0.010000 1.000000 0.015\n",
"400 1.00 -1.28 0.000000 0.010000 1.000000 0.015\n",
"600 2.00 -1.54 0.000000 0.010000 1.000000 0.015\n",
"800 3.00 -1.63 0.000000 0.010000 1.000000 0.015\n",
"1000 2.00 -1.72 0.000000 0.010000 1.000000 0.015\n",
"1200 3.00 -1.81 0.000000 0.010000 1.000000 0.015\n",
"1400 2.02 -1.90 0.000000 0.010000 1.000000 0.015\n",
"1600 2.02 -1.96 0.000000 0.010000 1.000000 0.015\n",
"1800 1.98 -2.03 0.000000 0.010000 1.000000 0.015\n",
"2000 2.02 -2.06 0.000000 0.010000 1.000000 0.015\n",
"2200 2.00 -2.07 0.000000 0.010000 1.000000 0.015\n",
"2400 2.00 -2.13 0.000000 0.010000 1.000000 0.015\n",
"2600 3.00 -2.14 0.000000 0.010000 1.000000 0.015\n",
"2800 3.02 -2.16 0.000000 0.010000 1.000000 0.015\n",
"3000 3.00 -2.19 0.000000 0.010000 1.000000 0.015\n"
]
}
],
"source": [ "source": [
"print(\"{0:<8}{1:>12}{2:>12}{3:>12}{4:>12}{5:>12}{6:>15}\".format('Scale(n)', 'time(ms)', 'feval', 'min(x)', 'max(x)', 'sum(x)', 'x(0) + x(1)'))\n", "print(\"{0:<8}{1:>12}{2:>12}{3:>12}{4:>12}{5:>12}{6:>15}\".format('Scale(n)', 'time(ms)', 'feval', 'min(x)', 'max(x)', 'sum(x)', 'x(0) + x(1)'))\n",
"\n", "\n",
"for n in range(200, 10200, 200):\n", "for n in range(200, 3200, 200):\n",
" elapsed, result = time_function(clp_lp, n)\n", " elapsed, result = time_function(clp_lp, n)\n",
" s = result[2]\n", " s = result[2]\n",
" print(\"{0:<8}{1:>12.2f}{2:>12.2f}{3:>12f}{4:>12f}{5:>12f}{6:>15}\".format(n, elapsed*1000, result[1], s.min(), s.max(), s.sum(), s[0] + s[1]))" " print(\"{0:<8}{1:>12.2f}{2:>12.2f}{3:>12f}{4:>12f}{5:>12f}{6:>15}\".format(n, elapsed*1000, result[1], s.min(), s.max(), s.sum(), s[0] + s[1]))"
...@@ -129,7 +177,7 @@ ...@@ -129,7 +177,7 @@
], ],
"metadata": { "metadata": {
"kernelspec": { "kernelspec": {
"display_name": "Python [default]", "display_name": "Python 3",
"language": "python", "language": "python",
"name": "python3" "name": "python3"
}, },
......
This diff is collapsed.
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