非阻塞模式範例
首先,讓我們來了解什麼是「Blocking」?如果一個函數需要等待某些操作完成才能繼續執行,那麼它就是一個「blocking」函數。無論你是進行 I/O 或是 CPU 相關任務,每個函數都是 blocking 的,因為任何操作都需要花費一定的時間。如果一個函數正在執行需要大量 CPU 運算的任務,那麼它會阻止該函數返回;同樣地,如果一個函數正在試圖從數據庫中取得某些資料,它會一直等待結果返回,直到結果返回為止才繼續執行。
相反,當執行非阻塞(non-blocking)操作時,它永遠不會等待操作完成。如果嘗試在短時間內發送大量請求,非阻塞模式非常有用。為了讓您了解阻塞和非阻塞模式之間的區別,我們提供了一些比較的例子。
Shioaji提供 Blocking 和 Non-Blocking 模式,只需設定 timeout
的值即可。timeout預設為5000(毫秒),表示函數最多等待5秒。
非阻塞模式下單¶
將PlaceOrder
函數中設置 timeout = 0
。
In
IContract contract = _api.Contracts.Stocks["TSE"]["2890"];
var stockOrder = new StockOrder()
{
price = 16.4,
quantity = 1,
action = Action.Buy,
price_type = StockPriceType.LMT,
order_type = StockOrderType.ROD,
order_lot = StockOrderLot.Common,
first_sell = StockFirstSell.No,
custom_field = "914"
};
var trade = new Trade();
trade = _api.PlaceOrder(
contract:contract,
order:stockOrder,
timeout:0,
cb:order_cb
);
Console.WriteLine(trade);
Out
{
contract={
security_type=STK,
code=2890,
symbol=TSE2890,
exchange=TSE,
limit_up=19.1,
limit_down=15.7,
reference=17.4,
margin_trading_balance=0,
short_selling_balance=0,
update_date=2022/09/26,
category=17,
day_trade=Yes,
name=永豐金,
},
order={
action=Buy,
price=15.7,
quantity=1,
price_type=LMT,
order_type=ROD,
order_lot=Common,
order_cond=Cash,
first_sell=false,
account={
account_type=S,
person_id=PERSON_ID,
broker_id=BROKER_ID,
account_id=ACCOUNT_ID,
signed=True,
username=USERNAME,
},
custom_field=test,
ca=,
},
status={
status=Inactive,
order_ts=0,
modified_ts=0,
modified_price=0,
deal_quantity=0,
cancel_quantity=0,
},
}
在非阻塞模式中取得的Trade
物件,因為委託單仍在傳輸中還未送至交易所,所以會缺少一些資訊。在Order
物件中沒有id
和seqno
,OrderStatus
物件中沒有 id
、status_code
、order_datetime
和 Deals
,status
顯示為Inactive
。在非阻塞模式中要取得上述提到的資訊可利用委託回報
和非阻塞模式下單回調
兩種方式。
委託回報¶
Out
OrderState.StockOrder {
"operation": {
"op_type": "New",
"op_code": "00",
"op_msg": ""
},
"order": {
"id": "8bbe0c24",
"seqno": "612978",
"ordno": "IB919",
"account": {
"account_type": "S",
"person_id": "",
"broker_id": "",
"account_id": "",
"signed": true
},
"action": "Buy",
"price": 15.7,
"quantity": 1,
"order_type": "ROD",
"price_type": "LMT",
"order_cond": "Cash",
"order_lot": "Common",
"custom_field": "914"
},
"status": {
"id": "8bbe0c24",
"exchange_ts": 1664152597,
"modified_price": 0,
"cancel_quantity": 0,
"order_quantity": 1,
"web_id": "137"
},
"contract": {
"security_type": "STK",
"exchange": "TSE",
"code": "2890",
"symbol": "",
"name": "",
"currency": "TWD"
}
}
非阻塞模式下單回調¶
In
private static void PlaceOrder(Shioaji _api)
{
IContract contract = _api.Contracts.Stocks["TSE"]["2890"];
var stockOrder = new StockOrder()
{
price = 15.7,
quantity = 1,
action = Action.Buy,
price_type = StockPriceType.LMT,
order_type = StockOrderType.ROD,
order_lot = StockOrderLot.Common,
first_sell = StockFirstSell.No,
custom_field = "test"
};
var trade = _api.PlaceOrder(
contract:contract,
order:stockOrder,
timeout:0,
cb:order_cb // only work in non-blocking mode
);
}
private static void order_cb(Trade trade)
{
Console.WriteLine($"MY_ORDER_CB: {trade}");
}
Out: place order callback
MY_ORDER_CB: {
contract={
security_type=STK,
code=2890,
symbol=TSE2890,
exchange=TSE,
limit_up=19.1,
limit_down=15.7,
reference=17.4,
margin_trading_balance=0,
short_selling_balance=0,
update_date=2022/09/26,
category=17,
day_trade=Yes,
name=永豐金,
},
order={
action=Buy,
price=15.7,
quantity=1,
price_type=LMT,
order_type=ROD,
order_lot=Common,
order_cond=Cash,
first_sell=false,
id=8bbe0c24,
seqno=612978,
ordno=IB919,
account={
account_type=S,
person_id=PERSON_ID,
broker_id=BROKER_ID,
account_id=ACCOUNT_ID,
signed=True,
username=USERNAME,
},
custom_field=test,
ca=,
},
status={
id=8bbe0c24,
status=PendingSubmit,
status_code=0,
order_ts=1664152597,
msg=委託成功,
modified_ts=0,
modified_price=0,
deal_quantity=0,
cancel_quantity=0,
},
}
支援非等待模式的函數
- PlaceOrder
- UpdateOrder
- CancelOrder
- UpdateStatus