歡迎使用社群 Markdown 編輯器寫文章!
在學習pandas的時候有時候我會覺得非常奇怪,為什麼美國的投資公司這麼重視Pandas,甚至在招聘要求上註明量化投資分析師要掌握pandas呢?例如我見到Gelber Group的交易員崗位中,註明了這樣的一句話:“經濟學、金融、統計學或相關領域的學士學位,且具有以下的程式設計經驗 - Python(NumPy、pandas 和相關庫)。”
後來我也去登入一下美股的股票庫,覺得是以下幾個原因:
首先,美股上市公司的股票量大,全美國大概有2萬支上市公司股票,可能有人覺得不是很多,但中國上證加深證加起來也不過5千幾隻股票,即使再加上香港4千多,也不過是美股一半的體量左右。而要在這一定時間內查詢2萬隻股票中有那些可以在近期進行投資,可以說是一頓非常花時間的操作,而如果能靠計算機分析,這會是一個很有效率的工具。
其次,現金賬戶交易規則不同。A股主要是當天買的股票最早第二個交易日才能賣(T+1),美股沒有此方面的限制, 當日可賣(T+0),這就決定了你必須在最短的時間內決定是否購入和出售手中的股票。而且更厲害的是高頻交易的投資公司,平均每次持倉時間極短,用量變來達到質變,甚至還要求交易員自己寫計算機程式。所以割起韭菜來,已經不是用人力了,而是自動化收割了。
不過,在中國,現時是沒有高頻交易這樣的事的,因為單日開倉交易量超過10手的,會被納入“日內開倉交易量異常”等的導常交易行為。
再次,美國股票下跌過程中也有進行對衝的工具,即可以買跌獲利,如渾水之類的公司,這個時候,如果想穩健一點,用計算機每天計算出好幾個能互衝的投資組合,理論上可以抵擋不少的市場風險,達到持續收益的目的。
所以在美國金融市場,可以見到很多投資公司有一個專門的量化投資部門或量化投資公司,而交易員和分析員大多數是數學出身,或是計算機程式設計師,他們除了會研究股票,還會研究那型別的CPU能提高交易速度,也會修改程式碼,努力減少每個bug。因為他們清楚,這些雖然不會讓他們賺到多少錢,但往往會減少他們會虧的錢。這就是我們審計中常說的——風險控制比盈利重要。
注意:我是審計師,不是程式設計師。
國內涉及證券的兩個庫分別為tushare、baostock,由於tushare需要積分,我只好介紹baostock庫,它對個人使用者除了能免費使用外,還不需要註冊,對初學者比較友好。而且它能提供大量上市公司歷年財務資料,行情資料。
如果是Anaconda執行環境,即通過Anaconda prompt進入命令列。
一般我們用Jupyter Notebook的話,就一定要在Anaconda prompt輸入pip install baostock才能成功安裝。
安裝成功後,我們就可以通過baostock介面查詢到股票資料,具體使用方法可以到官網查詢:http://baostock.com/baostock/index.php/Python_API文件
不過官網的程式碼只有最基本的功能,且沒有中文,一般來說我都會作一些修改,如我的日K線程式碼:
##歷史K線指標
import baostock as bs ##呼叫baostock庫
import pandas as pd ##呼叫pandas庫
# 登陸系統
lg = bs.login()
# 周月線指標:date,code,open,high,low,close,volume,amount,adjustflag,turn,pctChg
#code:股票程式碼,sh或sz.+6位數字程式碼
rs = bs.query_history_k_data_plus("sh.000001",
"date,code,open,high,low,close,preclose,volume,amount,pctChg",##以半形逗號分隔。此引數不可為空;
start_date='2017-01-01', end_date='2021-06-30', frequency="d")##查詢的起始日
##frequency:資料型別,預設為d,日k線;d=日k線、w=周、m=月、5=5分鐘、15=15分鐘、30=30分鐘、60=60分鐘k線資料
# 設定一個空集
data_list = []
while (rs.error_code == '0') & rs.next():##rs.error_code:當為“0”時表示連線成功,當為非0時表示失敗;next()返回下一個專案
# 獲取一條記錄,將記錄合併在一起
data_list.append(rs.get_row_data())#當以上的條件成立時,將資料放到空集中
result = pd.DataFrame(data_list, columns=rs.fields)##匯入pandas中
result.rename(columns={'date':'日期'},inplace=True) #將表頭的名稱改成統一的名稱
result.rename(columns={'code':'證券號'},inplace=True) #將表頭的名稱改成統一的名稱
result.rename(columns={'open':'開盤價'},inplace=True) #將表頭的名稱改成統一的名稱
result.rename(columns={'high':'最高價'},inplace=True) #將表頭的名稱改成統一的名稱
result.rename(columns={'low':'最低價'},inplace=True) #將表頭的名稱改成統一的名稱
result.rename(columns={'close':'收盤價'},inplace=True) #將表頭的名稱改成統一的名稱
result.rename(columns={'preclose':'昨日收盤價'},inplace=True) #將表頭的名稱改成統一的名稱
result.rename(columns={'volume':'成交數量(股)'},inplace=True) #將表頭的名稱改成統一的名稱
result.rename(columns={'amount':'成交金額(元)'},inplace=True) #將表頭的名稱改成統一的名稱
result.rename(columns={'pctChg':'漲跌幅'},inplace=True) #將表頭的名稱改成統一的名稱
result["成交金額(元)"].astype(float)
# 輸出到excel檔案
with pd.ExcelWriter("d:\歷史K線指標.xlsx", mode='a',engine='openpyxl') as writer:
result.to_excel(writer,index=False)
print(result)
# 登出系統
bs.logout()
結果如下:
由於我查的是2017年度至2021年6月30日的資料,資料量不多,我直接用EXCEL的圖表進行分析。
可見,最近幾個月上證的成交金額漸漸升高。
程式碼說明:
1、 lg = bs.login()是必須要用到的程式碼,沒有這一行的話,就不能連線到庫,當然沒有網路的話也是連線不到的。
2、 bs.query_history_k_data_plus是一個專門用來查詢K線指標的函式,在baostock庫還有很多不同的函式,主要的函式如下:
函式名稱 | 作用 |
---|---|
query_history_k_data_plus() | 獲取滬深A股估值指標(日頻)資料(指數未提供估值資料) |
query_dividend_data() | 獲取除權除息資訊資料(預披露、預案、正式都已通過) |
query_adjust_factor() | 獲取復權因子資訊資料 |
query_profit_data() | 獲取季頻盈利能力資訊 |
query_operation_data() | 獲取季頻營運能力資訊 |
query_growth_data() | 獲取季頻成長能力資訊 |
query_balance_data() | 獲取季頻償債能力資訊 |
query_cash_flow_data() | 獲取季頻現金流量資訊 |
query_dupont_data() | 獲取季頻杜邦指數資訊 |
query_performance_express_report() | 獲取季頻公司業績快報資訊 |
query_stock_basic() | 獲取證券基本資料 |
query_stock_industry() | 獲取行業分類資訊 |
query_sz50_stocks() | 獲取上證50成分股資訊,更新頻率:每週一更新。 |
query_hs300_stocks() | 獲取滬深300成分股資訊,更新頻率:每週一更新。 |
query_zz500_stocks() | 獲取中證500成分股資訊,更新頻率:每週一更新。 |
query_deposit_rate_data() | 獲取存款利率 |
query_loan_rate_data() | 獲取貸款利率 |
query_required_reserve_ratio_data() | 獲取存款準備金率 |
query_money_supply_data_month() | 獲取貨幣供應量 |
query_shibor_data() | 獲取銀行間同業拆放利率 |
基本上程式碼不用改,只改函式命令就可以得出不同的結果。
3、 while (rs.error_code == ‘0’) & rs.next():是一個條件語句,如果不等於0,就表示連線不成功,所以當=0時,和還有下一個資料時,我們可以進行合併。
4、 合併用了append()函式,目的用於在列表末尾新增新的物件,rs.get_row_data()就是這些新的物件了。
5、 result.rename(columns={‘date’:’日期’},inplace=True)是一個將列名替換的語句,意思就是將原來用英文表示的date替換成中文‘日期’。
從這段程式碼我們可以將baostock庫理解成一個固定了格式的爬蟲庫,使用的目的其實就是為了獲得一個資料介面,然後將資料轉化成pandas格式,以便我們進行資料分析。
本作品採用《CC 協議》,轉載必須註明作者和本文連結