owned this note
owned this note
Published
Linked with GitHub
---
title: '程式交易 - 投資組合管理 PortfolioManagement'
disqus: hackmd
tags: AlgoTrading
description:
font-size: 12px;
letter-spacing: 0;
---
# 程式交易 - 投資組合管理



# Table of Contents
[TOC]
# 每月結算 SOP
結算日當周進行本月投組策略體檢
1. 排名策略表現倒數幾名
2. 衡量近 6 個月績效表現與近 3 個月績效表現, 包括 MDD, 平均 DD, 獲利
3. 檢查近 3 個月累積損益 (= X), 近 6 個月累積損益 (= X + Y)
4. 撈出 X < 0 or Y < 0 or X + Y < 0 者
5. 找近 3 個月獲利 < 0 & 上 3 個月獲利 < 0
<!-- 5. 找出近 3 個月 DD > 近 6 個月 DD 的策略 -->
6. 每個月重新挑選新策略組成新投組放入備選投組中, 一樣留樣本外判斷, 重組結束時間最好破DD (目的是為了找出互補)
7. 當體感覺得投組跟不上走勢, 日損益偏大時, 可以從備選投組中選出適合的直接替換
# 檢視投組流程
## 策略
### 績效獲利門檻值:
- 近 3 個月均獲利 > 歷史 9/12/18/24 個月均獲利的 60%
- 近 3 個月若為虧損, 是否超過 歷史 9~12 個月中前 3 大虧損月的平均值
- 不符合上述條件者先下架並檢視策略, 修改後放入備選庫
### 策略分類標準/依據:
* 質化標準
- 數據來源: 純價/價差 (data2)/籌碼 OI
- 純多/純空/多空翻
- 當沖/留倉
* 量化標準
- 損益分布
- 持倉多空比例
- 持倉時間分布
- 交易次數分布
## 投組建置 SOP
- 輸出所有策略 tradelist (看是否要開細部回測 != IOG (要關IOG))
- 計算所有策略是否達門檻值標準, 以及所有策略的分類
- 篩出符合門檻值的策略
- 將策略透過最佳化計算哪些策略具有互補效果並加入投組中
- 觀察大投組的最大部位(曝險)以及損益分布狀況
### 投組的架構與 benchmark:
- 主體主力: 多單
- 多單的管理 = 多單出場 = 空單進場
- 空單的管理 = 空單出場 = 空單停損停利
- 台指期純多單本身的表現 (賠要賠比較少, 賺要賺比較多)
- 賺錢月份風報比 > x 倍 BNH (x 尚未定義)
- 賠錢月份風報比 > 1/y 倍 BNH (y 尚未定義)
### 投組檢視依據
- 投組本身相較過去一段時間的表現
- 目前取 20/60 個交易日的日損益平均值 +- 1.5~2.5 個標準差為範圍
- 若投組淨值曲線連續一段時間(3~5天) 掉出這個 bound 表示可能需要檢視
- 也有可能是經濟事件造成, 因此主觀作微調, 而不是大調 (過度調整通常結果都不好)
## 每日收盤處理 RPA
- 1345 收盤 `代辦: reload price/recalculate after 日盤收盤, 可以跟MR_Output 寫在一起`
- 1350 吐 tradelist 到 GgoogleDrive
- 1400 跑 QM 自動化更新報價資訊 + 下載
- 1400 吐最新價格資料到雲端資料夾 GoogleDrive
- 1415 跑理論損益 + Googlesheet 記帳
- python 排程 + GoogleSheetAPI 自動上傳所有理論損益資料
- 核對理論損益差異 = 滑價
- 平均單口滑價 = (當日損益 - 理論損益)/當日實際交易口數
- 有其他要動投組或調部位的都在1415後
## 投資組合最佳化 (策略挑選演算法)
### PortfolioOptimization (Stragey Selection Algorithm)
1. 找出策略池中, `目標函數`最高的單支策略作為投組 P (主體)
2. 所有策略池中單支策略 S 與 P 的所有策略合成的 P'
3. `目標函數`最高的 P' 是加入哪個策略 (S*)
4. 將 S* 加入 P 中, 重複 2~3, 直到 P 無法再改善, 定為 P*
5. 將策略池排除 P* 中的所有策略, 把P* 定為 P1, 重新執行 1~4, 依序產出 P2...Pn
6. 將 P1~Pn 所有策略選出來後, 等權重組成大投組 P**
7. 檢測 P** 中所有單支策略移除後是否會改善`目標函數`值
8. 重複 7 直到無法移除任何一隻策略, 再將 P** 丟回此演算法重複執行 1~4
9. 產生無法再優化的 P**, 完成`目標函數`最佳化的投組 P**
(本來挑選法是一純多一純空輪流挑選, 但看起來不是必要的, 直接讓演算法挑選即可)
### 目標函數
1. NP/MDD
2. AVG(NP/MDD)
3. AVG(NP)/AVG(DD)
4. Sharpe Ratio
5. SQN
6. Sortino Ratio
7. AVG(Recovery Period)
8. Corr
### 要點
1. 策略池中的策略體質不能太差 (交易次數多, 可以持倉時間長但要貼盤不凹單) => 為了樣本外的表現
2. 策略對投組的改善要好 (顯著提升投組的`目標函數`?) => 是要提高風報比跟互補性
3. 單支策略佔比不能過高 (減少單支策略失效影響整體的風險) => 最佳化投組的策略數要夠多 (總數 > 50?)
### Notes
- 切過純多純空 & 短多短空的效果 => 短多幾乎沒權重, 長空幾乎沒權重
- 極致情況應該會是長分K多單 + 短分K空單
- 待測試組法: 移動停損選取法
- 針對每年取最高評分的投組 => 選取這些策略
- 需不需 by HoldingTimes 去取? (分短多短空, 長多長空四組)
- 做出來結果多空比會在 1:1.5~2 左右 (1支多單配2支空單)
## 投組報告內容
1. 依年度平均每口損益, MDD, 風報比, 日勝率, 週勝率, 日賺賠比, 週賺賠比
2. 月損益, 週損益
3. 年度日損益累積曲線圖
4. 策略總支數, 純多支數, 純空支數, 各類型支數(純價, D2,
5. 多支一點 換一點點的風暴比降 追求不要一次爆炸的風險 比較好
## Notes
- 有條件下的MDD加碼: 邏輯是 沒有失效的策略 MDD加碼 一定會比沒加碼表現好
- MDD加碼最怕的是 碰到失效的策略 => 用近3個月總損益 > 0 & 不重疊近6個月總損益 > 0 擋掉那些可能失效的策略
- 任何策略 只要從DD活過來 我們都不用排斥 都可以上
- 而且DD比之前大更好(`待確認`) 表示他爬起來更有可能是回到屬於那個策略的行情, 就是代表他開始可以賺錢
- 一直開發體質好的策略就對了, 一支策略不要花超過一天
- 而且我們還有一個設定是 近 3 個月 + 不重疊6個月要賺錢 所以也不會真的上到那種賠爛的策略, 一路賠的沒辦法上架XD
- 條件就是 策略不能失效, 所以只要定義"失效"就好, 把沒有失效的拿來加碼, 失效的都暫時下架
- 比較怪的是, 比較的是兩段的DD, 這兩個DD很看切的時間點
- 覺得應該是算出 該策略平均的單口DD, 然後用3個月的去和那個DD比
- 抓好開發一支策略不要花超過一天的原則 (Leon 好像之前是說3小時還多久 反正不要太久 太久的話主邏輯就先丟一邊)
- 新產品的開發 (option (python) & stocks (XQ)) 這應該是上面全部作完整的 SOP出來之後才會做
- 噱爆的開發 (看能不能一樣每隻都做到多空分拆 我這邊有整理了一下以前到現在拿到的 可以改來上)
- python 分析 (策略分類, 小投組, 大投組整合, 多空分拆)
---
### 59支, 風報比60組合
``` python
['TXALB1_tradelist',
'TXALB3_tradelist',
'TXALB4_tradelist',
'TXALB6_tradelist',
'TXALS1_tradelist',
'TXALS2_tradelist',
'TXALS4_tradelist',
'TXALS7_tradelist',
'TXALS8_tradelist',
'TXDNB15_tradelist',
'TXDNB16_tradelist',
'TXDNB17_tradelist',
'TXDNB19_tradelist',
'TXDNB1_tradelist',
'TXDNB21_tradelist',
'TXDNB22_tradelist',
'TXDNB26_tradelist',
'TXDNB6_tradelist',
'TXDNB7_tradelist',
'TXDNB9_tradelist',
'TXDNS13_tradelist',
'TXDNS16_tradelist',
'TXDNS18_tradelist',
'TXDNS19_tradelist',
'TXDNS1_tradelist',
'TXDNS21_tradelist',
'TXDNS22_tradelist',
'TXDNS24_tradelist',
'TXDNS27_tradelist',
'TXDNS3_tradelist',
'TXDNS4_tradelist',
'TXFDS11_tradelist',
'TXFDS1_tradelist',
'TXFDS2_tradelist',
'TXFDS3_tradelist',
'TXFDS4_tradelist',
'TXFDS5_tradelist',
'TXFDS6_tradelist',
'TXFDS7_tradelist',
'TXFDS8_tradelist',
'TXFLB10_tradelist',
'TXFLB11_tradelist',
'TXFLB16_tradelist',
'TXFLB2_tradelist',
'TXFLB3_tradelist',
'TXFLB4_tradelist',
'TXFLB6_tradelist',
'TXFLB9_tradelist',
'TXFLS10_tradelist',
'TXFLS11_tradelist',
'TXFLS17_tradelist',
'TXFLS18_tradelist',
'TXFLS1_tradelist',
'TXFLS4_tradelist',
'TXFLS7_tradelist',
'TXFLS8_tradelist',
'TXFLS9_tradelist',
'TXOIS3_tradelist',
'TXOIS4_tradelist']
"""
多 23
ALB 4
DNB 11
FLB 8
空 36
ALS 5
DNS 11
FDS 9
FLS 9
OIS 2
共 59支
多 23/59 * 100 = *38.98* %
空 36/59 * 100 = *61.01* %
Data2 24/59 * 100 = *40.67* %
單支佔比 1/59 * 100 = *1.69* %
多方單支影響 1/23 * 100 = *4.34* %
空方單支影響 1/36 * 100 = *2.77* %
"""
```
---
### 39支 風暴比70
``` python
[0 TXALB3_tradelist
1 TXALB4_tradelist
2 TXALB6_tradelist
3 TXDNB16_tradelist
4 TXDNB17_tradelist
5 TXDNB19_tradelist
6 TXDNB21_tradelist
7 TXDNB22_tradelist
8 TXDNB26_tradelist
9 TXFLB4_tradelist
10 TXFLB9_tradelist
11 TXOIB3_tradelist
12 TXFLB2_tradelist
13 TXFLB3_tradelist
14 TXALS1_tradelist
15 TXDNS13_tradelist
16 TXDNS18_tradelist
17 TXDNS19_tradelist
18 TXDNS1_tradelist
19 TXDNS21_tradelist
20 TXDNS27_tradelist
21 TXDNS4_tradelist
22 TXFDS11_tradelist
23 TXFDS1_tradelist
24 TXFDS3_tradelist
25 TXFDS5_tradelist
26 TXFDS6_tradelist
27 TXFDS7_tradelist
28 TXFDS8_tradelist
29 TXFLS10_tradelist
30 TXFLS11_tradelist
31 TXFLS17_tradelist
32 TXFLS1_tradelist
33 TXFLS4_tradelist
34 TXFLS7_tradelist
35 TXFLS8_tradelist
36 TXFLS9_tradelist
37 TXALS8_tradelist
38 TXFLS12_tradelist]
"""
這組的組法是先1多1空 => 輪流1多1空加進去 => 第一組 (大概61),
排除第一組後的最高1多1空 => 輪流1多1空加進去 => 第二組 (大概56),
第三組我發現出來直接卡在25 上不去,
所以把 第一 + 第二 => 變成啟始 => 再跑一次一多一空 => 70
DNB 6
FLB 4
ALB 3
OIB 1
DNS 7
FDS 7
FLS 9
ALS 2
多 14
空 25
多空比: 25/14 = *1.78*
多方佔比: 14/39 * 100 = *35.89*
空方佔比: 25/39 * 100 = *64.1* %
單支佔比: 1/39 * 100 = *2.56* %
多方單支影響: 1/14 * 100 = *7.14*
空方單支影響: 1/25 * 100 = *4* %
- 多方影響比較大一點, 可能要壓在5%以下比較好?
- Data2 總共14支
- 而且或許以後維持, 等權重會比較好
- 也許這是我們的優勢, 吃DD就條一次, 投組的配置 (重組投組/組新投組的時間點?)
- 單支策略, 一定不能佔太高比例, 讓失效速度慢一點, 我們才有機會調整
- 潛在風險應該就真的是在單支失效的影響, 報表上看不到的
- 實際上可能打出去的比重 空單可能會衝到64%
- 缺點在資金使用率, 比如歷史多單最大33%, 空單最大48%, 衡量槓桿還是得以 48%, 甚至投組的最大 64%去計算比較保險
"""
```
---
# 新商品
## 股票
- 資訊源: XQ, open api (FinMind, TEJ, ...)
- 策略: XQ, python
- 週期: 當沖空, 波段多?
## 選擇權
- 選擇權的條件策略(有條件的 bc/sc/bp/sp) 應該還是可以做
- 只是回測跟開發要怎麼更有系統的執行需要想一下
## 海期
- 套用台指開發架構
User story
---
```gherkin=
Feature: Guess the word
# The first example has two steps
Scenario: Maker starts a game
When the Maker starts a game
Then the Maker waits for a Breaker to join
# The second example has three steps
Scenario: Breaker joins a game
Given the Maker has started a game with the word "silky"
When the Breaker joins the Maker's game
Then the Breaker must guess a word with 5 characters
```
> I choose a lazy person to do a hard job. Because a lazy person will find an easy way to do it. [name=Bill Gates]
```gherkin=
Feature: Shopping Cart
As a Shopper
I want to put items in my shopping cart
Because I want to manage items before I check out
Scenario: User adds item to cart
Given I'm a logged-in User
When I go to the Item page
And I click "Add item to cart"
Then the quantity of items in my cart should go up
And my subtotal should increment
And the warehouse inventory should decrement
```
> Read more about Gherkin here: https://docs.cucumber.io/gherkin/reference/
User flows
---
```sequence
Alice->Bob: Hello Bob, how are you?
Note right of Bob: Bob thinks
Bob-->Alice: I am good thanks!
Note left of Alice: Alice responds
Alice->Bob: Where have you been?
```
> Read more about sequence-diagrams here: http://bramp.github.io/js-sequence-diagrams/
Project Timeline
---
```mermaid
gantt
title A Gantt Diagram
section Section
A task :a1, 2014-01-01, 30d
Another task :after a1 , 20d
section Another
Task in sec :2014-01-12 , 12d
anther task : 24d
```
> Read more about mermaid here: http://mermaid-js.github.io/mermaid/
## Appendix and FAQ
:::info
**Find this document incomplete?** Leave a comment!
:::
###### tags: `Templates` `Documentation`