網頁

2019年2月1日 星期五

台指期原始資料處理 (Ticks to 1 Minute K)

我手上留有一些 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')

# -----------------------------------------------------------------------------
 

沒有留言:

張貼留言