[VBA] 高達 114.60% 的獲利策略 – 0050 KD指標 回測程式
目錄 :
0050 KD指標 回測程式
此篇文章也是 0050即時分析系統 的延伸,主要是藉由 KD指標 的歷史資料,利用 低檔(超賣區)/高檔(超買區) 為 進/出場 的回測策略,同時與時下最夯的小資族 定時定額無腦存股法,再作比較,看其績效為何 ?
※ 所謂「 數據會說話 」,這就開始製作並解說 KD指標 回測程式的操作步驟,讓大家了解 — 如何達成 114.60% 翻倍獲利 !
( PS. 若對 KD指標 定義不了解的話,請先參考 : 隨機指標 ( KD )。
[ 操作步驟 ] : 雷同與 0050均線回測程式。
1. 複製歷史資料 : 將 元大台灣50 工作表內的資料欄位複製到 KD工作表。
( PS. 因為只針對 KD指標 作回測,所以只複製基本欄位 : 時間 + 開 / 高 / 低 / 收 + KD指標 的欄位資料,如下圖。)
2. 1 ~ 3列 插入空白列 : 為了做數據分析之用。
3. 填入需要的欄位名稱 : 依照下圖 — 紅框 / 桔框 位置,填入各欄位標題名稱。
4. 載入各項判別公式 : 依照上圖 — 紅/桔框,分成 : 兩個區塊 — (上) : 即時數據 + 策略分析 / (下) : 歷史資料分析,來載入相關的判別公式。
(下) : 歷史資料分析
※ 首先,先製作 台灣50KD指標回測程式 — (下) : 歷史資料分析 桔框部分,標題內,目前僅有一組 : K值 ↗ D值 ( 黃金交叉 – 買進 ) / K值 ↘ D值 ( 死亡交叉 – 賣出 ) 策略。
[ 注意 ] :
※ 為了符合大家對於KD值的認知,所以先利用 VBA程式,將 F欄( K(9,3)值 )及 G欄( D(9,3)值 ),改為不含 % 符號的數值來標示。( 例如 : 54.48% 改為 54.48 )
[ 程式碼 / 修改_台灣50KD數據 ] :
Sub 修改_台灣50KD數據()
Dim lastRow As Integer
Sheets("KD").Select '選取KD工作表
lastRow = Range("A5").End(xlDown).Row ' 藉由 A5 往下搜尋,找出最後一列列號。
For I = 13 To lastRow ' N/A不做處理,所以從 13列 開始。
Range("F" & I) = Range("F" & I) * 100 ' 將 F欄數值 * 100 => 去除 % 符號。
Range("G" & I) = Range("G" & I) * 100 ' 將 G欄數值 * 100 => 去除 % 符號。
Next
End Sub
[ 程式解說 ] :
0. 首先建立一個 : VBA模組。不了解如何建立,請參考 : 開啟 VBA 程式 – 插入模組。
1. Sub : 副程式名稱 : 修改_台灣50KD數據 。
2. Dim : 宣告變數 lastRow 為整數 : Integer。
3. Sheets(“KD”).Select : 選取:MA工作表。
4. lastRow = Range(“A5”).End(xlDown).Row : 這是 Range指令的用法 。End(xlDown) 參數,就是EXCEL的快速鍵 : Ctrl + ↓,Row : 列位置。
※ 意思是 : 點 A5 儲存格,按下 Ctrl + ↓,游標從 A5 往下移動,停止在收盤價最後一列的位置 : A4641。參數 Row = 4641。( PS. 值(4641) 再帶給 變數 lastRow 。)
5. 執行 For 迴圈 — 從 13列 開始 到 最後一列(lastRow)。
6. 迴圈內公式 — Range(“F” & I) = Range(“F” & I) * 100 及 Range(“G” & I) = Range(“G” & I) * 100 : 意思是將 F欄 及 G欄 的數值 * 100,即可去除 % 符號。
※ F欄( K(9,3)值 )及 G欄( D(9,3)值 ) 的 % 符號去除後,便能開始製作 KD指標 歷史資料的策略程式。
KD指標 策略
☆ 策略條件 : 於 K值 < 20 之後的黃金交叉 ( K值 ↗ D值 – 買進 ) / K值 > 80 之後的死亡交叉 ( K值 ↘ D值 – 賣出 )。
※ 策略與 MA均線回測程式 略有不同,主要差別在於 進場點 – 跌破 K值 : 20 以後的 黃金交叉 ( K值 ↗ D值 ),才買進;出場點 – 突破 K值 : 80 以後的 死亡交叉 ( K值 ↘ D值 ),則賣出。
☆ 步驟一 : 設計 H欄 / K欄 — 買進 / 賣出 信號標示公式
[ 買進 – 策略條件 ] :
◎ 條件一 : K值 < 20 。
◎ 條件二 : 條件一成立後,K值 ↗ D值 : K值 向上穿過 D值 — 買進。
——————————————————————————————————————————————
[ 公式設定與解說 ] :
☆ H5 儲存格 – 買進信號標示 公式 :
※ K值 < 20 公式 : =IF(F5=”N/A”,0,IF(H4=0,IF(F5<20,1,0),IF(H4=1,IF(F5>G5,2,1),IF(H4=2,IF(F5>80,0,2),0)))),這是多層的IF判斷式,比MA回測程式的複雜些,因為多了一個條件( K值 ↗ D值 — 買進 )設定。
◎ EXCLE函數寫法 : 如下 :
第 1 層 IF : =IF(F5=”N/A”,0,IF(H4=0,IF(F5<20,1,0),IF(H4=1,IF(F5>G5,2,1),IF(H4=2,IF(F5>80,0,2),0)))) :
※ 意思是判別 F5儲存格 K值 資料,是否正確。若為 N/A,H5欄/顯示 : 0,表示資料錯誤;非N/A,則進入 第 2 層 IF 判別式。
第 2 層 IF : IF(H4=0,IF(F5<20,1,0),IF(H4=1,IF(F5>G5,2,1),IF(H4=2,IF(F5>80,0,2),0))) :
※ 意思是判別 H4(前一日信號)資料,是否為 0。 (可先參考 H欄 信號解說)。
◎ 若為 是 ( =0 ) : 進入 IF(F5<20,1,0) 判別式,判別 F5 的 K值 是否 <20。( ※ 若 是 : 表示跌入超賣區,觸發信號,F5欄/顯示 : 1;若 否 : 則顯示 0,維持空手信號。)
◎ 若為 否 : 意思不等於 0,表示信號可能為 1 或 2,則進入 第 3 層 IF(H4=1,IF(F5>G5,2,1),IF(H4=2,IF(F5>80,0,2),0)) 判別式。
第 3 層 IF : IF(H4=1,IF(F5>G5,2,1),IF(H4=2,IF(F5>80,0,2),0)) :
※ 意思是判別 H4(前一日信號)資料,是否為 1。 (可先參考 H欄 信號解說)。
◎ 若為 是 ( =1 ) : 進入 IF(F5>G5,2,1) 判別式,判別 F5 的 K值 是否 >G5 的 D值。( ※ 若 是 : 表示黃金交叉,買進信號,F5欄/顯示 : 2;若 否 : 則顯示 1,等待黃金交叉信號。)
◎ 若為 否 : 意思不等於 0,表示信號可能為 2,則進入 第 4 層 IF(H4=2,IF(F5>80,0,2),0) 判別式。
第 4 層 IF : IF(H4=2,IF(F5>80,0,2),0) :
※ 意思是判別 H4(前一日信號)資料,是否為 2。 (可先參考 H欄 信號解說)。
◎ 若為 是 ( =2 ) : 進入 IF(F5>80,0,2) 判別式,判別 F5 的 K值 是否 >80。( ※ 若 是 : 表示進入超買區,觸發信號,F5欄/顯示 : 0;若 否 : 則顯示 2,維持有單信號。)
◎ 若為 否 : 意思不等於 2,則是空手,顯示 0。
★ 信號標示條件 ★
[ H欄 / 信號標示 ] : 欄位中,會有三種信號標示 : 空手 / 信號觸發 / 有單。
◎ 空手 / H欄=0 : 表示手上沒單。
◎ 信號觸發 / H欄=1 : 表示觸發了 K值 < 20 或 K值 > 80 信號。
◎ 有單 / H欄=2 : 表示觸發了 K值 ↗ D值 或 K值 ↘ D值 信號,手上有買或賣單。
[ 賣出 – 策略條件 ] :
◎ 條件一 : K值 > 80 。
◎ 條件二 : 條件一成立後,K值 ↘ D值 : K值 向下穿過 D值 — 賣出。
——————————————————————————————————————————————
[ 公式設定與解說 ] :
☆ K5 儲存格 – 賣出信號標示 公式 :
※ K值 > 80 公式 : =IF(F5=”N/A”,0,IF(K4=0,IF(F5>80,1,0),IF(K4=1,IF(F5<G5,2,1),IF(K4=2,IF(F5<20,0,2),0)))),這是多層的IF判斷式,比MA回測程式的複雜些,因為多了一個條件( K值 ↘ D值 — 賣出 )設定。
◎ EXCLE函數寫法 : 如下 :
第 1 層 IF : =IF(F5=”N/A”,0,IF(K4=0,IF(F5>80,1,0),IF(K4=1,IF(F5<G5,2,1),IF(K4=2,IF(F5<20,0,2),0)))) :
※ 意思是判別 F5儲存格 K值 資料,是否正確。若為 N/A,K5欄/顯示 : 0,表示資料錯誤;非N/A,則進入 第 2 層 IF 判別式。
第 2 層 IF : IF(K4=0,IF(F5>80,1,0),IF(K4=1,IF(F5<G5,2,1),IF(K4=2,IF(F5<20,0,2),0))) :
※ 意思是判別 K4(前一日信號)資料,是否為 0。 (請參考 H欄 信號解說)。
◎ 若為 是 ( =0 ) : 進入 IF(F5>80,1,0) 判別式,判別 F5 的 K值 是否 >80。( ※ 若 是 : 表示進入超買區,觸發信號,F5欄/顯示 : 1;若 否 : 則顯示 0,維持空手信號。)
◎ 若為 否 : 意思不等於 0,表示信號可能為 1 或 2,則進入 第 3 層 IF(K4=1,IF(F5<G5,2,1),IF(K4=2,IF(F5<20,0,2),0)) 判別式。
第 3 層 IF : IF(K4=1,IF(F5<G5,2,1),IF(K4=2,IF(F5<20,0,2),0)) :
※ 意思是判別 H4(前一日信號)資料,是否為 1。 (請參考 H欄 信號解說)。
◎ 若為 是 ( =1 ) : 進入 IF(F5<G5,2,1) 判別式,判別 F5 的 K值 是否 <G5 的 D值。( ※ 若 是 : 表示死亡交叉,賣出信號,F5欄/顯示 : 2;若 否 : 則顯示 1,等待黃金交叉信號。)
◎ 若為 否 : 意思不等於 0,表示信號可能為 2,則進入 第 4 層 IF(K4=2,IF(F5<20,0,2),0) 判別式。
第 4 層 IF : IF(K4=2,IF(F5<20,0,2),0) :
※ 意思是判別 H4(前一日信號)資料,是否為 2。 (請參考 H欄 信號解說)。
◎ 若為 是 ( =2 ) : 進入 IF(F5<20,0,2) 判別式,判別 F5 的 K值 是否 <20。( ※ 若 是 : 表示跌入超賣區,觸發信號,F5欄/顯示 : 0;若 否 : 則顯示 2,維持有單信號。)
◎ 若為 否 : 意思不等於 2,則是空手,顯示 0。
☆ 步驟二 : I欄 / L欄 — 買進 / 賣出 信號觸發標記 :
[ 買進標記條件 ] :
◎ 條件一 : 判別 H-1欄(昨日信號)資料,是否為 1 (已進入超賣區)。
◎ 條件二 : 判別 H欄(今日信號)資料,是否為 2 (正式黃金交叉)。
※ 以上兩條件均成立,則今日 I欄 標記 : 1,表示 : 買進。
——————————————————————————————————————————————
[ 公式設定與解說 ] :
☆ I5 儲存格 – 標記買進信號 公式 :
※ 觸發信號 買進公式 : =IF(F5=”N/A”,””,IF(AND(H4=1,H5=2),1,””)),這是二層的IF判斷式。
◎ EXCLE函數寫法 : 如下 : ( 下圖為 : 示意圖 )。
第 1 層 IF : =IF(F5=”N/A”,“”,IF(AND(H4=1,H5=2),1,””)) :
※ 意思是判別 F5儲存格 K值 資料,是否正確。若為 N/A,I5欄/顯示 : ” “,表示資料錯誤;非N/A,則進入 第 2 層 IF 判別式。
第 2 層 IF : IF(AND(H4=1,H5=2),1,“”) :
※ 意思是 : 使用 AND邏輯函數,同時判別 H4(前一日信號),是否為 1 及 H5(今日信號),是否為 2。 (可先參考 H欄 信號解說)。
◎ 若為 是 : 表示今日 K值 ↗ D值 黃金交叉 – 買進,I欄 標記 : 1,方便次數加總計算。
◎ 若為 否 : 條件不成立,便不做任何更動,標記 : ” “ (空白)。
[ 賣出標記條件 ] :
◎ 條件一 : 判別 L-1欄(昨日信號)資料,是否為 1 (已進入超買區)。
◎ 條件二 : 判別 L欄(今日信號)資料,是否為 2 (正式死亡交叉)。
※ 以上兩條件均成立,則今日 L欄 標記 : 1,表示 : 賣出。
——————————————————————————————————————————————
[ 公式設定與解說 ] :
☆ L5 儲存格 – 標記賣出信號 公式 :
※ 觸發信號 賣出公式 : =IF(F5=”N/A”,””,IF(AND(K4=1,K5=2),1,””)),這是二層的IF判斷式。
◎ EXCLE函數寫法 : 如下 : ( 下圖為 : 示意圖 )。
第 1 層 IF : =IF(F5=”N/A”,“”,IF(AND(K4=1,K5=2),1,””)) :
※ 意思是判別 F5儲存格 K值 資料,是否正確。若為 N/A,L5欄/顯示 : ” “,表示資料錯誤;非N/A,則進入 第 2 層 IF 判別式。
第 2 層 IF : IF(AND(K4=1,K5=2),1,“”) :
※ 意思是 : 使用 AND邏輯函數,同時判別 K4(前一日信號),是否為 1 及 K5(今日信號),是否為 2。 (可先參考 H欄 信號解說)。
◎ 若為 是 : 表示今日 K值 ↘ D值 死亡交叉 – 賣出,L欄 標記 : 1,方便次數加總計算。
◎ 若為 否 : 條件不成立,便不做任何更動,標記 : ” “ (空白)。
☆ 步驟三 : J欄 / M欄 — 買進價 / 賣出價 標記 :
[ 買進價標記條件 ] :
◎ 條件一 : 判別 I欄 資料,是否為 1 (買進標記)。
——————————————————————————————————————————————
[ 公式設定與解說 ] :
☆ J5 儲存格 – 標記 買進價 公式 : =IF(I5=1,E5,””)。
◎ EXCLE函數寫法 : 如下 : ( 下圖為 : 示意圖 )。
☆ IF 判別式 : =IF(I5=1,E5,“”) :
※ 意思是 : 判別 I5欄 資料,是否為 1。 (可先參考 H欄 信號解說)。
◎ 若為 是 : 顯示 E5欄 收盤價,為 買進價。
◎ 若為 否 : 條件不成立,便不做任何更動,標記 : ” “ (空白)。
[ 賣出價標記條件 ] :
◎ 條件一 : 判別 L欄 資料,是否為 1 (賣出標記)。
——————————————————————————————————————————————
[ 公式設定與解說 ] :
☆ M5 儲存格 – 標記 賣出價 公式 : =IF(L5=1,E5,””)。
◎ EXCLE函數寫法 : 如下 : ( 下圖為 : 示意圖 )。
☆ IF 判別式 : =IF(L5=1,E5,“”) :
※ 意思是 : 判別 L5欄 資料,是否為 1。 (可先參考 H欄 信號解說)。
◎ 若為 是 : 顯示 E5欄 收盤價,為 賣出價。
◎ 若為 否 : 條件不成立,便不做任何更動,標記 : ” “ (空白)。
☆ 步驟四 : 公式延伸複製
※ 完成以上三組公式設定後,便可將公式往下延伸複製,複製到最新一筆資料。
[ 延伸複製方法 ] : 步驟如下 —
◎ 選取 H5 ~ M5 欄位資料,滑鼠游標移到 M5儲存格的右下角,此時游標會變成 + (十字),然後滑鼠左鍵點二下,公式便會往下延伸複製到最後一列。
◎ 延伸複製後,資料如下 :
(上) : 即時數據 + 策略分析
( 1 ) : 即時數據
※ 即時數據 : 包含 — 時間 ( A欄 ) / 開高低收 ( B ~ E欄 ) / KD值 ( F ~ G欄 ) 等部分。
PS. 為了求得即時的 KD值 數據,必須再增加三個參數欄位( RSV值 / 九日最大值 / 九日最小值 — P ~ R欄 ),如下圖 :
[ 公式設定與解說 ] :
( A2欄 ) : 時間 — 利用 RTD語法 連結 XQ,取得交易時間。公式 : =RTD(“xqrtd.rtdserverxqlite”,,”TSE.TW-TradingDate”)
( B2欄 ) : 開盤價 — 同上法,取得開盤價。公式 : =RTD(“xqrtd.rtdserverxqlite”,,”0050.TW-Open”)
( C2欄 ) : 最高價 — 同上法,取得最高價。公式 : =RTD(“xqrtd.rtdserverxqlite”,,”0050.TW-High”)
( D2欄 ) : 最低價 — 同上法,取得最低價。公式 : =RTD(“xqrtd.rtdserverxqlite”,,”0050.TW-Low”)
( E2欄 ) : 收盤價 — 同上法,取得收盤價。公式 : =RTD(“xqrtd.rtdserverxqlite”,,”0050.TW-Price”)
◎ 若忘記 RTD語法的使用方式,請參考 : DDE/RTD語法與參數。
[ KD指標 — 公式設定 ] :
※ 由於 KD值 的即時數據,必須經過計算,先求得 RSV值,再演算出 R值 與 D值。( 詳細介紹,請參考 : KD指標 – 計算公式 )
※ KD指標 公式原理 : 以 日 為單位。
☆ H (最高值) = MAX ( 最近9日內(含今日)的最高價 )
☆ L (最低值) = MIN ( 最近9日內(含今日)的最低價 )
☆ RSV = C ( 今日收盤價 ) – L ( 近九日最低價 ) / H ( 近九日最高價 ) – L ( 近九日最低價 )
☆ K(9,3) = 1 / 3 * RSV + 2 / 3 * 昨日K值
☆ D(9,3) = 1 / 3 * 今日K值 + 2 / 3 * 昨日D值
[ EXCEL 公式解說 ] :
1. Q2欄 / H (最高值) : =MAX(C2,C4638:C4645) — 意思 : C2(今日最高價) 與 C4638:C4645(前8日最高值) 做比較,求得最高價。
2. R2欄 / L (最低值) : =MIN(D2, D4638:D4645) — 意思 : D2(今日最低價) 與 D4638:D4645(前8日最高值) 做比較,求得最低價。
3. P2欄 / RSV : =((E2-R2)/(Q2-R2))*100 — 意思 : ( E2(今日收盤價) – R2(近九日最低價) / Q2(近九日最高價) – R2(近九日最低價) ) * 100
4. F2欄 / K(9,3) : =1/3*P2+2/3*F4645 — 意思 : 1/3 * P2(RSV值) + 2/3 * F4645(昨日K值)
5. G2欄 / D(9,3) : =1/3*F2+2/3*G4645 — 意思 : 1/3 * F2(今日K值) + 2/3 * G4645(昨日D值)
◎ 以上,就是KD指標的數據公式,為求每天即時更新數據,便採用 VBA公式來做設計,方便抓取歷史資料的最新列數。
[ 程式碼 / 台灣50_KD數據更新 ] :
Sub 台灣50_KD數據更新()
Dim lastRow As Integer
Sheets("KD").Select
lastRow = Range("A5").End(xlDown).Row ' 藉由 E5,往下搜尋最後一列。)
[Q2] = "=MAX(C2, C" & lastRow - 7 & ":C" & lastRow & ")" ' 求出 最高值 的公式
[R2] = "=MIN(D2, D" & lastRow - 7 & ":D" & lastRow & ")" ' 求出 最低值 的公式
' RSV值 :
[P2] = "=((E2-R2)/(Q2-R2))*100"
' K值 :
[F2] = "=1/3*P2+2/3*F" & lastRow
' D值
[G2] = "=1/3*F2+2/3*G" & lastRow
End Sub
[ 程式解說 ] :
0. 首先建立一個 : VBA模組。不了解如何建立,請參考 : 開啟 VBA 程式 – 插入模組。
1. Sub : 副程式名稱 : 台灣50_KD數據更新 。
2. Dim : 宣告變數 lastRow 為整數 : Integer。
3. Sheets(“KD”).Select : 選取:KD工作表。
4. lastRow = Range(“A5”).End(xlDown).Row : 這是 Range指令的用法 。End(xlDown) 參數,就是EXCEL的快速鍵 : Ctrl + ↓,Row : 列位置。
※ 意思是 : 點 A5 儲存格,按下 Ctrl + ↓,游標從 A5 往下移動,停止在收盤價最後一列的位置 : A4641。參數 Row = 4641。( PS. 值(4641) 再帶給 變數 lastRow 。)
5. [P2] = “=((E2-R2)/(Q2-R2))*100” : 直接在 P2欄(RSV),貼上 RSV 計算公式。
6. [F2] = “=1/3*P2+2/3*F” & lastRow : 直接在 F2欄(K(9,3)),貼上 K值 計算公式。
7. [G2] = “=1/3*F2+2/3*G” & lastRow : 直接在 G2欄(D(9,3)),貼上 D值 計算公式。
( 2 ) : 策略分析
※ 策略分析 : 包含 —
( 一 ) : K < 20 / K > 80 的 信號標記。
( 二 ) : K ↗ D / K ↘ D 的 買 / 賣 標記(次數) 和 買進價 / 買出價
( 三 ) : 獲利總結算。
如下圖 :
[ 公式設定與解說 ] :
※ 首先我們已將歷史資料的回測數據,做了買/賣標記 : 1,也記錄了買/賣價位,現在只要將其加總,便可得知歷年來總買賣的次數/點數與策略績效。
( PS. 因為有牽扯到最新列數的加總問題,所以還是利用 VBA程式,來做處理。)
[ 程式碼 ] :
' 策略分析 -- 加總次數/點數
[I2] = "=SUM(I5:I" & lastRow & ")" ' 買進次數 -- 加總
[J2] = "=SUM(J5:J" & lastRow & ")" ' 買進點數 -- 加總
[L2] = "=SUM(L5:L" & lastRow & ")" ' 賣出次數 --加總
[M2] = "=SUM(M5:M" & lastRow & ")" ' 賣出點數 --加總
[N2] = "=M2-J2" '總結算 -- 策略績效
[ 程式解說 ] :
1. ( I2欄 ~ M2欄 ) : 都是利用 SUM加總函數,將買進/賣出的歷史回測數據做加總。I2欄 – 轉換而來的 EXCEL函式為 =SUM(I5:I4645) : 意思是將 I5 ~ I4645(最後一列lastRow) 的次數/點數,做加總(SUM)。
2. ( N2欄 ) : 函式為 =M2-J2,意思是將 賣出總點數(M2) 減去 買進總點數(M2),所得的數值,就是這個策略的績效。
[ 注意事項 ] :
※ 做好加總公式的計算後,你要了解一個關鍵點,那就是在初始回測的時候,數據是先觸發買進,還是賣出;還有你目前手上是空手,還是已經有進單;這些都關係到在計算總結算點數時,會不會出錯的問題。
[ 圖例解說 ] :
※ 以下圖為例 ,買進點數(I2欄) : 4847.10點 / 賣出點數(J2欄) : 4791.01點,賣出點數 減去 買進點數 = -57.09點(總結算(N2欄)),但這是錯的,為何?
[解] : 買/賣 次數都相同,怎麼錯了? 錯在,KD指標作回測時,第一筆觸發單是 : 先賣出,成交在 2003/08/26,賣出價 : 43.46元。
( PS. 因為這個策略是 : 先買後賣,回測時先觸發 : 賣出,就會導致數據錯誤。)
◎ 所以直接手動將 賣出標記 跟 賣出價 : 43.46元刪除,即可。所得數值如下圖 :
◎ 但還是錯,請參考上圖。刪除賣出標記後,買/賣次數變不相同,如同 均線回測程式 裡說過,買進次數 比 賣出次數 大1 等於是把手上的進單,也一起結算,這樣數據一定錯,所以必須有一個判別的儲存格(J3),來當介質,買進點數扣除掉手上進單點數(介質),這樣的結算數據,才是正確的。
☆ 介質導入
※ 目前需要考量的介質數據是 J2欄,所以就利用 J3欄 ,來做介質儲存格,記錄 : 進單價位;若手上無單,則顯示 : 0。
[ 程式碼 / 介質導入 ] :
' J3欄 / 介質導入 :
If Range("H" & lastRow) = 1 And [F2] > [G2] Then [J3] = [E2]: [N3] = "手上有單": [N4] = 1 ' 買進成立 -- 進單
If Range("K" & lastRow) = 1 And [F2] < [G2] Then [J3] = 0: [N3] = "手上沒單": [N4] = 0 ' 賣出成立 -- 空手
[ 程式解說 ] :
※ ( J3欄 ) : 為進單價位(介質)儲存格,其公式就是 剛進單/剛空手 的判斷式。目的是 : 方便將買進的總點數,直接扣除手上的進單點數,如此便能得知正確的結算數據。
◎ 剛進單 — VBA公式 : If Range(“H” & lastRow) = 1 And [F2] > [G2] Then [J3] = [E2]: [N3] = “手上有單”: [N4] = 1
意思是 : 判別前一日 H欄 的買進標記,是否為 1 且 是否 K值 ↗ D值 (黃金交叉) 。
若 是 (兩條件皆成立) — 在 J3欄 顯示 : E2 (收盤價)資料;N3欄 顯示 : 手上有單;N4欄 : 標記 1。
◎ 剛空手 — VBA公式 : If Range(“K” & lastRow) = 1 And [F2] < [G2] Then [J3] = 0: [N3] = “手上沒單”: [N4] = 0
意思是 : 判別前一日 K欄 的賣出標記,是否為 1 且 是否 K值 ↘ D值 (死亡交叉)。
若 是 (兩條件皆成立) — 則 J3欄 顯示 : 0;N3欄 顯示 : 手上沒單;N4欄 : 標記 0。
★ J2欄 — VBA公式修正 ★
[ 注意 ] :
※ 原 I2欄 及 J2欄 公式 : [I2] = “=SUM(I5:I” & lastRow & “)” 和 [J2] = “=SUM(J5:J” & lastRow & “)”,只做加總處理,現在加入介質判斷,其加總公式,也必須加以修正。
[ 程式碼 ] :
' 策略分析 -- K ↗ D 加總次數/點數
[I2] = "=SUM(I5:I" & lastRow & ")-N4" ' 加總買進次數 減去 N4 (手上是否有單的標記)
[J2] = "=SUM(J5:J" & lastRow & ")-J3" ' 加總買進點數 減去 J3 (手上進單點數)
[ 程式解說 ] :
1. ( I2欄 ) : K ↗ D (買進次數) — 原加總程式為 =SUM(I5:I4645),現修正為 : =SUM(I5:I4645)-N4。
◎ 增加了介質判斷,手上有進單時 : N4欄 會有進單標記 : 1,則將以扣除;空手時 : N4欄 的進單標記為 0,即使扣除,也無大礙。
2. ( J2欄 ) : K ↗ D (買進點數) — 原加總程式為 =SUM(J5:J4645),現修正為 : =SUM(J5:J4645)-J3。
◎ 增加了介質判斷,手上有進單時 : J3欄 會有進單點數,則將以扣除;空手時 : J3欄 的進單點數為 0,即使扣除,也無大礙。
★ 手動資料修補 ★
[ 注意 ] :
☆ 這件事很重要,當你完成以上步驟後,你會發現(下圖紅框內)沒有資料,但程式並沒有問題,問題是出在你下載歷史資料的時間點(2022/04/15),已經過了買進觸發日(2022/04/14),所以它不會去觸發變更條件。
◎ 當你製作此程式時,要注意二種情況 :
1. 買進次數 比 買出次數 大1 : 表示 : 手上有進單。此時,就從 J欄最後一列,往上找,找到 : 134.55,這就是 觸發買進 的價位,請手動將 134.55 的數值,填寫或複製到 J3欄,並在 N3欄 – 填上文字 : 手上有單 / N4欄 – 填上數值 : 1。( PS. 藍框內原數值 : 72,會自動變更為 71。)
2. 買進次數 等於 買出次數 : 表示 : 手上沒單(空手)。此時,資料是正確的,只是 J3 / N3 / N4欄 沒有資料,想增加也行,J3欄 – 填上 : 0 / N3欄 – 填上 : 手上無單 / N4欄 – 填上 : 0。
◎ PS. 以上兩種情況,若不想處理也沒關係,只是要等到再觸發一次 觸發買進 的指令,介質資料才會正常。
0050 KD指標 / 每日數據更新
※ 以上兩個區塊 (即時數據 + 策略分析 與 歷史資料分析) 的程式設定,都已完成。但少了每日更新數據的動作,等於沒用,所以要再製作一個 每日數據更新 的 VBA程式,才能達成自動化的目的。
[ 公式設定與解說 ] :
◎ 複製即時數據 : 選取 A2 ~ G2欄 的資料,複製到 A欄最後一列 的下一列(無資料的新列)。★ 提醒 : 複製成 數值 資料( xlPasteValues )。
◎ 複製策略分析 : 選取 H欄 ~ M欄 最後一列的資料,複製到 H欄最後一列 的下一列(無資料的新列)。★ 提醒 : 複製成 公式 資料( xlPasteFormulas )。
[ 程式碼 ] :
lastRow = Range("A5").End(xlDown).Row ' 藉由 A5,往下搜尋最後一列。)
' 複製今日數據 & KD數據
Range("A2:G2").Copy
Range("A" & lastRow + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues
' 複製策略分析公式
Range("H" & lastRow & ":M" & lastRow).Copy
Range("H" & lastRow + 1).Select
Selection.PasteSpecial Paste:=xlPasteFormulas
[ 程式解說 ] :
1. 首先,藉由 A5 往下搜尋出歷史資料的最後一列列號,其值帶給 變數 lastRow。
————————————————————————————————–
2. Range(“A2:G2”).Copy : 複製 A2欄 ~ G2欄 的資料。
3. Range(“A” & lastRow + 1).Select : 選取要複製到的新欄位起點位置( A欄最後一列 再 +1 )。
4. Selection.PasteSpecial Paste:=xlPasteValues : 貼上複製資料,請注意看使用的參數 : xlPasteValues,此參數用法 : 依字面意思 — 貼成數值。
————————————————————————————————–
5. Range(“H” & lastRow & “:M” & lastRow).Copy : 複製前一日的回測公式, H欄最後一列 ~ M欄最後一列 的公式資料。
6. Range(“H” & lastRow + 1).Select : 選取要複製到的新欄位起點位置( H欄最後一列 再 +1 )。
7. Selection.PasteSpecial Paste:=xlPasteFormulas : 貼上複製資料,請注意看使用的參數 : xlPasteFormulas,此參數用法 : 依字面意思 — 貼成公式。
製作更新按鈕
※ 數據完成,程式也搞定,就在 下午:01:30 台股收盤後,一鍵完成 — 數據自動更新吧 !
[ 更新按鈕製作 ] :
1. 按鈕製作方法 : 請參考 — VBA 按鈕製作。( PS. 製作方式 – 同 台灣50MA回測程式。)
2. 指定巨集 : 游標移動到 更新數據 按鈕上,按 滑鼠右鍵,點選 : 指定巨集。
3. 確定巨集名稱 : 出現 指定巨集 視窗後,選取 : 台灣50_KD數據更新 巨集名稱。
KD指標 策略回測分析
※ KD指標 策略回測 – 能不能賺錢 ?
◎ 以下,根據 幾組策略的回測數據,來說明其策略的可行性;同時,依照各策略進場買進方式,再做另一組定額存股的投資報告,以便比較其績效。
( PS. 擔心程式太多且複雜,所以只提供數據報告。若有興趣研究程式的朋友,請自行研究,有任何問題,歡迎您提問或私訊我。)
☆ 策略一 :
◎ 進場條件 : K值 < 20 之後的黃金交叉 ( K值 ↗ D值 – 買進 )
◎ 出場條件 : K值 > 80 之後的死亡交叉 ( K值 ↘ D值 – 賣出 )
☆ 獲利分析 : 2003/06/30 ~ 2022/04/15,獲利 : 34 點 ( 不含歷年股息 )。
※ 定額存股 :
◎ 進場條件 : 同上,只存不出。
☆ 獲利分析 : 2003/06/30 ~ 2022/04/15,獲利 : 4593.50 點 / 96.80 % ( 不含歷年股息 )。
☆ 策略二 :
◎ 進場條件 : K值 < 20 – 買進
◎ 出場條件 : K值 > 80 – 賣出
☆ 獲利分析 : 2003/06/30 ~ 2022/04/15,獲利 : 63.93 點 ( 不含歷年股息 )。
※ 定額存股 :
◎ 進場條件 : 同上,只存不出。
☆ 獲利分析 : 2003/06/30 ~ 2022/04/15,獲利 : 4666.37 點 / 99.80 % ( 不含歷年股息 )。
☆ 策略三 :
◎ 進場條件 : K值 和 D值 同時 < 20 – 買進
◎ 出場條件 : K值 和 D值 同時 > 80 – 賣出
☆ 獲利分析 : 2003/06/30 ~ 2022/04/15,獲利 : 18.03 點 ( 不含歷年股息 )。
※ 定額存股 :
◎ 進場條件 : 同上,只存不出。
☆ 獲利分析 : 2003/06/30 ~ 2022/04/15,獲利 : 1966.72 點 / 114.60 % ( 不含歷年股息 )。
☆ 策略四 :
※ 這組策略與上面三組策略不同,這組嘗試利用雙向買賣(多空皆進場)的方式,來測試其績效。
◎ 進場條件 : K值 ↗ D值 – 買進0050(做多) / K值 ↘ D值 – 先賣0050(做空)
◎ 出場條件 : K值 < 20 – 回補空單 / K值 > 80 – 賣出多單
☆ 獲利分析 : 2003/06/30 ~ 2022/04/15,獲利 : 8.84 點 ( 不含歷年股息 )。
◎ 這組不做 定額存股 的計算,因為進場條件同 策略一,所以無需再製作。
完整程式碼
Sub 台灣50_KD數據更新()
Dim lastRow As Integer, xMAX As String, xMIN As String
lastRow = Range("A5").End(xlDown).Row ' 藉由 A5,往下搜尋最後一列。)
' 介質導入 -- 手上有單 -- 標記 : 進價 / 空手 -- 標記 : 0
If Range("H" & lastRow) = 1 And [F2] > [G2] Then [J3] = [E2]: [N3] = "手上有單": [N4] = 1
If Range("K" & lastRow) = 1 And [F2] < [G2] Then [J3] = 0: [N3] = "手上沒單": [N4] = 0
' -----------------------------------------------------------------------------
' 複製今日數據 & KD數據
Range("A2:G2").Copy
Range("A" & lastRow + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues
' 複製策略分析公式
Range("H" & lastRow & ":M" & lastRow).Copy
Range("H" & lastRow + 1).Select
Selection.PasteSpecial Paste:=xlPasteFormulas
' -----------------------------------------------------------------------------
lastRow = Range("A5").End(xlDown).Row ' 藉由 A5,往下搜尋最後一列。)
' KD指標 -- 公式設計
[Q2] = "=MAX(C2, C" & lastRow - 7 & ":C" & lastRow & ")" ' 求出 最高值 的公式
[R2] = "=MIN(D2, D" & lastRow - 7 & ":D" & lastRow & ")" ' 求出 最低值 的公式
' RSV值 :
[P2] = "=((E2-R2)/(Q2-R2))*100"
' K值 :
[F2] = "=1/3*P2+2/3*F" & lastRow
' D值
[G2] = "=1/3*F2+2/3*G" & lastRow
' -----------------------------------------------------------------------------
' 策略分析 -- 加總次數/點數
[I2] = "=SUM(I5:I" & lastRow & ")-N4" ' 加總買進次數 減去 N4 (手上是否有單的標記)
[J2] = "=SUM(J5:J" & lastRow & ")-J3" ' 加總買進點數 減去 J3 (手上進單點數)
[L2] = "=SUM(L5:L" & lastRow & ")" ' 賣出次數 --加總
[M2] = "=SUM(M5:M" & lastRow & ")" ' 賣出點數 --加總
[N2] = "=M2-J2" '總結算 -- 策略績效
End Sub
[ 溫馨提醒 } :
完整程式碼的執行程序,跟文章敘述順序,有些不同。例如 : 介質導入 & 複製數據的部分。
主要的原因是 先判別介質條件,有助於簡化程式碼,方便於下一步複製的動作,也不會影響到後續建立策略分析的步驟。
結論
這篇 0050 KD指標 回測程式 的策略設計,主要針對0050的歷史資料,利用 KD指標進出場策略(技術分析),來作數據回測,再加上每天的數據更新,以達到自動化分析的目的。
根據文章後段的策略獲利報告得知,以 技術指標 進場買進的獲利,均不理想。歷史數據分析得知,能賺錢的波段單,皆落在多頭行情;空頭洗刷時,便會吃掉該有的獲利,所以策略該如何改進,就由大家來思考了。
至於 定額存股法 的回測數據同樣誘人,尤其是 策略三 的獲利績效,更高達 114.60%,還不包含歷年股息發放;重點在於 投資金額 不大,20年進場 28次,比起其它策略 7 80次,甚至上百的進單,這組策略算是理想,可列為口袋回測清單。
每種投資法都有優缺點,端看你如何來操作。若你是上班族無法專心看盤,或者你是小資/存股族,想定額存股,上述的回測數據,提供你作參考。
[ 提醒 ] : 若你依照我的操作步驟來製作回測程式,絕不會有問題。問題會出在你的回測數據一定跟我的不同,因為你回測的日期一定跟我的不一樣,回測結果也就不一樣;若你有疑問,不知道數據是否正確,歡迎你來詢問,我可以跟你比對數據,這樣就不會有問題。
非常感謝您看到最後,若在閱讀的過程中,有任何疑問,歡迎您利用左下角 Messenger 直接提問或寫信給我,我會盡快回覆您,最後感謝您的閱讀,感恩 !
( PS. 如果喜歡 股小白 的文章,歡迎到 股小白臉書粉絲頁 點讚,衝人氣,目前不定期分析大盤趨勢,將來會有 每日公報 : 分析並公布跑分的個股資料,讓大家作為投資參考。 )
關 聯 文 章
1. 你知道0050怎樣買,賺最多? — 好用的 0050即時分析系統
- 大盤數據 及 股票資料擷取 是研究股市歷史脈動的必要程序,這可藉由EXCEL的表格設計,程式的撰寫,再透過DDE串接券商的資料源,就能針對財經數據做進一步的匯整與運算分析,大大節省許多抓取資料的時間,讓分析工作能更順利的進行。
- 0050均線回測程式 : 主要是利用均線策略,針對0050的歷史資料,作績效回測。
◎ 內文包含 : 黃金交叉買進/死亡交叉賣出的實際績效,小資族瘋投資–定時定額的存股績效,以及如何達到獲利翻倍的手把手策略教學 — 程式的概念 / 設計 / 操作步驟,皆在文中詳細說明。
3. 高達 114.60% 的獲利策略 – 0050KD指標回測程式
- 0050KD指標回測程式 : 主要是利用KD指標的進出場策略,針對0050的歷史資料,作績效回測。
◎ 內文 : 針對 KD指標 的 超買 / 超賣區,進行多組策略回測,同時也提供 定額存股 的投資績效,做為比較,文中對於 台灣50KD指標回測程式 的概念 / 設計 / 操作步驟,皆有詳盡的圖文說明。
- 0050布林通道回測程式 : 主要是以布林通道(上/下軌)技術指標,當做進出場條件,針對0050的歷史資料,作績效回測。
◎ 內文 : 針對 布林通道 的 上軌/下軌 指標,進行 多/空 雙向策略回測,同時也提供 定額存股 的投資績效,做為比較,文中對於 台灣50布林通道回測程式 的概念 / 設計 / 操作步驟,皆有詳盡的圖文說明。
★ 這四篇文章,資料互相關聯,有興趣學習的朋友,請依照文章順序及內文的操作步驟,一步步完成,就能順利架起 大盤歷史資料自動儲存系統。
V B A 資 源
- EXCEL & VBA功能 筆記 : 將針對文章中所使用的 EXCEL 及 VBA公式 / 工具操作 / 巨集設定 / 控制項的運用,做個整合記錄,方便大家在學習當下的參考與使用。
- VBA 提供相當多的指令用法,VBA指令 彙整筆記,將會陸續記錄 VBA文章 中,所用過的 VBA指令,方便學員們對照運用。
- 語法就是程式的文法。 使用者要與電腦溝通,就必須遵守這些規則。VBA程式語法 筆記 : 將針對 VBA文章 中所使用的 VBA程式語法,做個整合記錄,方便大家在學習當下參考與使用。