SeanChenTaipei 2 years ago
parent 9a1c7c7669
commit cbf7a80c7c
  1. 2
      main.py
  2. 2
      requirements.txt
  3. 4
      static/js/addStock.js
  4. 138
      templates/strategy_tw.html

@ -310,7 +310,7 @@ def buildPort():
# Query DB # Query DB
market_asset = '0050.TW' if session['tw']==1 else 'SPY' market_asset = '0050.TW' if session['tw']==1 else 'SPY'
conn = psycopg2.connect(**SQL_CONFIG) conn = psycopg2.connect(**SQL_CONFIG)
if 'market_asset' in stock_list: if market_asset in stock_list:
port = get_stock(conn, stock_list, session['tw']) port = get_stock(conn, stock_list, session['tw'])
market = port[market_asset] market = port[market_asset]
else: else:

@ -2,7 +2,7 @@ Flask==2.2.2
Flask-Login==0.6.2 Flask-Login==0.6.2
Flask-SQLAlchemy==3.0.3 Flask-SQLAlchemy==3.0.3
gunicorn==20.0.4 gunicorn==20.0.4
matplotlib==3.6.3 matplotlib
packaging==23.0 packaging==23.0
pandas==1.5.3 pandas==1.5.3
plotly==5.13.1 plotly==5.13.1

@ -127,17 +127,21 @@ $submitBtn.click(function(event) {
// console.log(cacheList.value, stockList); // console.log(cacheList.value, stockList);
if (stockList.length > 0) { if (stockList.length > 0) {
// cacheList = stockList; // cacheList = stockList;
$('#graph').html('<div class="spinner-border" role="status"><span class="visually-hidden">Loading...</span></div>')
$.ajax({ $.ajax({
url: '/postStock', //todo create_strategy url: '/postStock', //todo create_strategy
method: 'POST', method: 'POST',
data: { stockList: JSON.stringify(stockList) }, data: { stockList: JSON.stringify(stockList) },
success: function(response) { success: function(response) {
$('#graph').html('')
var graphs = JSON.parse(response); var graphs = JSON.parse(response);
Plotly.newPlot("graph", Plotly.newPlot("graph",
graphs.data, graphs.layout, {responsive: true}); graphs.data, graphs.layout, {responsive: true});
console.log(response.layout); console.log(response.layout);
}, },
error: function(xhr) { error: function(xhr) {
$('#graph').html('<div><span class="badge bg-warning">錯誤</span></div>')
console.log('Error submitting stock list: ' + xhr.responseText); console.log('Error submitting stock list: ' + xhr.responseText);
} }
}); });

@ -10,7 +10,7 @@
{% block title %}Strategy Page{% endblock%} {% block title %}Strategy Page{% endblock%}
{% block style %} {% block style %}
.input-group > input { <!-- .input-group > input {
border: 2px solid #8E8E8E; border: 2px solid #8E8E8E;
border-radius: 7px; border-radius: 7px;
} }
@ -21,10 +21,16 @@
.input-group-lg > select { .input-group-lg > select {
border: 2px solid #8E8E8E; border: 2px solid #8E8E8E;
border-radius: 7px; border-radius: 7px;
} } -->
.input-group > span{ <!-- .input-group > span{
bg-dark; bg-dark;
font-bold; font-bold;
} -->
div.input-group > * {
border-radius: 0px;
}
div.card{
border-radius: 2px;
} }
{% endblock style %} {% endblock style %}
@ -35,51 +41,51 @@
<div class="card mb-3"> <div class="card mb-3">
<!-- <img src="{{ url_for("static", filename="img/stock.jpeg") }}" class="card-img-top" alt="..."> --> <!-- <img src="{{ url_for("static", filename="img/stock.jpeg") }}" class="card-img-top" alt="..."> -->
<div class="card-body"> <div class="card-body">
<h5 class="card-title text-xl font-bold">投資組合建立步驟 <i class="bi bi-arrow-down-right-circle-fill"></i></h5> <h5 class="card-title text-xl font-bold">{% if session.tw == 1 %}台股{% endif %}投資組合建立步驟 <i class="bi bi-arrow-down-right-circle-fill"></i></h5>
<ol class="list-group list-group-flush list-group-numbered"> <ol class="list-group list-group-flush list-group-numbered">
<li class="list-group-item"><span class="ps-2">輸入投資組合名稱</span></li> <li class="list-group-item"><span class="ps-2">輸入投資組合名稱</span></li>
<li class="list-group-item"><span class="ps-2">選擇所參加的課程或競賽</span></li> <li class="list-group-item"><span class="ps-2">選擇所參加的課程或競賽</span></li>
<li class="list-group-item"><span class="ps-2">選擇資產 (可使用搜索功能篩選)</span></li> <li class="list-group-item"><span class="ps-2">選擇資產 (可使用搜索功能篩選)</span></li>
<li class="list-group-item"><span class="ps-2">確認資產後按下 "確認資產", 查看資產價格動態圖表</span></li> <li class="list-group-item"><span class="ps-2">確認資產後按下<span class="badge bg-info">確認資產</span>, 查看資產價格動態圖表</span></li>
<li class="list-group-item"><span class="ps-2">選擇訓練 / 回測數據比例與最佳化目標函數</span></li> <li class="list-group-item"><span class="ps-2">選擇訓練 / 回測數據比例與最佳化目標函數</span></li>
<li class="list-group-item"><span class="ps-2">確認後按下 "建立投資組合", 查看回傳訊息</span></li> <li class="list-group-item"><span class="ps-2">確認後按下<span class="badge bg-danger">確認建立</span>, 查看回傳訊息</span></li>
</ol> </ol>
</div> </div>
</div> </div>
<div class="input-group-lg"> <div class="card">
<label for="input1" class="form-label text-xl font-bold">投資組合名稱</label> <div class="card-header font-bold text-lg">
<input if="imput1" name="portName" type="text" class="form-control" placeholder="EX. 空軍一號" required> 投資組合名稱
</div> </div>
<div class="input-group-lg mb-3"> <div class="card-body">
<label for="competition" class="form-label text-xl font-bold">請選擇所參加的課程/競賽</label> <input if="imput1" name="portName" type="text" class="form-control" placeholder="EX. " required>
<select id="competition" class="form-select" size="1"> </div>
{% include 'competitions.html' %}
</select>
</div> </div>
<label for="stockAll" class="form-label text-xl font-bold">選擇資產:</label> <div class="card">
<div class="mb-3 input-group d-flex"> <div class="card-header font-bold text-lg">
<input name="assetSelect" class="form-control" list="datalistOptions" id="stockAll" placeholder="輸入資產名稱..."> 請選擇所參加的課程/競賽
<datalist id="datalistOptions"> </div>
{% if session.tw==0 %} <div class="card-body">
{% for key, data in data_us.items() -%} <select id="competition" class="form-select" size="1">
<option value="{{ key|e }}">{{ key|e }} | {{ data|e }}</option> {% include 'competitions.html' %}
{% endfor %} </select>
{% endif %} </div>
{% for key, data in data_tw.items() -%}
<option value="{{ key|e }}">{{ key|e }} | {{ data|e }} </option>
{% endfor %}
</datalist>
<button class="btn btn-secondary"
type="button btn-lg"
id="addStockBtn">
加入
</button>
</div> </div>
<hr class="my-3"> <hr class="my-3">
<div class="card">
<div class="card-header ">
<div class="py-2 font-bold text-lg">
價格動態圖表
</div>
</div>
<div class="card-body">
<div id="graph"></div>
</div>
</div>
<div class="card"> <div class="card">
<div class="card-header d-flex"> <div class="card-header d-flex">
<div class="py-2 font-bold"> <div class="py-2 font-bold text-lg-center">
已選擇的資產 已選擇的資產
</div> </div>
<div class="btn-group ms-auto"> <div class="btn-group ms-auto">
@ -91,35 +97,57 @@
</button> </button>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-body d-flex mb-0">
<div class="input-group mb-3"> <input name="assetSelect" class="form-control" list="datalistOptions" id="stockAll" placeholder="輸入資產名稱...">
<!-- <span class="input-group-text me-auto bg-info" id="inputGroup3">請選擇訓練/回測數據比例</span> --> <datalist id="datalistOptions">
<select id="ratio-select" class="form-select"> {% if session.tw==0 %}
<option value="0.5">5:5</option> {% for key, data in data_us.items() -%}
<option value="0.6">6:4</option> <option value="{{ key|e }}">{{ key|e }} | {{ data|e }}</option>
<option selected value="0.7">7:3</option> {% endfor %}
<option value="0.8">8:2</option> {% endif %}
<option value="0.9">9:1</option> {% for key, data in data_tw.items() -%}
</select> <option value="{{ key|e }}">{{ key|e }} | {{ data|e }} </option>
<select id="role-select" class="form-select"> {% endfor %}
<option selected value="max_sharpe">最大化夏普比率</option> </datalist>
<option value="max_sortino">最大化索提諾比率</option> <button class="btn btn-secondary"
<option value="min_volatility">最小化波動率</option> type="button btn-lg"
</select> id="addStockBtn">
</div> 加入
</button>
<ol class="list-group list-group-numbered" id="stock-list" type="1"> </div>
<hr class="mb-3">
<div>
<ol class="list-group list-group-numbered px-3 pb-3" id="stock-list" type="1">
<li class="list-group-item"> <li class="list-group-item">
<span class="px-2">2330.TW | 台積電 | 2000-01-05 ~</span> <span class="px-2">2330.TW | 台積電</span>
<a class="btn btn-sm btn-danger float-right delete-btn"> <a class="btn btn-sm btn-danger float-right delete-btn">
<i class="fas fa-trash-alt"></i> <i class="fas fa-trash-alt"></i>
</a> </a>
</li> </li>
</ol> </ol>
</div> </div>
<hr class="my-3"> <div class="input-group mt-3">
<div id="graph" style="border-radius: 10px;"></div> <span class="input-group-text bg-info">訓練 / 回測數據比</span>
<select id="ratio-select" class="form-select">
<option value="0.5">5:5</option>
<option value="0.6">6:4</option>
<option selected value="0.7">7:3</option>
<option value="0.8">8:2</option>
<option value="0.9">9:1</option>
</select>
</div>
<div class="input-group">
<span class="input-group-text bg-info">最佳化目標函數</span>
<select id="role-select" class="form-select">
<option selected value="max_sharpe">最大化夏普比率</option>
<option value="max_sortino">最大化索提諾比率</option>
<option value="min_volatility">最小化波動率</option>
</select>
</div>
</div> </div>
<div class="modal" id="portModal" tabindex="-1"> <div class="modal" id="portModal" tabindex="-1">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">

Loading…
Cancel
Save