量化交易學習:交易資料自動抓取
題記:一直對量化交易比較感興趣,想先自學一下,將來如果有機會,能到機構實戰就更棒了。去年用matlab做過一個股票下一交易日價格區間的預測演算法,至少在股災前那段時間準確率還行(別笑,預測區間當然不是在正負10%之間),不過受限於自己的本職工作強度太大(苦逼的移動網際網路行業),一直沒能繼續做下去。後面希望能擠時間慢慢做下去,就當是個業餘愛好吧。由於自己的本職工作是做音視訊的編解碼、增強相關的演算法的,所以對量化交易的演算法更偏好一點,其實兩個方向本質上是相通的,都可以抽象為對隨機過程的描述建模,模型建的好,音視訊的壓縮效率更高、增強效果更好,交易演算法的預測準度更高。anyway:我的思路是用RNN-LSTM做學習模型,RNN-LSTM可以用來做自然語言處理,也可以用來做語音識別及增強,當然也可以用來做交易趨勢預測啦。
第一步:抓取交易資料。
無論後面交易演算法多麼核心,都要先解決輸入問題。先解決交易資料的自動抓取吧。沒有絕對的原創,我的這步工作90%都是基於牛人的既有工作,原帖連結:http://www.zhihu.com/question/29648560/answer/56186559,先表示感謝。不過,原帖的程式碼應該是在低版本的python上可以工作的,但是在我的3.4.3版本上不能用,所以我的改造工作大約10%。改造後、可以正常work的程式碼如下:
"""
@author: David
"""
import const as ct
import pandas as pd
import json
import urllib.request
import urllib.error
def get_hist_data(code = None, start = None, end = None, ktype = 'D'):
"""
功能:
獲取個股歷史交易資料
--------
輸入:
--------
code:string
股票程式碼 比如:601989
start:string
開始日期 格式:YYYY-MM-DD 為空時取到API所提供的最早日期資料
end:string
結束日期 格式:YYYY-MM-DD 為空時取到最近一個交易日資料
ktype:string(default=D, 函式內部自動統一為大寫)
資料型別 D=日K線,W=周K線,M=月K線,5=5分鐘,15=15分鐘
30=30分鐘,60=60分鐘
輸出:
--------
DataFrame
date 日期
open 開盤價
high 最高價
close 收盤價
low 最低價
chg 漲跌額
p_chg 漲跌幅
ma5 5日均價
ma10 10日均價
ma20 20日均價
vma5 5日均量
vma10 10日均量
vma20 20日均量
turnover換手率(指數無此項)
"""
code = code_to_APIcode(code.upper())
ktype = ktype.upper()
url = ''
url = get_url(ktype, code)
print(url)
js = json.loads(ping_API(url))
cols = []
if len(js['record'][0]) == 14:
cols = ct.INDEX_DAY_PRICE_COLS
else:
cols = ct.DAY_PRICE_COLS
df = pd.DataFrame(js['record'], columns=cols)
if ktype in ct.K_TYPE_KEY:
df = df.applymap(lambda x:x.replace(u',', u''))
for col in cols[1:]:
df[col]=df[col].astype(float)
if start is not None:
df = df [df.date >= start]
if end is not None:
df = df[df.date <= end]
df = df.set_index('date')
return df
def code_to_APIcode(code):
"""
功能:
驗證輸入的股票程式碼是否正確,若正確則返回API對應使用的股票程式碼
"""
print(code)
if code in ct.INDEX_KEY:
return ct.INDEX_LIST[code]
else:
if len(code) != 6:
raise IOError('code input error!')
else:
return 'sh%s'%code if code[:1] in ['5', '6'] else 'sz%s'%code
def get_url(ktype, code):
"""
功能:
驗證輸入的K線型別是否正確,若正確則返回url
"""
if ktype in ct.K_TYPE_KEY:
url = ct.DAY_PRICE_URL % (ct.PAGE_TYPE['http'], ct.PAGE_DOMAIN['ifeng'],
ct.K_TYPE[ktype], code)
return url
elif ktype in ct.K_TYPE_MIN_KEY:
url = ct.MIN_PRICE_URL % (ct.PAGE_TYPE['http'], ct.PAGE_DOMAIN['ifeng'],
code, ktype)
return url
else:
raise IOError('ktype input error!')
def ping_API(url):
"""
功能:
向API傳送資料請求,若連結正常返回資料
"""
text = ''
try:
#req = Request(url)
text = urllib.request.urlopen(url,timeout=10).read().decode('utf-8')
if len(text) < 15:
raise IOError('no data!')
except Exception as e:
print(e)
else:
return text
#測試入口
print(get_hist_data('300291','2016-09-11'))
這部分程式碼已測試有效、可以直接使用。不過,需要提個醒(尤其是剛開始用python的童鞋):要注意程式碼的縮排,誰讓python的解析器那麼注重格式涅。。。