Futu API(二)- 监听股票实时数据

1,615 阅读3分钟

前言

Futu API(一)- 准备 中已经完成了基础环境的搭建,接下来就是通过监听股票实时数据来做一些事情了。

正文

来看官方给的 Demo 代码:

import time
from futu import *

class StockQuoteTest(StockQuoteHandlerBase):
    def on_recv_rsp(self, rsp_pb):
        ret_code, data = super(StockQuoteTest,self).on_recv_rsp(rsp_pb)
        # ======= diy below =======
        if ret_code != RET_OK:
            print("StockQuoteTest: error, msg: %s" % data)
            return RET_ERROR, data
        print("StockQuoteTest ", data) # StockQuoteTest 自己的处理逻辑
        # print(data['code'].values, data['last_price'].values)
        # ======= diy above =======
        return RET_OK, data
        
quote_ctx = OpenQuoteContext(host='127.0.0.1', port=11111)
handler = StockQuoteTest()
quote_ctx.set_handler(handler)  # 设置实时报价回调
quote_ctx.subscribe(['HK.00700', 'SH.000001', 'SZ.399001'], [SubType.QUOTE])  # 订阅实时报价类型,FutuOpenD 开始持续收到服务器的推送
time.sleep(15)  #  设置脚本接收 FutuOpenD 的推送持续时间为15秒
quote_ctx.close()   # 关闭当条连接,FutuOpenD 会在1分钟后自动取消相应股票相应类型的订阅    

# quote_ctx.start()
# quote_ctx.stop()

Demo 很简单,也很容易理解,只要修改代码中注释了 diy 的部分就行了。这里把自己做的一些测试结果写一下:

  1. 股票代码的前缀。A 股的话会分为 SZSH,分别表示深交所和上交所,另外还有 HKUS 等,可以在软件里面查看前缀;
  2. data['code'].values 获取纯数据。回调数据,即代码中的 data,是一个复杂对象数据,具体字段见 文档。但是,如果你直接使用 data['code'] 会获取到一个对象,如果想要获取到 SH.000001 这样的字符串,需要像 Demo 代码中一样,使用 data['code'].values,其他字段也一样。不过这样得到的数据是个 list,即 ['SH.000001'],使用的时候请注意;
  3. quote_ctx 对象还有 startstop 方法。如果后续要一直运行它,那么在非开盘时间 stop 订阅,还是能够节省一些资源的。

如果文章到这就结束了,貌似有点太水了哈,那我们干脆就把 3 的代码实现了吧。经过查询,得知:

A股市场的交易时间为:每周一到周五上午时段9:30-11:30,下午时段13:00-15:00,其中上午9:15-9:25为早盘集合竞价时间,14:57-15:00为收盘集合竞价时间。——《A股、美股、港股交易时间汇总

利用 time.localtime() 的各种数据来判断当前时间是否符合规则即可。再加上每 10min 轮询一次;打印一些信息;再根据轮询时间计算点提前量,代码如下:

is_subscribing = True
quote_ctx.subscribe(['HK.00700', 'SH.000001', 'SZ.399001'], [ft.SubType.QUOTE])
quote_ctx.stop()

while (True):
    time_obj = time.localtime()
    wday = time_obj.tm_wday
    hour = time_obj.tm_hour
    mins = time_obj.tm_min
    if wday < 5 and hour in [10, 13, 14] or (hour == 9 and mins > 15) or (hour == 11 and mins <= 30) or (hour == 12 and mins > 45):
        if not is_subscribing:
            quote_ctx.start()
            is_subscribing = True
    else:
        if is_subscribing:
            quote_ctx.stop()
            is_subscribing = False

    print('Running state: %s - %s' %
          (is_subscribing, time.ctime()))
    time.sleep(600)

总结

订阅这块差不多就这样了,再剩下就是交易了。futu A 股交易的佣金是万 3,不算高,但是会有 15元/单的平台使用费,这还是挺贵的(虽然它还有阶梯式的套餐)。所以暂时还没有打算用它来进行交易,而是着手去研究怎么用证券公司的软件实现自动交易了。所以后续有关交易的文章可能要等等了。

不过,既然交易用到了其它方式,那么肯定就涉及到服务间的通信,所以这块还是有些内容可写的,各位敬请期待~

认知不是知识。认知是对人性、对趋势、对事物底层逻辑、对世界隐性规则的深刻洞察。——碳9知识卡片