master
SeanChenTaipei 2 years ago
parent f61bcb4791
commit 0357b22ec9
  1. 68
      main.py
  2. BIN
      static/img/growth.png
  3. 1
      static/js/addStock.js
  4. 86
      t.html
  5. 31
      templates/base.html
  6. 91
      templates/result.html

@ -25,20 +25,20 @@ CONFIGS = {
"SECRET_KEY": os.urandom(30), # Set the secret key for session authentication "SECRET_KEY": os.urandom(30), # Set the secret key for session authentication
"PERMANENT_SESSION_LIFETIME": timedelta(minutes=60) "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( # SQL_CONFIG = dict(
# database="railway", # database= os.getenv("PGDATABASE"),
# user="postgres", # user=os.getenv("PGUSER"),
# host="containers-us-west-103.railway.app", # host=os.getenv("PGHOST"),
# port="5913", # port=os.getenv("PGPORT"),
# password="gv5Mh7cPjCm9YTjAmsYD" # password=os.getenv("PGPASSWORD")
# ) # )
SQL_CONFIG = dict(
database="railway",
user="postgres",
host="containers-us-west-103.railway.app",
port="5913",
password="gv5Mh7cPjCm9YTjAmsYD"
)
# SQL_CONFIG = { # SQL_CONFIG = {
# 'database': "tpm", # 'database': "tpm",
# 'user': "hsienchen", # 'user': "hsienchen",
@ -337,12 +337,12 @@ def buildPort():
train_info = MVO.portfolio_info(sol, train, train_market) train_info = MVO.portfolio_info(sol, train, train_market)
test_info = MVO.portfolio_info(sol, test, test_market) test_info = MVO.portfolio_info(sol, test, test_market)
# print(sol, train_info, test_info) # print(sol, train_info, test_info)
print("-"*10) # print("-"*10)
print(ts, name, session.get('username'), comp, # print(ts, name, session.get('username'), comp,
role, test_info['annual_ret'], test_info['vol'], test_info['mdd'], test_info['annual_sr'], # role, test_info['annual_ret'], test_info['vol'], test_info['mdd'], test_info['annual_sr'],
test_info['beta'], test_info['alpha'], test_info['var10'], test_info['R2'], True, comment, stock_list, list(sol), sep=", ") # test_info['beta'], test_info['alpha'], test_info['var10'], test_info['R2'], True, comment, stock_list, list(sol), sep=", ")
print("-"*10) # print("-"*10)
data = (ts, name, session.get('username'), comp, data = (ts, name, session.get('username').split('@')[0], comp,
role, ratio, test_info['annual_ret'], test_info['vol'], test_info['mdd'], test_info['annual_sr'], role, ratio, test_info['annual_ret'], test_info['vol'], test_info['mdd'], test_info['annual_sr'],
test_info['beta'], test_info['alpha'], test_info['var10'], test_info['R2'], True, comment, stock_list, list(sol)) test_info['beta'], test_info['alpha'], test_info['var10'], test_info['R2'], True, comment, stock_list, list(sol))
sql='insert into strategy \ sql='insert into strategy \
@ -355,6 +355,8 @@ def buildPort():
print("\n------Write in Success--------\n") print("\n------Write in Success--------\n")
return jsonify({'mes': '投資組合已完成建立,請至<a href"/">gooooooo</a>查詢分析結果。'}) return jsonify({'mes': '投資組合已完成建立,請至<a href"/">gooooooo</a>查詢分析結果。'})
@app.route('/custom') @app.route('/custom')
def custom(): def custom():
if login_required(): if login_required():
@ -363,6 +365,8 @@ def custom():
flash('使用投組功能請先登入。', 'warning') flash('使用投組功能請先登入。', 'warning')
return redirect(url_for('login')) return redirect(url_for('login'))
return render_template('custom.html', message='No') return render_template('custom.html', message='No')
@app.route('/result') @app.route('/result')
def result(): def result():
if login_required(): if login_required():
@ -370,15 +374,25 @@ def result():
else: else:
flash('使用投組功能請先登入。', 'warning') flash('使用投組功能請先登入。', 'warning')
return redirect(url_for('login')) return redirect(url_for('login'))
return render_template('result.html')
@app.route('/result_tw') sql="""select id, date, name, username, annual_ret, vol, annual_sr\
def result_tw(): from strategy order by id desc limit 100;"""
if login_required(): conn = psycopg2.connect(**SQL_CONFIG)
pass with conn:
else: with conn.cursor() as curs:
flash('使用投組功能請先登入。', 'warning') curs.execute(sql)
return redirect(url_for('login')) data= curs.fetchall()
return render_template('result_tw.html') conn.close()
return render_template('result.html', strategy_data=data)
# @app.route('/result_tw')
# def result_tw():
# if login_required():
# pass
# else:
# flash('使用投組功能請先登入。', 'warning')
# return redirect(url_for('login'))
# return render_template('result_tw.html')
# handle login failed # handle login failed
@app.errorhandler(401) @app.errorhandler(401)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 B

@ -54,6 +54,7 @@ $stockList.on('click', '.delete-btn', function(){
$addStockBtn.click(function(event) { $addStockBtn.click(function(event) {
event.preventDefault(); event.preventDefault();
$('#search').val(''); $('#search').val('');
$('#search').trigger("keyup");
// Get selected stock from form // Get selected stock from form
const selectedStock = $stockSelect.val(); const selectedStock = $stockSelect.val();
var text = $('#stock-select option:selected').text(); var text = $('#stock-select option:selected').text();

@ -0,0 +1,86 @@
<!DOCTYPE html>
<html>
<head>
<title>Serial Information</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Serial Information</h1>
<!-- Button group for filtering -->
<div class="btn-group mb-3">
<button type="button" class="btn btn-primary filter" data-filter="all">All</button>
<button type="button" class="btn btn-primary filter" data-filter="serial001">Serial 001</button>
<button type="button" class="btn btn-primary filter" data-filter="serial002">Serial 002</button>
<button type="button" class="btn btn-primary filter" data-filter="serial003">Serial 003</button>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>Serial Number</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="filter-item serial001">
<td>001</td>
<td><a href="#">Serial 001 Information</a></td>
</tr>
<tr class="filter-item serial002">
<td>002</td>
<td><a href="#">Serial 002 Information</a></td>
</tr>
<tr class="filter-item serial003">
<td>003</td>
<td><a href="#">Serial 003 Information</a></td>
</tr>
</tbody>
</table>
<div class="card h-100">
<img src="{{ item.image }}" class="card-img-top" alt="{{ item.title }}">
<div class="card-body">
<h5 class="card-title"><a href="{{ item.href }}">{{ item.title }}</a></h5>
<p class="card-text">{{ item.description }}</p>
</div>
<div class="card-footer">
<small class="text-muted">{{ item.date }}</small>
</div>
</div>
</div>
</div>
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper-base.min.js"
integrity="sha384-GCUZeyb8ZgWw+/sO62C/NzCHQvT8CZTVSd8zRn77mDyBkGyMUwzA8bjoCIp1afmU"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js"
integrity="sha384-LofhOvz9f0uYN7V+eLhqJF7iG0QikIKgv7VYlWlqAz7VX9/ZLyya0TpRG2x/sxIS"
crossorigin="anonymous"></script>
<!-- Filter logic with jQuery -->
<script>
$(document).ready(function() {
$('.filter').click(function() {
var filter = $(this).data('filter');
if (filter == 'all') {
$('.filter-item').show();
} else {
$('.filter-item').hide();
$('.' + filter).show();
}
});
});
</script>
</body>
</html>

@ -5,6 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{% block title %}NTHU Trading Platform{% endblock title%}</title> <title>{% block title %}NTHU Trading Platform{% endblock title%}</title>
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='/img/growth.png') }}">
<link <link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css"
rel="stylesheet" rel="stylesheet"
@ -29,7 +30,7 @@
font-family: Georgia, sans-serif !important; font-family: Georgia, sans-serif !important;
} }
/* .offcanvas-body { /* .offcanvas-body {
font-size: 2vw font-size: 2vw;
} */ } */
.navbar { .navbar {
background-image: linear-gradient(to bottom right, #5d9faa , #c4e0e5); background-image: linear-gradient(to bottom right, #5d9faa , #c4e0e5);
@ -148,6 +149,7 @@
</div> </div>
<div class="prose lg:prose-xl p-3"> <div class="prose lg:prose-xl p-3">
<h2 class="text-xl font-bold mb-4">平台簡介</h2> <h2 class="text-xl font-bold mb-4">平台簡介</h2>
<hr class="mt-0 mb-2">
<p> <p>
我們常聽到的「鷄蛋不要放在同個籃子裏」, 我們常聽到的「鷄蛋不要放在同個籃子裏」,
爲的就是要分散股市不確定性所帶來的風險。 爲的就是要分散股市不確定性所帶來的風險。
@ -222,8 +224,8 @@
</div> </div>
</div> </div>
</div> </div>
<hr class="my-4"> <h2 class="text-xl font-bold mb-2 mt-4">投資組合的$\alpha$、$\beta$值簡介</h2>
<h2 class="text-xl font-bold mb-4 mt-4">投資組合的$\alpha$、$\beta$值簡介</h2> <hr class="mt-1 mb-3">
<p class="my-1"> <p class="my-1">
在評估投資組合的表現時,經常使用的是絕對性的指標, 在評估投資組合的表現時,經常使用的是絕對性的指標,
例如報酬率、波動率、夏普指數,MDD等, 例如報酬率、波動率、夏普指數,MDD等,
@ -248,8 +250,27 @@
在本擂台上,不限台股的投組使用的大盤指數 ($r_m$) 是SPY, 在本擂台上,不限台股的投組使用的大盤指數 ($r_m$) 是SPY,
台股的投組使用的大盤指數是0050.TW,無風險利率暫定為0。 台股的投組使用的大盤指數是0050.TW,無風險利率暫定為0。
</p> </p>
<hr class="my-4"> <h2 class="text-xl font-bold mb-2 mt-4">VaR 簡介</h2>
<h2 class="text-xl font-bold mb-4 mt-4">VaR 簡介</h2> <hr class="mt-1 mb-3">
<p class="my-1">
Value at Risk(VaR)是一種風險度量方法,用於衡量某個金融投資組合在一定置信水平下的最大可能損失,
即在給定的時間段內,可能出現的最大虧損額度。VaR的置信水平通常為95%或99%,表示對於未來某個時間段,
投資組合的損失不會超過該置信水平對應的虧損額度。VaR的計算需要考慮投資組合的市場風險、信用風險和操作風險等多個因素,
並且常常使用統計方法和模型來估計。常見的VaR模型包括歷史模擬法、蒙特卡羅模擬法和參數化模型等。
以下針對資產報酬率,在常態分配的假設下,10-day 95% VaR 風險值的計算方式如下:
</p>
<p>
給定資產的每日投組價值後,我們可以計算出該投組的(每日)報酬率與(每日)波動率。利用常態分配的假設,我們假設
$\mu$為$n$日報酬率(亦即(每日)報酬率 x n), $\sigma$為$n$日波動率亦即(每日)波動率
則 n-day 5% VaR 的公式為: $$-(\mu - 1.645\times\sigma)$$
</p>
<p class="my-1">
其中,置信水平的標準正態分位數是指標準正態分布累積分布函數在置信水平下的分位數,
可以通過查找標準正態分布表來獲得。在這個式子中,第一項是投資組合價值乘以置信水平,
表示投資組合的預期損失;第二項是投資組合價值乘以投資組合日收益的標準差乘以置信水平的標準正態分位數,
表示在一定置信水平下,投資組合可能遭受的最大損失。因此,VaR可以用來幫助投資者評估其投資組合的風險水平,
制定合適的風險管理策略。
</p>
</div> </div>
</div> </div>
{% endblock content %} {% endblock content %}

@ -1,6 +1,95 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% set active_page = 'result' %} {% set active_page = 'result' %}
{% block style %}
body {
background-image: url({{ url_for('static', filename='img/money.jpeg') }});
background-repeat: no-repeat; /* Do not repeat the image */
background-size: cover;
}
{% endblock style %}
{% block title %}Strategy Page{% endblock%} {% block title %}Strategy Page{% endblock%}
{% block content %}Hello world - {{ active_page|e }} {% endblock %} {% block content %}
<div class="container-fluid fade-in" style="background-color: #eee;">
<div class="container-fluid px-1 py-4">
<div class="alert alert-success p-3 mx-3" role="alert">
<h4 class="alert-heading">Well done!</h4>
<p>Aww yeah, you successfully read this important alert message. This example text is going to run a bit longer so that you can see how spacing within an alert works with this kind of content.</p>
<hr>
<p class="mb-0">Whenever you need to, be sure to use margin utilities to keep things nice and tidy.</p>
<div class='d-flex justify-content-end'>
<div>
<select id="competition" class="form-select" size="1" aria-label="size 5 select example">
{% include 'competitions.html' %}
</select>
</div>
<div>
<button type="button" class="btn btn-info"><i class="fa-duotone fa-person-running"></i></button>
</div>
</div>
</div>
<div class="card m-3">
<div card="card p-3 m-3">
<div class="card-header">
<div class="d-flex">
<div class="py-2 font-bold text-xl">
<span class='m-2'>策略顯示</span>
</div>
<div class="dropdown ms-auto py-2">
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
排行方式
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">我的策略</a></li>
<li><a class="dropdown-item" href="#">時間排行</a></li>
<li><a class="dropdown-item" href="#">報酬排行</a></li>
<li><a class="dropdown-item" href="#">SR排行</a></li>
<li><a class="dropdown-item" href="#">波動率排行</a></li>
</ul>
</div>
</div>
</div>
<div class="p-3">
<table class="table caption-top">
<caption></caption>
<thead>
<tr>
<th scope="col">#ID</th>
<th scope="col">投組名稱</th>
<th scope="col">創建者</th>
<th scope="col">報酬率</th>
<th scope="col">夏普率</th>
<th scope="col">波動率</th>
<th scope="col">創建時間</th>
</tr>
</thead>
{% for info in strategy_data %}
<thead style="font-size: 1vmin'">
<tr>
<th scope="col" role="alert">
<a href="" class="alert-link">
{{ info[0] }}
</a>
</th>
<td>{{ info[2] }}</td>
<td>{{ info[3] }}</td>
<td>{{ info[4] }}</td>
<td>{{ info[6] }}</td>
<td>{{ info[5] }}</td>
<td>{{ info[1] }}</td>
</tr>
</thead>
{% endfor %}
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

Loading…
Cancel
Save