我手上留有一些 2016 年四到十月的小台指期原始資料 (Ticks Row Data) Excel 檔 , 用我的第二代台指期自動當沖交易系統做回測時 , 不是賠錢就是沒進場交易 , 我就很好奇那時候的盤到底是長怎樣 , 可是現在已經看不到 2016 年那時候的五分K線圖了 , 剛好最近開始在學 Python , 知道 Python 的功能很強大 , 學習程式語言時我習慣用主題式的學習法 ,
也就是先有一個想要完成的主題目標 , 然後學習如何使用那個程式語言去把主題目標給實做出來 , 有目標的學習不但速度快 , 不會覺得枯燥 , 而且會有很多成就感跟樂趣 , 就像當初在 2016 年我打算開始寫第一代台指期自動當沖交易系統時 , 我根本沒學過 C# , 我是邊研究 Sample Code 邊學 C# 邊寫程式 , 遇到問題就到 Google 上去查找 , 就這樣讓我把系統給寫出來了 , 雖然現在我對 C# 還是一知半解略懂皮毛 , 但是要維護系統已經綽綽有餘了 .
學習 Python 我的最終目標是要寫出一套 [台指期 AI 程式自動當沖交易系統] , 短中期目標是 [台指期原始資料運用及機器學習] . 所以一開始先來處理台指期的原始資料 (Ticks Row Data) , 讓這些資料可以彙總成 1 分K , 5 分K , 10 分K ... , 然後可以用來畫K線圖 , 更進一步可以拿來做為機器學習的資料 .
Python 的第三方套件很多 , 不過好像找不到可以用來處理我手上的台指期原始資料的套件 (可能是我不懂或不會吧 !) , 所以只好自己寫 Python 程式了 , 我的台指期原始資料長的如下圖 :
Python 程式的步驟如下 :
1. 從 Excel 檔中匯入台指期原始資料 , 這個步驟我是用 xlrd 來做 .
2. 寫一個把原始資料彙總成 1 分K的函式 , 資料彙總成 1 分K的序號 , 時間 , 開盤 , 最高 , 最低 , 收盤 及 成交量後先暫存到一個空的 pandas DataFrame 中 , 然後順便再回寫一份處理過的資料到 Excel 檔以備不時之需 . 存在 Excel 中處理過的資料如下圖 :
存在 pandas DataFrame 中的資料如下 :
兩者之間只有差在 timeseconds 這個欄位中的資料 , 在 Excel 中放的是 seconds , 在 DataFrame 中放的是轉換過的時間 , 像 [08:45:00] 這樣 , 我有試過要把轉換過的時間存到 Excel , 但是都沒有成功 , 後來想說存 seconds 也OK , 因為在 pandas 中要把 seconds 轉成像 [08:45:00] 這樣的格式很容易就可以做到 .
以下是我的完整程式碼 :
import pandas as pd
import xlrd
import datetime
# 從 Excel 讀入 ticks row data
book = xlrd.open_workbook('D:\HistoryData\MXF\MXF_20190130.xlsx')
sheet = book.sheet_by_index(0)
# 先開好一個空的 DataFrame
k1 = pd.DataFrame(columns=['k1seq', 'timeseconds', 'open', 'high', 'low', 'close', 'volume'])
#開始秒數 baseSecond = 31500 = 08:45:00
baseSecond = 31500
# k1Seq = 1分K 序號
k1Seq = 0
ticksCount = 0
# --------------------------------------------------------------------------------------------------------------
def ticks_to_k1(secTime, tickPrice, singleVolume):
global baseSecond
global k1Seq
global k1Time
global k1Open
global k1High
global k1Low
global k1Close
global k1TotalVol
global k1
global ticksCount
if k1Seq == 0:
#第一個1分K 的 tick
k1Seq = 1
k1Time = baseSecond
k1Open = tickPrice
k1High = tickPrice
k1Low = tickPrice
k1Close = tickPrice
k1TotalVol = singleVolume
ticksCount = ticksCount + 1
elif (secTime >= baseSecond) and (secTime < baseSecond + 60):
#同一個1分K
if (tickPrice > k1High):
k1High = tickPrice
if (tickPrice < k1Low):
k1Low = tickPrice
k1Close = tickPrice
k1TotalVol = k1TotalVol + singleVolume
ticksCount = ticksCount + 1
#原始資料讀取完畢 , 將最後一分鐘的資料寫入 DataFrame
if ((secTime < baseSecond + 60) and (secTime == 49499) and (ticksCount == sheet.nrows)):
newRow = [[k1Seq, k1Time, k1Open, k1High, k1Low, k1Close, k1TotalVol]]
k1 = k1.append(pd.DataFrame(newRow, columns=['k1seq', 'timeseconds', 'open', 'high', 'low', 'close', 'volume']), ignore_index=True)
elif (secTime > baseSecond + 59):
#寫1分K資料
newRow = [[k1Seq, k1Time, k1Open, k1High, k1Low, k1Close, k1TotalVol]]
k1 = k1.append(pd.DataFrame(newRow, columns=['k1seq', 'timeseconds', 'open', 'high', 'low', 'close', 'volume']), ignore_index=True)
#換1分K
baseSecond = baseSecond + 60
k1Time = baseSecond
k1Seq = k1Seq + 1
k1Open = tickPrice
k1High = tickPrice
k1Low = tickPrice
k1Close = tickPrice
k1TotalVol = singleVolume
ticksCount = ticksCount + 1
# --------------------------------------------------------------------------------------------------------------
for row in range(sheet.nrows):
timesecond = sheet.cell_value(row,1)
price = sheet.cell_value(row,2) / 100
volume = sheet.cell_value(row,3)
ticks_to_k1(timesecond, price, volume)
k1.to_excel('D:\Anaconda3\WorkShop\HistoryFiles\k1\MXF_20190130_k1.xlsx', sheet_name='sheet1', columns=['k1seq', 'timeseconds', 'open', 'high', 'low', 'close', 'volume'])
# 將 'timeseconds' 格式化成 hh:mm:ss
k1['timeseconds'] = pd.to_timedelta(k1['timeseconds'], unit='s')

你的文章右半邊部份被廣告遮蓋。