Day 15 - Order & Deal Event

本篇重点

Order & Deal Event

当委托单成功建立、修改或取消成功时,都会执行order_callback,预设下的callback就是执行print(stat, msg),把回传的状态及讯息输出。
当然,也可以自己自定callback所要执行的内容,范例如下:

# 定义callback的fuction,名称可自行定义,但所传的参数stat和msg是固定的
def place_cb(stat, msg):
    print('my_place_callback')
    print(f'stat:{stat}')
    print(f'msg:{msg}')
    api.update_status(api.stock_account) #测试,是否可以在成功发送委托单後,自动更新

api.set_order_callback(place_cb) #将刚才自行定义的function名称传入,设定为order的callback执行程序

完整程序范例如下:

rom dotenv import load_dotenv
import os
import shioaji as sj
from shioaji.constant import Action, StockPriceType, TFTOrderType, TFTStockOrderLot

load_dotenv('D:\\python\\shioaji\\.env') #读取.env中的环境变数

api = sj.Shioaji()
api.login(
    person_id=os.getenv('YOUR_PERSON_ID'), 
    passwd=os.getenv('YOUR_PASSWORD')
)

result = api.activate_ca(
    ca_path=os.getenv('YOUR_CA_PATH'),
    ca_passwd=os.getenv('YOUR_CA_PASS'),
    person_id=os.getenv('YOUR_PERSON_ID'),
)
# 定义place_order、update_order及cancel_order後,要执行什麽动作
# 没有定义的话,预设是print(stat, msg)
def place_cb(stat, msg):
    print('my_place_callback')
    print(f'stat:{stat}')
    print(f'msg:{msg}')
    api.update_status(api.stock_account) #测试,是否可以在成功发送委托单後,自动更新

api.set_order_callback(place_cb)

contract = api.Contracts.Stocks['2890']
order = api.Order(
    price=contract.limit_down,
    quantity=2, 
    action=Action.Buy, 
    price_type=StockPriceType.LMT, 
    order_type=TFTOrderType.ROD, 
    order_lot=TFTStockOrderLot.Common, 
    account=api.stock_account
)

trade = api.place_order(contract, order)
print(trade)

执行成功後,可以看到输出结果如下:

OrderState中,最主要看operation这里头的资料,分别有以下三个属性内容:

属性 内容说明
op_type 委托单的动作内容
op_code op_msg对应的code,若为00表示委托动作成功,其余code皆为错误
op_msg 错误讯息内容。若此内容为空,表示委托动作成功

委托单失败

由於官方文件中,只有放成功委托单所回传的OrderState及message,以下列几个在测试时发现的错误讯息范例。
委托单已全部成交,无法进行修改。

Trade(contract=Stock(exchange=<Exchange.TSE: 'TSE'>, code='2890', symbol='TSE2890', name='永丰金', category='17', unit=1000, limit_up=15.3, limit_down=12.6, reference=13.95, update_date='2021/09/27', day_trade=<DayTrade.Yes: 'Yes'>), order=Order(action=<Action.Buy: 'Buy'>, price=13.8, quantity=1, id='0ab3dd4a', seqno='092823', ordno='WA027', account=Account(account_type=<AccountType.Stock: 'S'>, person_id='PAPIUSER06', broker_id='9A95', account_id='0506701', signed=True), price_type=<StockPriceType.LMT: 'LMT'>, order_type=<FuturesOrderType.ROD: 'ROD'>), status=OrderStatus(id='0ab3dd4a', status=<Status.Filled: 'Filled'>, status_code='00', order_datetime=datetime.datetime(2021, 9, 27, 10, 56, 37), modified_price=14.0, deal_quantity=1, deals=[Deal(seq='000928', price=14.0, quantity=1, ts=1632712382)]))
OrderState.TFTOrder {'operation': {'op_type': 'UpdatePrice', 'op_code': '88', 'op_msg': '该委托书已完全成交,不可删单/改量或改价'}, 'order': {'id': '076475b8', 'seqno': '092826', 'ordno': 'WA027', 'account': {'account_type': 'S', 'person_id': '', 'broker_id': '9A95', 'account_id': '0506701', 'signed': True}, 'action': 'Buy', 'price': 13.0, 'quantity': 1, 'order_type': 'ROD', 'order_cond': 'Cash', 'order_lot': 'Common', 'price_type': 'LMT'}, 'status': {'id': '076475b8', 'exchange_ts': 1632712456, 'modified_price': 13.0, 'cancel_quantity': 0}, 'contract': {'security_type': 'STK', 'exchange': 'TSE', 'code': '2890', 'symbol': '', 'name': '', 'currency': 'TWD'}}

股票的价格档数错误,导致金额修改失败。

Trade(contract=Stock(exchange=<Exchange.TSE: 'TSE'>, code='2890', symbol='TSE2890', name='永丰金', category='17', unit=1000, limit_up=15.3, limit_down=12.6, reference=13.95, update_date='2021/09/27', day_trade=<DayTrade.Yes: 'Yes'>), order=Order(action=<Action.Buy: 'Buy'>, price=13.8, quantity=1, id='11e11995', seqno='310462', ordno='XC307', account=Account(account_type=<AccountType.Stock: 'S'>, person_id='F126684691', broker_id='9A79', account_id='0103298', signed=True), price_type=<StockPriceType.LMT: 'LMT'>, order_type=<FuturesOrderType.ROD: 'ROD'>), status=OrderStatus(id='11e11995', status=<Status.Submitted: 'Submitted'>, status_code='00', order_datetime=datetime.datetime(2021, 9, 27, 10, 28, 52), modified_price=13.7, deals=[]))
OrderState.TFTOrder {'operation': {'op_type': 'UpdatePrice', 'op_code': '88', 'op_msg': '价格档数错误'}, 'order': {'id': '12329396', 'seqno': '311673', 'ordno': 'XC307', 'account': {'account_type': 'S', 'person_id': '', 'broker_id': '9A79', 'account_id': '0103298', 'signed': True}, 'action': 'Buy', 'price': 13.71, 'quantity': 1, 'order_type': 'ROD', 'order_cond': 'Cash', 'order_lot': 'Common', 'price_type': 'LMT'}, 'status': {'id': '12329396', 'exchange_ts': 1632710044, 'modified_price': 13.71, 'cancel_quantity': 0}, 'contract': {'security_type': 'STK', 'exchange': 'TSE', 'code': '2890', 'symbol': '', 'name': '', 'currency': 'TWD'}}

盘後定价及盘後零股,非委托时间送出。

Trade(contract=Stock(exchange=<Exchange.TSE: 'TSE'>, code='2890', symbol='TSE2890', name='永丰金', category='17', unit=1000, limit_up=15.3, limit_down=12.6, reference=13.95, update_date='2021/09/27', day_trade=<DayTrade.Yes: 'Yes'>), order=Order(action=<Action.Buy: 'Buy'>, price=13.95, quantity=1, account=Account(account_type=<AccountType.Stock: 'S'>, person_id='PAPIUSER06', broker_id='9A95', account_id='0506701', signed=True), price_type=<StockPriceType.LMT: 'LMT'>, order_type=<FuturesOrderType.ROD: 'ROD'>, order_lot=<TFTStockOrderLot.Odd: 'Odd'>), status=OrderStatus(status=<Status.Failed: 'Failed'>, status_code='74009', order_datetime=datetime.datetime(2021, 9, 27, 14, 31, 45), msg='非委托时间', deals=[]))

<<:  Day21 AJAX 请求方法?

>>:  不要再用print来debug 了 ...

python证照必考题 得票数计算 选举题目 投票问题TQC+ 程序语言 Python 3 _ 409

*TQC+ 程序语言 Python 3 _ 409 得票数计算 * 说明: 某次选举有两位候选人,分...

Ruby幼幼班--Best Time to Buy and Sell Stock

Best Time to Buy and Sell Stock 题目连结:https://leet...

【Day 26】迁移学习(Transfer Learning)(上)

Transfer Learning的意思是,假设你现在有一些跟你的task没有直接相关的data,那...

Day18 javascript 阵列

今天咱们先来简单的稍为介绍一下JavaScript Array(阵列) 物件,JavaScript ...

第30天:《听说做完380个实例,就能成为.NET Core大内高手》里面真的没怎麽讲.NET Core

今天是最後一天了,每天看这本书《听说做完380个实例,就能成为.NET Core大内高手》,真的里面...