SeanChenTaipei 2 years ago
parent b5582fef3b
commit 07f7686a7d
  1. 35
      main.py
  2. 28
      portfolio_builder.py
  3. 5
      static/js/addStock.js
  4. 2
      templates/strategy_tw.html

@ -20,25 +20,25 @@ pd.options.plotting.backend = "plotly"
# PARAMETERS
CONFIGS = {
"ENV": "development",
"DEBUG": True,
# "ENV": "development",
# "DEBUG": True,
"SECRET_KEY": os.urandom(30), # Set the secret key for session authentication
"PERMANENT_SESSION_LIFETIME": timedelta(minutes=60)
}
# SQL_CONFIG = dict(
# database= os.getenv("PGDATABASE"),
# user=os.getenv("PGUSER"),
# host=os.getenv("PGHOST"),
# port=os.getenv("PGPORT"),
# password=os.getenv("PGPASSWORD")
# )
SQL_CONFIG = dict(
database="railway",
user="postgres",
host="containers-us-west-103.railway.app",
port="5913",
password="gv5Mh7cPjCm9YTjAmsYD"
database= os.getenv("PGDATABASE"),
user=os.getenv("PGUSER"),
host=os.getenv("PGHOST"),
port=os.getenv("PGPORT"),
password=os.getenv("PGPASSWORD")
)
# SQL_CONFIG = dict(
# database="railway",
# user="postgres",
# host="containers-us-west-103.railway.app",
# port="5913",
# password="gv5Mh7cPjCm9YTjAmsYD"
# )
# SQL_CONFIG = {
# 'database': "tpm",
# 'user': "hsienchen",
@ -178,10 +178,6 @@ def logout():
flash('請先登入。', 'warning')
return redirect(url_for('login'))
if 'username' in session:
# for key in list(session.keys()):
# print(key, session[key])
# for key in list(session.keys()):
# session.pop(key)
session.clear()
return redirect(url_for('index'))
@ -254,7 +250,6 @@ def submit_stock_list():
print(key, request.form[key])
# Do something with the stock list heres
return graphJSON
# return jsonify({'message': 'Stock list received successfully, NOOOOO'})
@app.route('/postPort', methods=['POST'])
def buildPort():
@ -341,7 +336,7 @@ def buildPort():
strategy_id = curs.fetchone()[0]
conn.close()
print("\n------Write in Success--------\n")
return f'''<span>投資組合已完成建立,請至 <a class="badge rounded-pill text-bg-primary" href="/result_view?strategy_id={strategy_id}"><span class="badge bg-success">{strategy_id}</span></a>查詢分析結果。</span>'''
return f'''<span>投資組合已完成建立,請至 <a class="badge rounded-pill text-bg-warning" href="/result_view?strategy_id={strategy_id}">{strategy_id}</a>查詢分析結果。</span>'''

@ -60,8 +60,8 @@ class MVO(object):
retPort = ret@w # T-dimensional array
stdPort = np.std(retPort)
g1=manual_ret/stdPort
g2=np.mean(retPort)*(-0.5)*stdPort**(-3)*(2*cov@w)
return g1+g2
g2=np.mean(retPort)*stdPort**(-3)*cov@w
return g1-g2
@staticmethod
def sortino_ratio(w, ret):
retPort = ret@w # T-dimensional array
@ -74,8 +74,23 @@ class MVO(object):
retPort = ret@w # T-dimensional arrayss
stdPort = np.std(retPort)
g1=manual_ret/stdPort
g2=np.mean(retPort)*(-0.5)*stdPort**(-3)*(2*cov_sor@w)
return g1+g2
g2=np.mean(retPort)*stdPort**(-3)*cov_sor@w
return g1-g2
@staticmethod
def sortino_ratio(w, ret):
retPort = ret@w # T-dimensional array
stdPort = np.std(np.maximum(-retPort, 0))
return np.mean(retPort)/stdPort
@staticmethod
def sortino_grad(w, ret, cov_sor):
manual_ret = np.mean(ret, axis=0)
# print(cov.shape, w.shape)
retPort = ret@w # T-dimensional arrayss
stdPort = np.std(retPort)
g1=manual_ret/stdPort
g2=np.mean(retPort)*stdPort**(-3)*cov_sor@w
return g1-g2
@staticmethod
def volatility(w, ret):
retPort = ret@w # T-dimensional array
@ -85,7 +100,7 @@ class MVO(object):
def volatility_grad(w, ret, cov):
retPort = ret@w # T-dimensional array
stdPort = np.std(retPort)
return cov@w/stdPort**(0.5)
return cov@w/stdPort
@classmethod
def opt(cls, ret, role="max_sharpe"):
n = ret.shape[1]
@ -105,11 +120,12 @@ class MVO(object):
else:
return init
bnds = [[0, 0.6] for i in range(n)]
opts = {'maxiter': 10000, 'disp': False}
opts = {'maxiter': 1000, 'disp': False}
cons = ({'type': 'eq', 'fun': lambda w: np.sum(w) - 1})
result = minimize(loss, init, method="SLSQP",\
options=opts, bounds=bnds, tol = None, jac = grad, constraints=cons)
sol = result['x']
print(sol)
return np.round(sol, 2)

@ -1,7 +1,8 @@
// Initialize empty stock list
let stockList = ['2330.TW'];
let currentList = [];
const layout={'autosize': true, 'title': {'text': 'Assets'},
const layout={'autosize': true, 'markers':true,
'title': {'text': 'Assets'},
'xaxis': {'anchor': 'y', 'domain': [0.0, 1.0],
'rangeslider': {'visible': true},
'rangeselector':{'rangeselector':
@ -10,7 +11,7 @@ const layout={'autosize': true, 'title': {'text': 'Assets'},
{'count': 6, 'label': '6m', 'step': 'month', 'stepmode': 'backward'},
{'count': 1, 'label': 'YTD', 'step': 'year', 'stepmode': 'todate'},
{'count': 1, 'label': '1y', 'step': 'year', 'stepmode': 'backward'}, {'step': 'all'}]}, 'rangeslider': {'visible': true},'type': 'date'}},
'yaxis': {'anchor': 'x', 'domain': [0.0, 0.9]},
'yaxis': {'anchor': 'x', 'domain': [0.0, 1.0], 'fixedrange': false},
'legend': {'yanchor': 'top', 'y': 1.8, 'xanchor': 'left', 'x': 0.01}, 'margin': {'l': 25, 'r': 5, 't': 10, 'b': 5},
}
// Cache frequently-used DOM elements

@ -123,7 +123,7 @@ div.card{
</div>
<div class="card-body">
<div id="graph" style="max-height:50vh">
<div id="graph" style="max-height:60vh">
<span>
按下
<button type="button" class="btn btn-outline-primary btn-sm" disabled>確認資產</button>

Loading…
Cancel
Save