把手边的工具都了解一遍,像是合约、订阅等等。尤其是昨天的订阅,让我们更前一步,但是实际上这样的行情资料,并不适合在Jupyter notebook上,应该是要写在一般的py
档中,所以这篇尝试移植过去。
本日程序码使用:d15_subscribe_change_order.py
由於行情资料会一直进来,Jupyter notebook很适合观察图表,但是程序运作比较难进行,因此制作出一个trader
模组来进行资料处理吧~
首先把一些预设资料设定好,这边设定的是登入资讯,在预设中,先预设登入测试环境的资讯。
class trader:
"""The Shioaji Object"""
def __init__(self) -> None:
self.simulation = True # 是否为测试环境
self.id = "PAPIUSER07"
self.pwd = "2222"
self.api = None
接着最核心的就是登入功能,登入功能会有三个参数:id
、pwd
、simulation
,分别代表登入的帐号、密码、登入的环境,如果没有输入就是使用测试环境。
def login(self, id=None, pwd=None, simulation=True):
"""Login to Shioaji.
Args:
id(str): user ID
pwd(str): the login password
Returns:
bool: True is login successfully, False is not.
"""
print(f"=start login-{datetime.now().strftime('%Y%m%d')}")
if id and pwd:
self.id = id
self.pwd = pwd
try:
# 登入 shioaji
self.api = sj.Shioaji(simulation=simulation)
self.api.login(person_id=self.id, passwd=self.pwd)
except Exception as exc:
print(f"id={self.id}, pwd={self.pwd}...{exc}")
return False
return True
订阅功能,其实就是原本的API简化版,只有一个function名和一个合约参数而已。
def subscribe(self, contract):
print("订阅中")
self.api.quote.subscribe(contract, quote_type=sj.constant.QuoteType.Tick)
解除订阅也是如此,简化原本的呼叫路径。
def unsubscribe(self, contract):
self.api.quote.unsubscribe(contract, quote_type=sj.constant.QuoteType.Tick)
print("取消订阅")
当设定完後,就是要实作罗!
首先制作一个thread
(scraper
),是用来停顿程序,这边设定十秒,在这十秒钟,来收集台指期货的交易Tick,避免太快没有收到资料就结束程序。
有了之後,我们就先登入shioaji,之後再订阅资料,当十秒後关闭订阅。其中当收到的订阅回报时,会有一个回呼(callback)quote_callback
,将由这个功能显示我们的API回复,进行後续的处理。这样的用途是我们收到行情并不是只有一两次而已,而是有长时间收资料的需求,像是我们要收到加权指数即时价格,就要推出台积电现在应该的价格,诸如此类的计算都是需要当下的交易状况,因此需要一个thread和callback搭配,才能持续地收回报与计算作业。
def scraper():
print("start sleeping...")
time.sleep(30)
print("Wake up!!")
timer = threading.Thread(target=scraper) # 建立执行绪
t = trader()
t.login()
@t.api.quote.on_quote
def quote_callback(topic: str, quote: dict):
"""Print quote info.
此版本没有 from shioaji import TickSTKv1了,
所以不能用范例QuoteVersion.v1,
只能用QuoteVersion.v0
"""
print(f"Topic: {topic}, Quote: {quote}")
t._get_subscribe()
t.subscribe(t.api.Contracts.Futures.TXF["TXF202110"])
timer.start() # 执行
timer.join() # 等待结束
t.quote.unsubscribe(t.Contracts.Futures.TXF["TXF202110"])
如此改写,我们就可以重复使用这个class了,不过更好的方式应该是把登入拉出来,变成登入模组和订阅模组。但我们这个范例就先不处理这块,把它全部放在一起,之後需要在切开。
<<: 成员 17 人:60%的人在 10分钟的谈话中,至少会撒 1次谎
处理overfitting的时候:把train data 分析的太细了,训练过头了,这个可以通过ea...
上次做过调色盘的练习,对基本的东西有一些认识之後我们开始继续往下练习~ 其实TableViewy我们...
没有要开车,参赛规定有写不能污言秽语,等我有空再去其他平台写个开车系列的coroutine 这里给个...
前言 今天是铁人赛的第二十一天,终於把之前超前部署的文章存档的扣打都用完了 今天上传的文章,今天才开...
基本流程图与跨职能流程图 流程可以用流程图来表示,但它们有一个缺点——标准流程图无法表明谁负责这些活...