SeanChenTaipei 2 years ago
parent 4201a1f884
commit fe555f6542
  1. 28
      main.py
  2. 13
      static/js/addStock.js
  3. 152
      templates/base.html
  4. 3
      templates/result.html
  5. 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",

@ -2,9 +2,16 @@
let stockList = ['2330.TW'];
let currentList = [];
const layout={'autosize': true, 'title': {'text': 'Assets'},
'xaxis': {'anchor': 'y', 'domain': [0.0, 1.0], 'rangeslider': {'visible': true}},
'yaxis': {'anchor': 'x', 'domain': [0.0, 1.0]},
'legend': {'yanchor': 'top', 'y': 1.3, 'xanchor': 'left', 'x': 0.01}, 'margin': {'l': 25, 'r': 5, 't': 10, 'b': 5},
'xaxis': {'anchor': 'y', 'domain': [0.0, 1.0],
'rangeslider': {'visible': true},
'rangeselector':{'rangeselector':
{'buttons': [
{'count': 1, 'label': '1m', 'step': 'month', 'stepmode': 'backward'},
{'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]},
'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
const $stockForm = $('#stock-form');

@ -45,20 +45,9 @@
height: 60px;
background-color: #f5f5f5;
}
.navbar-fixed-top {
top:20px;
}
{% block style %}
p {
text-indent: 2em;
@ -191,22 +180,47 @@
<div class="prose lg:prose-xl p-3">
<h2 class="text-xl font-bold mb-4">平台簡介</h2>
<hr class="mt-0 mb-2">
<p class="font-bold">
「不要把所有的雞蛋放在一個籃子裡。」
</p>
<p>
我們常聽到的「鷄蛋不要放在同個籃子裏」,
爲的就是要分散股市不確定性所帶來的風險。
一般來説,在風險分散的同時,收益也會跟著降低
於是問題就變成:我們如何在風險與報酬率中取捨
被稱爲資産配置之父的哈利·馬可維兹(Harry Max Markowitz)就提供了以下的想法。
分散投資是一種投資策略,旨在通過將資金分散投資在不同的資產類別中,從而降低投資風險。
如果兩個資產之間存在高度正相關,則它們的價格通常會同時上漲或下跌
相反,如果它們之間存在高度負相關,則它們的價格通常會發生相反的變化
因此,分散投資應選擇具有低相關性的資產,以實現風險的分散
</p>
<p>
在給定各個標的(underlying)的權重後,
對該投資組合(portfolio)做均值–變異數分析(mean-variance analysis),
其中平均數爲平均報酬率,變異數爲波動率(意即「風險」)。
在這樣定義不同投資組合的報酬與風險的情况下,
我們可以發現:在不同的預期報酬下,
都可以找到一個投資組合(或權重)使波動率達到最小值。
將這些報酬與對應到的最小風險記錄下來後所形成的開口向右的二維拋物線圖形(如下圖),
就是所謂的「效率前緣(efficient frontier)」。
Efficient Frontier的建立基於資產收益率和風險的統計分析和優化理論。資產收益率可以通過歷史數據進行計算,而風險則通常使用標準差、協方差等統計指標進行衡量。
假設有n個資產,它們的收益率分別為 $R_1, R_2, ..., R_n$,協方差矩陣為 $\Sigma$。假設現有一個投資組合,其中各資產的權重分別為 $w_1, w_2, ..., w_n$,則該投資組合的收益率為:
$$R_p = w_1 R_1 + w_2 R_2 + ... + w_n R_n = w^T R$$
該投資組合的方差為:
$$\begin{align}\sigma^2_p &= w_1^2 \sigma_1^2 + w_2^2 \sigma_2^2 + ... \\&+ w_n^2 \sigma_n^2 + 2w_1w_2\sigma_{1,2} + 2w_1w_3\sigma_{1,3} + ... \\&+ 2w_{n-1}w_n\sigma_{n-1,n} = w^TRw\end{align}$$
其中,$\sigma_i$ 表示第 i 個資產的標準差,$\sigma_{i,j}$ 表示第 i 和第 j 個資產的協方差。
為了尋找最優投資組合,我們可以使用均值-方差優化方法。該方法的核心思想是通過最小化投資組合的方差,來最大化其收益率。假設有一個投資者的風險偏好係數為 $\gamma$,則該投資者所選擇的最優投資組合為:
$$\text{min}\ \frac{1}{2}w^T \Sigma w - \gamma w^T R$$
$$\text{s.t.}\ \sum_{i=1}^n w_i = 1, w_i \geq 0$$
其中,$w$ 是資產權重向量,$\Sigma$ 是協方差矩陣,$R$ 是收益率向量。目標函數是投資組合方差的一半減去風險偏好係數乘以投資組合收益率,約束條件是權重向量的元素之和為1且每個權重都不小於0。
通過調整風險偏好係數 $\gamma$
,可以獲得不同風險水平下的最優投資組合,這些投資組合形成了有效邊界(Efficient Frontier),即在一定風險水平下,可以實現最大化收益的投資組合集合。
在實際應用中,通常使用投資組合的夏普比率(Sharpe Ratio)作為評估指標。夏普比率可以看作是投資組合每單位風險所帶來的超額收益,其計算公式為:
$$\text{Sharpe Ratio} = \frac{R_p - R_f}{\sigma_p}$$
其中,$R_p$ 是投資組合的預期收益率,$R_f$ 是無風險利率,$\sigma_p$ 是投資組合的標準差。
Efficient Frontier的建立是現代投資組合理論的基石之一。通過將不同資產的收益率和風險納入考慮,投資者可以通過構建有效邊界,實現在不同風險水平下的最優資產配置。這為投資者提供了一個更有效的投資方案,可以實現更穩定的收益和更低的風險水平。</p>
<div class='d-flex justify-content-center'>
<div class="rounded mx-auto d-block" style="height: 80%; width: 80%;">
<img src="{{ url_for('static', filename='img/frontier.jpg') }}" class="img-fluid" alt="frontier-example">
@ -215,15 +229,7 @@
<p class="p-0">
本網站使用S&P 500、元大臺灣50以及Nasdaq 100指數的成份股的歷史日資料。
每次計算標的權重,都是取六個月的資料,依照馬可維兹的理論,
畫出效率前緣,然後取夏普值最大的權重,再用接下來三個月的資料,
觀察投資組合的價值如何變化。我們每三個月更新一次權重,
再把許多三個月區間內投資組合的價值變動拼接起來,
得到2015年中到2020年中投資組合的價值變動,
再藉此求出平均年報酬、年波動率,再把報酬除以波動率得到整個投資期間的夏普值。
另外我們還算出最大跌幅(maximum drawdown),就是投資過程中,
會從到目前為止的最高點,最多下跌多少幅度。
------
</p>
<div class="row">
<div class="col-sm-6">
@ -268,49 +274,59 @@
<h2 class="text-xl font-bold mb-2 mt-4">投資組合的$\alpha$、$\beta$值簡介</h2>
<hr class="mt-1 mb-3">
<p class="my-1">
在評估投資組合的表現時,經常使用的是絕對性的指標,
例如報酬率、波動率、夏普指數,MDD等,
不過也有相對性的指標alpha、beta值。
比較投組與另一個標的(例如大盤指數,
我們可以透過回歸式,估計出作為超額報酬的alpha值,
以及作為相關性的beta值。Alpha值表示投組的獲利能力,
越高越好。Beta值代表了投組對系統性風險的曝險程度,越低越好。
投資組合報酬率的Alpha和Beta是投資組合評估中常用的指標。
Alpha代表投資組合的超額收益,Beta則代表投資組合與市場的相關性。
Beta值是衡量資產相對於整個市場的波動性的指標。Beta值的公式如下:
$$\beta_i = \frac{\text{Cov}(r_i,r_m)}{\text{Var}(r_m)}$$
其中,$r_i$表示資產i的收益率,$r_m$表示市場收益率,
$Cov(r_i,r_m)$表示資產i的收益率和市場收益率之間的協方差,
$Var(r_m)$表示市場收益率的方差。Beta值越高,表示資產的波動性越大,
其收益率與市場收益率之間的關聯度也越高。
Beta值可以用來評估投資組合的風險程度,投資者可以通過控制投資組合中資產的Beta值來實現風險管理。
Beta值可以與CAPM(Capital Asset Pricing Model)和線性回歸相關聯。在CAPM中,假設資產的預期收益率可以通過以下公式計算:
$$E(r_i) = r_f + \beta_i(E(r_m) - r_f)$$
其中,$E(r_i)$表示資產i的預期收益率,$r_f$表示無風險收益率,$E(r_m)$表示市場的預期收益率,
$\beta_i$表示資產i的Beta值。該公式表示,資產的預期收益率是無風險收益率和市場風險溢價的加權平均值,
其中市場風險溢價的大小與市場風險的大小成正比,且與資產的Beta值相關。
</p>
<p class="my-1">
根據CAPM模型,給定投組報酬 $r_{p}$, 大盤指數 $r_m$ 以及無風險利率 $r_f$ ,
$\beta$ 值可以藉由以下公式得出:
$$ \mathbb{E}[r_p] - r_f = \beta (\mathbb{E}[r_m] - r_f)$$
$\alpha$ 值則是藉由計算實際的投組報酬與由CAPM得到的理論報酬的差得到,公式為:
$$\alpha = r_p - (r_f + \beta (r_m - r_f))$$
Alpha 值是指投資組合的實際收益率與其根據 Beta 值預期的收益率之間的差異。如果投資組合的實際收益率高於其根據 Beta 值所預期的收益率,則 Alpha 值為正;反之,如果投資組合的實際收益率低於其預期收益率,則 Alpha 值為負。
Alpha 值可以通過線性回歸分析來計算。假設投資組合的收益率可以表示為以下公式:
$$r_p = \alpha + \beta_p (r_m-f_f) + \epsilon$$
其中,$r_p$ 表示投資組合的收益率,$\alpha$ 表示 Alpha 值,$\beta_p$ 表示投資組合的 Beta 值,$r_m$ 表示市場收益率,$\epsilon$ 表示誤差項。如果我們將上述公式進行線性回歸,可以得到:
$$\hat{r_p} = \hat{\alpha} + \hat{\beta_p} (r_m-r_f)$$
其中,$\hat{r_p}$ 表示預測的投資組合收益率,$\hat{\alpha}$ 表示預測的 Alpha 值,$\hat{\beta_p}$ 表示預測的 Beta 值。如果實際收益率高於預測收益率,則 $\hat{\alpha}$ 為正;反之,如果實際收益率低於預測收益率,則 $\hat{\alpha}$ 為負。
</p>
<p class="my-1">
當給定一組時間序列時,alpha、beta值可以利用線性回歸的方式得出。
我們可以將上述的式子改寫成以下的形式:
$$Y = \alpha + \beta X + \epsilon,$$ 而 $$Y = r_p-r_f , X = r_m-r_f$$
透過此回歸式,我們除了可以得到alpha、beta值外,也可以計算出值,用以衡量此模型的解釋力。
在本擂台上,不限台股的投組使用的大盤指數 ($r_m$) 是SPY,
台股的投組使用的大盤指數是0050.TW,無風險利率暫定為0。
</p>
<h2 class="text-xl font-bold mb-2 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 風險值的計算方式如下:
VaR (Value at Risk) 是用來衡量投資組合或資產在一定時間內可能面臨的最大潛在損失的一種風險管理指標。VaR 通常用機率的形式表達,表示在一定信心水平下,資產或投資組合在未來一定時間內的最大可能損失額。
假設 $X$ 是一個隨機變量,表示資產或投資組合在未來一定時間內的損失額,$p$ 表示所選取的信心水平,VaR 可以表示為:
$$\text{VaR}_p(X) = - \inf \{ x \in \mathbb{R} : F_X(x) \geq p \}$$
其中,$F_X(x)$ 是 $X$ 的累積分布函數。這個公式的意思是,我們尋找一個最小的數值 $x$,使得資產或投資組合在未來一定時間內的損失額大於 $x$ 的機率不超過 $1-p$。這個最小的數值就是 VaR,通常表示為負數,因為它是損失額。
例如,假設我們選取信心水平 $p=0.95$,並且假設資產或投資組合在未來一周內的報酬率的分布是正態分布 $N(\mu,\sigma^2)$,那麼根據上述公式,VaR 的值為:
$$\begin{align}\text{VaR}_{0.95}(X) &= -\inf\{ x \in \mathbb{R} : F_X(x) \leq 0.05 \} \\
&= -\inf \{x \in \mathbb{R} : \mathbb{P}(z\leq\frac{x-\mu}{\sigma}) \leq 0.05) \} \\
&= -\inf \{x \in \mathbb{R} : \Phi (\frac{x-\mu}{\sigma}) \leq 0.05 \} \\
&= -(\mu - 1.645\times\sigma)\end{align}$$
其中,$\Phi(x)$ 是標準常態分布的累積分布函數。
需要注意的是,VaR 是一個單一數字,只反映了資產或投資組合在一定時間內的最大可能損失額,
不能反映風險的分布情況。因此,在使用 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>

@ -59,7 +59,6 @@
</div>
<div class="p-3 table-responsive-sm table-responsive-md table-responsive-xl">
<table class="table caption-top">
<caption></caption>
<thead>
<tr>
<th scope="col">#ID</th>
@ -76,7 +75,7 @@
<tr>
<th scope="col" role="alert">
<a href="" class="alert-link">
<span class="badge rounded-pill text-bg-info">{{ info[0] }}</span>
<span class="badge rounded-pill text-bg-warning">{{ info[0] }}</span>
</a>
</th>
<td>{{ info[2] }}</td>

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

Loading…
Cancel
Save