diff --git a/main.py b/main.py index d81c2d0..0d36527 100644 --- a/main.py +++ b/main.py @@ -118,6 +118,8 @@ def index(): # Login Page @app.route('/login') def login(): + if 'username' in session: + return render_template('base.html') return render_template('login.html') @app.route('/login', methods=['POST']) def login_post(): @@ -325,9 +327,9 @@ def buildPort(): n = len(port.index) if n < lookback+backtest+63: return f'''投資組合無法建立,資料長度與所選參數不符。''' - elif n > 909+lookback: - port = port.iloc[-(909+lookback):, :] - market = market.iloc[-909:] + elif n > 1009+lookback: + port = port.iloc[-(1009+lookback):, :] + market = market.iloc[-1009:] else: market = market.iloc[lookback:] @@ -341,7 +343,7 @@ def buildPort(): # Get portfolio info. - info = MVO.portfolio_info(np.array([1]), rets['Portfolio'].to_numpy().reshape(-1, 1), rets['Equally'].to_numpy()) + info = MVO.portfolio_info(np.array([1]), rets['Portfolio'].to_numpy().reshape(-1, 1), market.pct_change().dropna().to_numpy()) data = (ts, name, session.get('username').split('@')[0], comp, role, info['annual_ret'], info['vol'], info['mdd'], info['annual_sr'], info['beta'], info['alpha'], info['var10'], info['R2'], True, comment, stock_list, json.dumps(weight.to_dict()), json.dumps(rets.to_dict())) @@ -365,7 +367,61 @@ def custom(): else: flash('使用投組功能請先登入。', 'warning') return redirect(url_for('login')) - return render_template('custom.html', message='No') + return render_template('custom.html') +@app.route('/custom', methods=['POST']) +def custom_post(): + if login_required(): + pass + else: + flash('使用投組功能請先登入。', 'warning') + return redirect(url_for('login')) + port = pd.read_csv(request.files['csv_file'], index_col=0, parse_dates=True) + role = request.form.get('role') + lookback = int(request.form.get('lookback')) + backtest = int(request.form.get('frequency')) + gamma = float(request.form.get('gamma'))/100 + # Optimization + n = len(port.index) + if n < lookback+backtest+63: + return f'''投資組合無法建立,資料長度與所選參數不符。''' + elif n > 1009+lookback: + port = port.iloc[-(1009+lookback):, :] + else: + pass + length, num = port.shape + ret = port.pct_change().dropna() + weight, rets = rolling_optimize(ret, lookback, backtest, role=role, gamma=gamma) + weight.index = weight.index.astype(str) + rets.index = rets.index.astype(str) + rets= rets.round(5) + + info = MVO.portfolio_info(np.array([1]), rets['Portfolio'].to_numpy().reshape(-1, 1), np.zeros(len(ret)-lookback)) + info['username'] = session.get('username').split('@')[0] + info['role'] = role_map[role] + info['id']='使用者自行上傳' + info['name']='使用者自行上傳' + info['date'] = '-' + info['alpha'] = '-' + info['beta'] = '-' + info['r2'] = '-' + info['assets'] = list(port.columns) + # Plotting weight + fig = px.bar(weight) + fig['layout'] = {} + info['weight'] = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder) + # Plotting weight + fig = (rets+1).cumprod().iloc[::5, :].plot() + fig['layout'] = {} + info['ret'] = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder) + # Plotting ret bars + rets.index.name = 'date' + rets.index = pd.to_datetime(rets.index) + ret_hist = rets.to_period('Q').groupby('date').apply(lambda x: (x+1).prod()-1) + ret_hist.index = ret_hist.index.astype(str) + fig = px.bar(ret_hist) + fig['layout'] = {} + info['bar'] = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder) + return render_template('result_view.html', data=info) @app.route('/result', methods=['GET', 'POST']) diff --git a/static/img/file.jpg b/static/img/file.jpg new file mode 100644 index 0000000..0c50114 Binary files /dev/null and b/static/img/file.jpg differ diff --git a/static/img/file.png b/static/img/file.png new file mode 100644 index 0000000..9a634fa Binary files /dev/null and b/static/img/file.png differ diff --git a/static/js/addStock.js b/static/js/addStock.js index a5472e4..d120ae9 100644 --- a/static/js/addStock.js +++ b/static/js/addStock.js @@ -92,8 +92,6 @@ $sendPort.click(function(event) { if (stockList.length > 1){ // $('#confirmMes').replaceWith("投資組合已開始建立,請等待完成訊息,或1分鐘後至分析結果區查看!") // $('#confirmModal').modal('show'); - - $submitPort.prop('disabled', true); $.ajax({ url: '/postPort', //todo create_strategy diff --git a/templates/custom.html b/templates/custom.html index c2eb06e..1d8a791 100644 --- a/templates/custom.html +++ b/templates/custom.html @@ -4,7 +4,91 @@ {% block title %}Strategy Page{% endblock%} {% block content %} -