Skip to content

Commit 78d9478

Browse files
committed
Update to API v151
1 parent ec8eb45 commit 78d9478

File tree

13 files changed

+253
-17
lines changed

13 files changed

+253
-17
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: rib
22
Title: An R implementation of Interactive Brokers API
3-
Version: 0.5.0
3+
Version: 0.5.1
44
Authors@R: person("Luca", "Billi", email = "noreply.section+dev@gmail.com", role = c("aut", "cre"))
55
Description: A native R implementation of Interactive Brokers API.
66
It establishes a TCP connection to a server and handles

R/Decoder.R

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,9 @@ Decoder <- R6::R6Class("Decoder",
409409
if(private$serverVersion >= MIN_SERVER_VER_D_PEG_ORDERS)
410410
order$discretionaryUpToLimitPrice <- imsg$pop()
411411

412+
if(private$serverVersion >= MIN_SERVER_VER_PRICE_MGMT_ALGO)
413+
order$usePriceMgmtAlgo <- imsg$pop()
414+
412415
private$validate("openOrder", orderId= order$orderId,
413416
contract= contract,
414417
order= order,
@@ -1153,6 +1156,194 @@ Decoder <- R6::R6Class("Decoder",
11531156
ORDER_BOUND= function(imsg) {
11541157

11551158
private$validate("orderBound", imsg$pop(3L), no_names=TRUE)
1159+
},
1160+
1161+
COMPLETED_ORDER= function(imsg) {
1162+
1163+
contract <- Contract
1164+
order <- Order
1165+
orderState <- OrderState
1166+
1167+
contract[c(1L:8L, 10L:12L)] <- imsg$pop(11L)
1168+
1169+
order[c(4L:9L)] <- imsg$pop(6L) # "action" through "tif"
1170+
1171+
order[c("ocaGroup",
1172+
"account",
1173+
"openClose")] <- imsg$pop(3L)
1174+
1175+
order$origin <- map_int2enum("Origin", imsg$pop())
1176+
1177+
order[c("orderRef",
1178+
"permId",
1179+
"outsideRth",
1180+
"hidden",
1181+
"discretionaryAmt",
1182+
"goodAfterTime",
1183+
"faGroup",
1184+
"faMethod",
1185+
"faPercentage",
1186+
"faProfile")] <- imsg$pop(10L)
1187+
1188+
if(private$serverVersion >= MIN_SERVER_VER_MODELS_SUPPORT)
1189+
order$modelCode <- imsg$pop()
1190+
1191+
order[c("goodTillDate",
1192+
"rule80A",
1193+
"percentOffset",
1194+
"settlingFirm",
1195+
"shortSaleSlot",
1196+
"designatedLocation",
1197+
"exemptCode")] <- imsg$pop(7L)
1198+
1199+
order[47L:51L] <- imsg$pop(5L) # "startingPrice" through "stockRangeUpper"
1200+
1201+
order[c("displaySize",
1202+
"sweepToFill",
1203+
"allOrNone",
1204+
"minQty",
1205+
"ocaType",
1206+
"triggerMethod")] <- imsg$pop(6L)
1207+
1208+
order[54L:57L] <- imsg$pop(4L) # "volatility" through "deltaNeutralAuxPrice"
1209+
1210+
if(nzchar(order$deltaNeutralOrderType))
1211+
order[c(58L, 63L:65L)] <- imsg$pop(4L) # "deltaNeutralConId" through "deltaNeutralDesignatedLocation"
1212+
1213+
1214+
order[c("continuousUpdate",
1215+
"referencePriceType",
1216+
"trailStopPrice",
1217+
"trailingPercent")] <- imsg$pop(4L)
1218+
1219+
contract$comboLegsDescrip <- imsg$pop()
1220+
1221+
# ComboLegs
1222+
comboLegsCount <- Validator$i(imsg$pop())
1223+
1224+
if(comboLegsCount > 0L) {
1225+
1226+
contract$comboLegs <- lapply(seq_len(comboLegsCount),
1227+
function(i) {
1228+
1229+
combo <- ComboLeg
1230+
1231+
combo[1L:8L] <- imsg$pop(8L)
1232+
1233+
combo
1234+
})
1235+
}
1236+
1237+
# OrderComboLeg
1238+
orderComboLegsCount <- Validator$i(imsg$pop())
1239+
1240+
if(orderComboLegsCount > 0L)
1241+
order$orderComboLegs <- imsg$pop(orderComboLegsCount)
1242+
1243+
# SmartComboRouting
1244+
smartComboRoutingParamsCount <- Validator$i(imsg$pop())
1245+
1246+
if(smartComboRoutingParamsCount > 0L)
1247+
order$smartComboRoutingParams <- fold_tagvalue(imsg$pop(2L * smartComboRoutingParamsCount))
1248+
1249+
1250+
order[c("scaleInitLevelSize",
1251+
"scaleSubsLevelSize")] <- imsg$pop(2L)
1252+
1253+
order$scalePriceIncrement <- Validator$n(imsg$pop())
1254+
1255+
if(!is.na(order$scalePriceIncrement) && order$scalePriceIncrement > 0L)
1256+
order[73L:79L] <- imsg$pop(7L)
1257+
1258+
1259+
order$hedgeType <- imsg$pop()
1260+
1261+
if(nzchar(order$hedgeType))
1262+
order$hedgeParam <- imsg$pop()
1263+
1264+
order[c("clearingAccount",
1265+
"clearingIntent",
1266+
"notHeld")] <- imsg$pop(3L)
1267+
1268+
# DeltaNeutralContract
1269+
if(Validator$l(imsg$pop())) {
1270+
1271+
contract$deltaNeutralContract <- DeltaNeutralContract
1272+
1273+
contract$deltaNeutralContract[1L:3L] <- imsg$pop(3L)
1274+
}
1275+
1276+
# AlgoStrategy
1277+
order$algoStrategy <- imsg$pop()
1278+
1279+
if(nzchar(order$algoStrategy)) {
1280+
1281+
algoParamsCount <- Validator$i(imsg$pop())
1282+
1283+
if(algoParamsCount > 0L)
1284+
order$algoParams <- fold_tagvalue(imsg$pop(2L * algoParamsCount))
1285+
}
1286+
1287+
order$solicited <- imsg$pop()
1288+
1289+
orderState$status <- imsg$pop()
1290+
1291+
order[c("randomizeSize",
1292+
"randomizePrice")] <- imsg$pop(2L)
1293+
1294+
if(private$serverVersion >= MIN_SERVER_VER_PEGGED_TO_BENCHMARK) {
1295+
1296+
if(order$orderType == "PEG BENCH")
1297+
order[c("referenceContractId",
1298+
"isPeggedChangeAmountDecrease",
1299+
"peggedChangeAmount",
1300+
"referenceChangeAmount",
1301+
"referenceExchangeId")] <- imsg$pop(5L)
1302+
1303+
conditionsSize <- Validator$i(imsg$pop())
1304+
1305+
if(conditionsSize > 0L) {
1306+
1307+
for(i in seq_len(conditionsSize)) {
1308+
1309+
condition <- fCondition(map_int2enum("Condition",
1310+
Validator$i(imsg$pop())))
1311+
1312+
condition[-1L] <- imsg$pop(length(condition) - 1L)
1313+
1314+
order$conditions[[i]] <- condition
1315+
}
1316+
1317+
order[c("conditionsIgnoreRth",
1318+
"conditionsCancelOrder")] <- imsg$pop(2L)
1319+
}
1320+
}
1321+
1322+
order[c("trailStopPrice",
1323+
"lmtPriceOffset")] <- imsg$pop(2L)
1324+
1325+
if(private$serverVersion >= MIN_SERVER_VER_CASH_QTY)
1326+
order$cashQty <- imsg$pop()
1327+
1328+
if(private$serverVersion >= MIN_SERVER_VER_AUTO_PRICE_FOR_HEDGE)
1329+
order$dontUseAutoPriceForHedge <- imsg$pop()
1330+
1331+
if(private$serverVersion >= MIN_SERVER_VER_ORDER_CONTAINER)
1332+
order$isOmsContainer <- imsg$pop()
1333+
1334+
order[122L:129L] <- imsg$pop(8L) # "autoCancelDate" through "parentPermId"
1335+
1336+
orderState[c("completedTime",
1337+
"completedStatus")] <- imsg$pop(2L)
1338+
1339+
private$validate("completedOrder", contract= contract,
1340+
order= order,
1341+
orderState= orderState)
1342+
},
1343+
1344+
COMPLETED_ORDERS_END= function(imsg) {
1345+
1346+
private$validate("completedOrdersEnd")
11561347
}
11571348
)
11581349
)

R/IBClient.R

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ IBClient <- R6::R6Class("IBClient",
144144
# Consistency checks
145145
# TODO: remove this
146146
stopifnot(raw_msg[length(raw_msg)] == as.raw(0L), # Last byte is 0
147-
n > 1L) # At least 2 fields (TODO: too strict?)
147+
n > 0L) # At least 1 field
148148

149149
res <- readBin(raw_msg, character(), n=n)
150150

@@ -576,6 +576,9 @@ cat("Server Version and Timestamp:", res, "\n")
576576
if(self$serVersion >= MIN_SERVER_VER_D_PEG_ORDERS)
577577
payload <- c(payload, order["discretionaryUpToLimitPrice"])
578578

579+
if(self$serVersion >= MIN_SERVER_VER_PRICE_MGMT_ALGO)
580+
payload <- c(payload, order["usePriceMgmtAlgo"])
581+
579582
# TODO: remove this?
580583
# Check that NA's are only in allowed fields
581584
idx <- which(is.na(payload))
@@ -591,6 +594,7 @@ cat("Server Version and Timestamp:", res, "\n")
591594
"scalePriceIncrement", "scalePriceAdjustValue",
592595
"scalePriceAdjustInterval", "scaleProfitOffset",
593596
"scaleInitPosition", "scaleInitFillQty", "cashQty",
597+
"usePriceMgmtAlgo",
594598

595599
# The following ones are not set to "" in the API,
596600
# but left as .Machine$double.xmax
@@ -1069,6 +1073,17 @@ cat("Server Version and Timestamp:", res, "\n")
10691073
private$encodeMsg(msg)
10701074
},
10711075

1072-
cancelTickByTickData= function(reqId) private$req_simple("CANCEL_TICK_BY_TICK_DATA", reqId)
1076+
cancelTickByTickData= function(reqId) private$req_simple("CANCEL_TICK_BY_TICK_DATA", reqId),
1077+
1078+
reqCompletedOrders= function(apiOnly) {
1079+
1080+
msg <- private$initMsg("REQ_COMPLETED_ORDERS")
1081+
1082+
# Add payload
1083+
msg <- c(msg, private$sanitize(list(apiOnly)))
1084+
1085+
# Encode and send
1086+
private$encodeMsg(msg)
1087+
}
10731088
)
10741089
)

R/IBWrap.R

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ IBWrap <- R6::R6Class("IBWrap",
77
public= list(
88

99
# Callbacks
10-
1110
tickPrice= function(tickerId, field, price, size, attrib) warning("Default implementation."),
1211

1312
tickSize= function(tickerId, field, size) warning("Default implementation."),
@@ -164,6 +163,10 @@ IBWrap <- R6::R6Class("IBWrap",
164163

165164
tickByTickMidPoint= function(reqId, time, midPoint) warning("Default implementation."),
166165

167-
orderBound= function(orderId, apiClientId, apiOrderId) warning("Default implementation.")
166+
orderBound= function(orderId, apiClientId, apiOrderId) warning("Default implementation."),
167+
168+
completedOrder= function(contract, order, orderState) warning("Default implementation."),
169+
170+
completedOrdersEnd= function() warning("Default implementation.")
168171
)
169172
)

R/IBWrapSimple.R

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ IBWrapSimple <- R6::R6Class("IBWrapSimple",
1414
initialize= function() self$context <- new.env(),
1515

1616
# Override methods
17-
1817
tickPrice= function(tickerId, field, price, size, attrib) {
1918
cat("Price:", tickerId, field, price, size, unlist(attrib), "\n")
2019
},
@@ -35,14 +34,15 @@ IBWrapSimple <- R6::R6Class("IBWrapSimple",
3534
},
3635

3736
orderStatus= function(orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld, mktCapPrice) {
38-
cat("OrderId:", orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld, mktCapPrice, "\n")
37+
cat("OrderStatus:", orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld, mktCapPrice, "\n")
3938
},
4039

4140
openOrder= function(orderId, contract, order, orderstate) {
4241
self$context$order <- list(id=orderId, contract=contract, order=order, orderstate=orderstate)
42+
cat("OpenOrder:", orderId, "\n")
4343
},
4444

45-
openOrderEnd= function() cat("openOrderEnd.\n"),
45+
openOrderEnd= function() cat("OpenOrderEnd.\n"),
4646

4747
connectionClosed= function() cat("ConnectionClosed.\n"),
4848

@@ -225,7 +225,16 @@ IBWrapSimple <- R6::R6Class("IBWrapSimple",
225225
cat("tickByTickBidAsk:", reqId, time, bidPrice, askPrice, bidSize, askSize, unlist(attribs), "\n"),
226226

227227
tickByTickMidPoint= function(reqId, time, midPoint)
228-
cat("tickByTickMidPoint:", reqId, time, midPoint, "\n")
228+
cat("tickByTickMidPoint:", reqId, time, midPoint, "\n"),
229+
230+
orderBound= function(orderId, apiClientId, apiOrderId)
231+
cat("orderBound:", orderId, apiClientId, apiOrderId, "\n"),
232+
233+
completedOrder= function(contract, order, orderState) {
234+
self$context$completed <- list(contract=contract, order=order, orderstate=orderState)
235+
cat("completedOrder.\n")
236+
},
229237

238+
completedOrdersEnd= function() cat("completedOrdersEnd.\n")
230239
)
231240
)

R/codes.R

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,6 @@ map_inbound <- c( "1" = "TICK_PRICE",
164164
"97" = "HISTORICAL_TICKS_BID_ASK",
165165
"98" = "HISTORICAL_TICKS_LAST",
166166
"99" = "TICK_BY_TICK",
167-
"100" = "ORDER_BOUND")
167+
"100" = "ORDER_BOUND",
168+
"101" = "COMPLETED_ORDER",
169+
"102" = "COMPLETED_ORDERS_END")

R/constants.R

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ MIN_SERVER_VER_SMART_DEPTH <- 146L
5454
MIN_SERVER_VER_REMOVE_NULL_ALL_CASTING <- 147L
5555
MIN_SERVER_VER_D_PEG_ORDERS <- 148L
5656
MIN_SERVER_VER_MKT_DEPTH_PRIM_EXCHANGE <- 149L
57+
MIN_SERVER_VER_COMPLETED_ORDERS <- 150L
58+
MIN_SERVER_VER_PRICE_MGMT_ALGO <- 151L
5759

5860
MIN_CLIENT_VER <- 101L
59-
MAX_CLIENT_VER <- MIN_SERVER_VER_MKT_DEPTH_PRIM_EXCHANGE
61+
MAX_CLIENT_VER <- MIN_SERVER_VER_PRICE_MGMT_ALGO
6062

6163
NO_VALID_ID <- -1L

R/structs.R

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ OrderState <- list(status= "",
128128
minCommission= NA_real_,
129129
maxCommission= NA_real_,
130130
commissionCurrency= "",
131-
warningText= "")
131+
warningText= "",
132+
completedTime= "",
133+
completedStatus= "")
132134

133135
SoftDollarTier <- list(name= "",
134136
val= "",
@@ -254,7 +256,16 @@ Order <- list(orderId= 0L,
254256
mifid2ExecutionAlgo= "",
255257
dontUseAutoPriceForHedge= FALSE,
256258
isOmsContainer= FALSE,
257-
discretionaryUpToLimitPrice= FALSE)
259+
discretionaryUpToLimitPrice= FALSE,
260+
autoCancelDate= "",
261+
filledQuantity= NA_real_,
262+
refFuturesConId= NA_integer_,
263+
autoCancelParent= FALSE,
264+
shareholder= "",
265+
imbalanceOnly= FALSE,
266+
routeMarketableToBbo= FALSE,
267+
parentPermId= NA_integer_,
268+
usePriceMgmtAlgo= NA)
258269

259270
ScannerSubscription <- list(numberOfRows= -1L,
260271
instrument= "",

R/validate.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ generate_validator <- function()
77

88
ev$i <- function(x) {
99
if(is.character(x))
10-
x[x == "2147483647"] <- NA_character_
10+
x[x == "2147483647" | x == "9223372036854775807"] <- NA_character_
1111

1212
as.integer(x)
1313
}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ This implements the IB `EClient` class functionality. Among its methods:
186186
- all other methods that send specific requests to the server.
187187
Refer to the official IB `EClient` class documentation for details and method signatures.
188188

189-
##### [`IBWrap`](R/IBWrap/R)
189+
##### [`IBWrap`](R/IBWrap.R)
190190
Like the official IB `EWrapper` class, this holds the callbacks that are dispatched
191191
when responses are processed. `IBWrap` itself is a base class containing
192192
only dummy methods.

0 commit comments

Comments
 (0)