1. 程式人生 > >程式化交易之:使用python的baostock介面,實現股票自動盯盤

程式化交易之:使用python的baostock介面,實現股票自動盯盤

        不是每個人都有時間時刻盯盤的,而且股票那麼多,往往掛一漏萬,錯過很多好的股票和買入機會。筆者嘗試用python實現了一個可以自動盯盤的程式,呼叫了一個免費的股票資料介面baostock提供的歷史行情資料和實時資料,實現了對盤中突破10日高點,且在20日均線上股票的提示。目前股票池最大容量為500只股票,同時實現對500只股票的監控,3秒以內就能快速識別和反應,聽上去是不是很酷?如果大家有興趣,可以自己往裡面新增別的功能,實現自己的策略。
首先預設已經安裝python,且版本是3.5或者以上。
安裝pandas: pip insall pandas
安裝numpy: pip install numpy
安裝baostock資料介面包:pip install baostock。
如果有問題,請去官網下載再安裝:

http://www.baostock.com
安裝TA-Lib庫 pip install ta-lib(如果安裝不成功,可進入“https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib”下載如“TA_Lib‑0.4.17‑cp35‑cp35m‑win32.whl”相對應的版本,使用pip install xx.whl進行本地安裝)

程式首先下載股票上一個交易日之前的日K線行情資料,然後計算上一交易日的20日均線,然後比較上一交易日20日均線的值和過去10天最高收盤價兩個值,取其中的最大值作為阻力線,然後再獲取當日實時資料,如果某個時刻突破了這個阻力線,則發出提示資訊。這只是個簡單的策略,大家可以自己在我的程式基礎上,設定自己的策略。

import baostock as bs
import pandas as pd
import numpy as np
import talib as ta
import datetime

# 獲取歷史行情資料,並根據日K線資料設定警示價格
def return_constraintdict(stockcodelist):
    login_result = bs.login(user_id='anonymous', password='123456')
    print('login respond error_msg:'+login_result.error_msg)

    startdate = '2018-01-01'
    today = datetime.datetime.now()
    delta = datetime.timedelta(days=1)
    # 獲取截至上一個交易日的歷史行情
    predate = today - delta
    strpredate = datetime.datetime.strftime(predate, '%Y-%m-%d')

    for stockcode in stockcodelist:
        ### 獲取滬深A股行情和估值指標(日頻)資料並返回收盤價20日均線 ####
        #     date    日期
        #     code    股票程式碼
        #     close    收盤價
        #     preclose    前收盤價
        #     volume    交易量
        #     amount    交易額
        #     adjustflag    復權型別
        #     turn    換手率
        #     tradestatus 交易狀態
        #     pctChg    漲跌幅
        #     peTTM    動態市盈率
        #     psTTM    市銷率
        #     pcfNcfTTM    市現率
        #     pbMRQ    市淨率
        rs = bs.query_history_k_data("%s" % stockcode,
                                     "date,code,close,preclose,volume,amount,adjustflag,turn,tradestatus,pctChg,peTTM,pbMRQ,psTTM,pcfNcfTTM",
                                     start_date=startdate, end_date=strpredate,
                                     frequency="d", adjustflag="2")
        print('query_history_k_data respond error_code:' + rs.error_code)
        print('query_history_k_data respond  error_msg:' + rs.error_msg)

        #### 列印結果集 ####
        result_list = []
        while (rs.error_code == '0') & rs.next():
            # 獲取一條記錄,將記錄合併在一起
            result_list.append(rs.get_row_data())
        result = pd.DataFrame(result_list, columns=rs.fields)

        closelist = list(result['close'])
        closelist = [float(price) for price in closelist]

        malist = ta.MA(np.array(closelist), timeperiod=20)
        if len(malist) > 20 and closelist[-20] > 0:
            ma20value = malist[-1]
            summit20day = max(closelist[-10:])
            # 以突破10日高點且在20日均線以上作為買入條件
            resistancelinedict[stockcode] = max(ma20value, summit20day)
        else:
            resistancelinedict[stockcode] = float(closelist[-1])
    bs.logout()
    return resistancelinedict

# 每次收到實時行情後,回撥此方法
def callbackFunc(ResultData):
    print(ResultData.data)
    for key in ResultData.data:
        # 當盤中價格高於警示價格,輸出提示資訊。
        if key in resistancelinedict and float(ResultData.data[key][6]) > resistancelinedict[key]:
            print("%s,突破阻力線,可以買入" % key)

def test_real_time_stock_price(stockcode):
    login_result = bs.login_real_time(user_id='anonymous', password='123456')
    # 訂閱
    rs = bs.subscribe_by_code(stockcode, 0, callbackFunc, "", "user_params")
#     rs = bs.subscribe_by_code("sz.300009", 0, callbackFunc, "", "user_params")
    if rs.error_code != '0':
        print("request real time error", rs.error_msg)
    else:
        # 使主程式不再向下執行。使用time.sleep()等方法也可以
        text = input("press any key to cancel real time \r\n")
        # 取消訂閱
        cancel_rs = bs.cancel_subscribe(rs.serial_id)
    # 登出
    login_result = bs.logout_real_time("anonymous")

if __name__ == '__main__':
    resistancelinedict = {}
    # stockcodes = "sh.600000,sz.300009,sz.300128,sh.603568,sz.000049"
    stockcodelist = ['sh.600000', 'sz.300009', 'sz.300128',
                     'sh.603568', 'sz.000049', 'sh.600518', 'sz.300532', 'sz.000001']
    stockcodes = ""
    for stockcode in stockcodelist:
        stockcodes = "%s%s," % (stockcodes, stockcode)
    stockcodes = stockcodes[:-1]
    print(stockcodes)
    resistancelinedict = return_constraintdict(stockcodelist)
    #### 登出系統 ####
    test_real_time_stock_price(stockcodes)