Skip to content

Commit

Permalink
Update to client version 63
Browse files Browse the repository at this point in the history
This is an attempt to manually merge all the functional changes from
Soren Wilkening's pull request. As I mentioned in the issue, I had to
figure out a way to effectively ignore all the formatting changes in
order to find and review the changes in functionality.

I happened to notice that it looked like Soren used package.skeleton()
to write all his changes to files. I did the same with the existing
version of the package, and that essentially formatted the current
package code the same as Soren's.

The differences are mainly additions to incoming message types,
eWrappers, and order object components. Soren removed some
functionality but it was not clear he did, so I did not remove it.

I did remove all the calls to .Internal() that Soren added, because
the package will not pass R CMD check with them.

Closes #9.

Adds new incoming message types and eWrappers:

  MARKET_DATA_TYPE = "58"
  COMMISSION_REPORT = "59"
  POSITION_DATA = "61"
  POSITION_END = "62"
  ACCOUNT_SUMMARY = "63"
  ACCOUNT_SUMMARY_END = "64"
  VERIFY_MESSAGE_API = "65"
  VERIFY_COMPLETED = "66"
  DISPLAY_GROUP_LIST = "67"
  DISPLAY_GROUP_UPDATED = "68"

Adds new order components:

  exemptCode
  trailingPercent
  scaleTable
  activeStartTime
  activeStopTime
  hedgeType
  hedgeParam
  optOutSmartRouting
  algoStrategy
  conId
  tradingClass

  deltaNeutralConId
  deltaNeutralSettlingFirm
  deltaNeutralClearingAccount
  deltaNeutralClearingIntent
  deltaNeutralOpenClose
  deltaNeutralShortSale
  deltaNeutralShortSaleSlot
  deltaNeutralDesignatedLocation

  scalePriceAdjustValue
  scalePriceAdjustInterval
  scaleProfitOffset
  scaleAutoReset
  scaleInitPosition
  scaleInitFillQty
  scaleRandomPercent

  smartComboRoutingParams
  smartComboRoutingParamsCount
  orderComboLegs
  orderComboLegsCount
  comboLegsCount
  orderMiscOptions
  • Loading branch information
joshuaulrich committed Jul 8, 2019
1 parent b7b9c78 commit a9ae056
Show file tree
Hide file tree
Showing 11 changed files with 450 additions and 27 deletions.
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#useDynLib(IBrokers)
importFrom(utils,
str)
import(zoo, xts)

export(twsConnect,
Expand Down
31 changes: 30 additions & 1 deletion R/eWrapper.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ eWrapper <- function(debug=FALSE, errfile=stderr()) {
scannerParameters <- scannerData <- scannerDataEnd <-
realtimeBars <- currentTime <- fundamentalData <-
deltaNeutralValidation <- tickSnapshotEnd <-
marketDataType <- commissionReport <-
positionData <- positionEnd <-
accountSummary <- accountSummaryEnd <-
verifyMessageAPI <- verifyCompleted <-
displayGroupList <- displayGroupUpdated <-
function(curMsg, msg, timestamp, file, ...) { c(curMsg,msg) }
} else
if(!debug) {
Expand Down Expand Up @@ -138,6 +143,15 @@ eWrapper <- function(debug=FALSE, errfile=stderr()) {
}
deltaNeutralValidation <- function(curMsg, msg, timestamp, file, ...) { c(curMsg, msg) }
tickSnapshotEnd <- function(curMsg, msg, timestamp, file, ...) { c(curMsg, msg) }
commissionReport <- function(curMsg, msg, timestamp, file, ...)
{
e_commissionReport(curMsg, msg, file, ...)
}
marketDataType <- positionData <- positionEnd <-
accountSummary <- accountSummaryEnd <-
verifyMessageAPI <- verifyCompleted <-
displayGroupList <- displayGroupUpdated <-
function(curMsg, msg, timestamp, file, ...) { c(curMsg, msg) }
} else {
# DEBUG code [ twsDEBUG ]
tickPrice <- tickSize <-
Expand All @@ -154,6 +168,11 @@ eWrapper <- function(debug=FALSE, errfile=stderr()) {
scannerParameters <- scannerData <- scannerDataEnd <-
realtimeBars <- currentTime <- fundamentalData <-
deltaNeutralValidation <- tickSnapshotEnd <-
marketDataType <- commissionReport <-
positionData <- positionEnd <-
accountSummary <- accountSummaryEnd <-
verifyMessageAPI <- verifyCompleted <-
displayGroupList <- displayGroupUpdated <-
function(curMsg, msg, timestamp, file, ...) {
cat(as.character(timestamp),curMsg, msg,"\n",file=file[[1]], append=TRUE,...)
}
Expand Down Expand Up @@ -197,7 +216,17 @@ eWrapper <- function(debug=FALSE, errfile=stderr()) {
currentTime = currentTime ,
fundamentalData = fundamentalData ,
deltaNeutralValidation = deltaNeutralValidation,
tickSnapshotEnd = tickSnapshotEnd)
tickSnapshotEnd = tickSnapshotEnd,
marketDataType = marketDataType,
commissionReport = commissionReport,
positionData = positionData,
positionEnd = positionEnd,
accountSummary = accountSummary,
accountSummaryEnd = accountSummaryEnd,
verifyMessageAPI = verifyMessageAPI,
verifyCompleted = verifyCompleted,
displayGroupList = displayGroupList,
displayGroupUpdated = displayGroupUpdated)
class(eW) <- "eWrapper"
invisible(eW)
}
29 changes: 25 additions & 4 deletions R/placeOrder.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,20 @@ function(twsconn,Contract,Order)
con <- twsconn[[1]]

#VERSION <- "28" # Version as of API 9.62
VERSION <- "29" # Version as of API 9.63
#VERSION <- "29" # Version as of API 9.63
#VERSION <- "30" # Version as of API 9.64
VERSION <- "42"
if(is.null(Order$hedgeType) || is.null(Order$hedgeParam))
stop("NEW twsOrder has to be used")

if(Order$orderId == "")
Order$orderId <- reqIds(twsconn)

# write order {{{
order <- c(.twsOutgoingMSG$PLACE_ORDER,
VERSION,
as.character(Order$orderId),
as.character(Contract$conId),
Contract$symbol,
Contract$sectype,
Contract$expiry,
Expand All @@ -32,6 +37,7 @@ function(twsconn,Contract,Order)
Contract$primary,
Contract$currency,
Contract$local,
if(is.null(Contract$tradingClass)) "" else Contract$tradingClass,

# as of 9.63
Contract$secIdType,
Expand All @@ -58,6 +64,7 @@ function(twsconn,Contract,Order)
Order$hidden)

if(Contract$sectype == "BAG") {
stop("BAG security type not supported")
if(is.null(Contract$comboleg)) {
order <- c(order, 0)
} else {
Expand Down Expand Up @@ -88,6 +95,7 @@ function(twsconn,Contract,Order)
Order$faProfile,
Order$shortSaleSlot,
Order$designatedLocation,
Order$exemptCode,
Order$ocaType,
Order$rule80A,
Order$settlingFirm,
Expand All @@ -111,16 +119,29 @@ function(twsconn,Contract,Order)
Order$continuousUpdate,
Order$referencePriceType,
Order$trailStopPrice,
Order$trailingPercent,
Order$scaleInitLevelSize,
Order$scaleSubsLevelSize,
Order$scalePriceIncrement,
Order$scaleTable,
Order$activeStartTime,
Order$activeStopTime)

if(Order$hedgeType != "") {
order <- c(order, Order$hedgeType, Order$hedgeParam)
} else {
order <- c(order, Order$hedgeType)
}

order <- c(order,
Order$optOutSmartRouting,
Order$clearingAccount,
Order$clearingIntent,
Order$notHeld,
"0", # Order$underComp .. not yet supported by IBrokers
"", # Order$algoStrategy .. not yet supported by IBrokers
Order$whatIf
)
Order$algoStrategy,
Order$whatIf,
"")
# }}}

writeBin(order, con)
Expand Down
193 changes: 184 additions & 9 deletions R/processMsg.R
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,106 @@ processMsg <- function(curMsg, con, eWrapper, timestamp, file, twsconn, ...)
eWrapper$errorMessage(curMsg, msg, timestamp, file, twsconn, ...)
} else
if(curMsg == .twsIncomingMSG$OPEN_ORDER) {
msg <- readBin(con, "character", 84)
msg <- readBin(con, "character", 1)
version <- as.integer(msg[1])
msg <- c(msg, readBin(con, "character", 7))
if(version >= 32) {
msg <- c(msg, readBin(con, "character", 1))
}
msg <- c(msg, readBin(con, "character", 3))
if(version >= 32) {
msg <- c(msg, readBin(con, "character", 1))
}
msg <- c(msg, tmp <- readBin(con, "character", 50))
order.deltaNeutralOrderType <- tmp[49]
if(order.deltaNeutralOrderType != "") {
if(version >= 27 & !is.na(order.deltaNeutralOrderType)) {
msg <- c(msg, readBin(con, "character", 4))
}
if(version >= 31 & !is.na(order.deltaNeutralOrderType)) {
msg <- c(msg, readBin(con, "character", 4))
}
}
msg <- c(msg, tmp <- readBin(con, "character", 3))
if(version >= 30) {
msg <- c(msg, readBin(con, "character", 1))
}
msg <- c(msg, tmp <- readBin(con, "character", 3))
if(version >= 29) {
msg <- c(msg, tmp <- readBin(con, "character", 1))
if(tmp[1] != "") {
comboLegsCount <- as.integer(tmp[1])
if(comboLegsCount > 0) {
msg <- c(msg, readBin(con, "character", comboLegsCount * 8))
}
}
msg <- c(msg, tmp <- readBin(con, "character", 1))
if(tmp[1] != "") {
orderComboLegsCount <- as.integer(tmp[1])
if(orderComboLegsCount > 0) {
msg <- c(msg, readBin(con, "character", orderComboLegsCount * 1L))
}
}
}
if(version >= 26) {
msg <- c(msg, tmp <- readBin(con, "character", 1))
if(tmp[1] != "") {
smartComboRoutingParamsCount <- as.integer(tmp[1])
if(smartComboRoutingParamsCount > 0) {
msg <- c(msg, readBin(con, "character", smartComboRoutingParamsCount * 2L))
}
}
}
msg <- c(msg, tmp <- readBin(con, "character", 3))
order.scalePriceIncrement <- as.integer(tmp[3])
if(!is.na(order.scalePriceIncrement)) {
if(version >= 28 & order.scalePriceIncrement > 0) {
msg <- c(msg, readBin(con, "character", 7))
}
}
if(version >= 24) {
msg <- c(msg, tmp <- readBin(con, "character", 1))
order.hedgeType <- tmp[1]
if(order.hedgeType != "") {
msg <- c(msg, tmp <- readBin(con, "character", 1))
}
}
if(version >= 25) {
msg <- c(msg, tmp <- readBin(con, "character", 1))
}
msg <- c(msg, tmp <- readBin(con, "character", 2))
if(version >= 22) {
msg <- c(msg, tmp <- readBin(con, "character", 1))
}
if(version >= 20) {
msg <- c(msg, tmp <- readBin(con, "character", 1))
underCompPresent <- as.integer(tmp[1])
if(!is.na(underCompPresent)) {
if(underCompPresent > 0) {
msg <- c(msg, tmp <- readBin(con, "character", 3))
}
}
}
if(version >= 21) {
msg <- c(msg, tmp <- readBin(con, "character", 1))
order.algoStrategy <- tmp[1]
if(order.algoStrategy != "") {
msg <- c(msg, tmp <- readBin(con, "character", 1))
algoParamsCount <- as.integer(tmp[1])
if(algoParamsCount > 0) {
msg <- c(msg, tmp <- readBin(con, "character", algoParamsCount * 2))
}
}
}
msg <- c(msg, tmp <- readBin(con, "character", 10))
eWrapper$openOrder(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$ACCT_VALUE) {
msg <- readBin(con, "character", 5)
eWrapper$updateAccountValue(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$PORTFOLIO_VALUE) {
msg <- readBin(con, "character", 18)
msg <- readBin(con, "character", 19)
eWrapper$updatePortfolio(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$ACCT_UPDATE_TIME) {
Expand All @@ -101,13 +192,58 @@ processMsg <- function(curMsg, con, eWrapper, timestamp, file, twsconn, ...)
eWrapper$nextValidId(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$CONTRACT_DATA) {
#msg <- readBin(con, character(), 21)
msg <- readBin(con, "character", 28)
#msg <- readBin(con, character(), 28)
msg <- readBin(con, "character", 1)
version <- as.integer(msg[1])
if (version >= 3) {
msg <- c(msg, readBin(con, "character", 1))
}
msg <- c(msg, readBin(con, "character", 16))
if (version >= 4) {
msg <- c(msg, readBin(con, "character", 1))
}
if (version >= 5) {
msg <- c(msg, readBin(con, "character", 2))
}
if (version >= 6) {
msg <- c(msg, readBin(con, "character", 7))
}
if (version >= 8) {
msg <- c(msg, readBin(con, "character", 2))
}
if (version >= 7) {
msg <- c(msg, secIdListCount <- readBin(con, "character", 1))
if (as.integer(secIdListCount) > 0) {
msg <- c(msg, readBin(con, "character", as.integer(secIdListCount) * 2))
}
}
eWrapper$contractDetails(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$EXECUTION_DATA) {
#msg <- readBin(con, character(), 24)
msg <- readBin(con, "character", 24)
msg <- readBin(con, "character", 1)
version <- as.integer(msg[1])
if (version >= 7) {
msg <- c(msg, readBin(con, "character", 1))
}
msg <- c(msg, readBin(con, "character", 7))
if (version >= 9) {
msg <- c(msg, readBin(con, "character", 1))
}
msg <- c(msg, readBin(con, "character", 3))
if (version >= 10) {
msg <- c(msg, readBin(con, "character", 1))
}
msg <- c(msg, readBin(con, "character", 10))
if (version >= 6) {
msg <- c(msg, readBin(con, "character", 2))
}
if (version >= 8) {
msg <- c(msg, readBin(con, "character", 1))
}
if (version >= 9) {
msg <- c(msg, readBin(con, "character", 2))
}
eWrapper$execDetails(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$MARKET_DEPTH) {
Expand All @@ -132,18 +268,18 @@ processMsg <- function(curMsg, con, eWrapper, timestamp, file, twsconn, ...)
} else
if(curMsg == .twsIncomingMSG$RECEIVE_FA) {
#msg <- readBin(con, character(), 2) # 3 with xml string
msg <- readBin(con, "character", 2)
msg <- readBin(con, "character", 3)
stop("xml data currently unsupported")
eWrapper$receiveFA(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$HISTORICAL_DATA) {
header <- readBin(con, character(), 5)
nbin <- as.numeric(header[5]) * 9
msg <- readBin(con, character(), nbin)
msg <- readBin(con, character(), as.integer(nbin))
eWrapper$historicalData(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$BOND_CONTRACT_DATA) {
warning("BOND_CONTRACT_DATA unimplemented as of yet")
stop("BOND_CONTRACT_DATA unimplemented as of yet")
eWrapper$bondContractDetails(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$SCANNER_PARAMETERS) {
Expand Down Expand Up @@ -230,9 +366,48 @@ processMsg <- function(curMsg, con, eWrapper, timestamp, file, twsconn, ...)
eWrapper$deltaNeutralValidation(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$TICK_SNAPSHOT_END) {
#msg <- readBin(con, character(), 2)
msg <- readBin(con, "character", 2)
eWrapper$tickSnapshotEnd(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$MARKET_DATA_TYPE) {
msg <- readBin(con, "character", 3)
eWrapper$marketDataType(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$COMMISSION_REPORT) {
msg <- readBin(con, "character", 7)
eWrapper$commissionReport(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$POSITION_DATA) {
msg <- readBin(con, "character", 15)
eWrapper$positionData(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$POSITION_END) {
msg <- readBin(con, "character", 1)
eWrapper$positionEnd(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$ACCOUNT_SUMMARY) {
msg <- readBin(con, "character", 6)
eWrapper$accountSummary(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$ACCOUNT_SUMMARY_END) {
msg <- readBin(con, "character", 2)
eWrapper$accountSummaryEnd(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$VERIFY_MESSAGE_API) {
msg <- readBin(con, "character", 2)
eWrapper$verifyMessageAPI(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$VERIFY_COMPLETED) {
msg <- readBin(con, "character", 3)
eWrapper$verifyCompleted(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$DISPLAY_GROUP_LIST) {
msg <- readBin(con, "character", 3)
eWrapper$displayGroupList(curMsg, msg, timestamp, file, ...)
} else
if(curMsg == .twsIncomingMSG$DISPLAY_GROUP_UPDATED) {
msg <- readBin(con, "character", 3)
eWrapper$displayGroupUpdated(curMsg, msg, timestamp, file, ...)
} else {
# default handler/error
warning(paste("Unknown incoming message: ",curMsg,". Please reset connection",sep=""), call.=FALSE)
Expand Down
Loading

0 comments on commit a9ae056

Please sign in to comment.