joshuaulrich / IBrokers

R API to Interactive Brokers Trader Workstation
65 stars 54 forks source link

Make placeOrder working with comboleg #42

Open diegoperoni opened 1 year ago

diegoperoni commented 1 year ago

Description

I noticed that order combolegs are not supported in current version.

Expected behavior

I changed just 2 lines of code to make the code working. Hope it is useful!

Minimal, reproducible example


# working function
placeOrder = function(twsconn, Contract, Order) {
  if (!IBrokers::is.twsConnection(twsconn))
    stop("requires twsConnection object")
  if (!IBrokers::is.twsContract(Contract))
    stop("requires twsContract object for Contract arg")
  if (!inherits(Order, "twsOrder"))
    stop("requires twsOrder object for Order arg")
  con <- twsconn[[1]]
  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)
  order <- c(IBrokers::.twsOutgoingMSG$PLACE_ORDER, VERSION, as.character(Order$orderId),
             as.character(Contract$conId), Contract$symbol, Contract$sectype,
             Contract$expiry, Contract$strike, Contract$right, Contract$multiplier,
             Contract$exch, Contract$primary, Contract$currency, Contract$local,
             {
               if (is.null(Contract$tradingClass)) "" else Contract$tradingClass
             }, Contract$secIdType, Contract$secId, Order$action,
             Order$totalQuantity, Order$orderType, Order$lmtPrice,
             Order$auxPrice, Order$tif, Order$ocaGroup, Order$account,
             Order$openClose, Order$origin, Order$orderRef, Order$transmit,
             Order$parentId, Order$blockOrder, Order$sweepToFill,
             Order$displaySize, Order$triggerMethod, Order$outsideRTH,
             Order$hidden)
  if (Contract$sectype == "BAG") {
    #stop("BAG security type not supported") # NEW CODE
    if (is.null(Contract$comboleg)) {
      order <- c(order, 0)
    }
    else {
      comboLeg <- Contract$comboleg
      order <- c(order, length(comboLeg))
      for (i in 1:length(comboLeg)) {
        Leg <- comboLeg[[i]]
        order <- c(order, Leg$conId, Leg$ratio, Leg$action,
                   Leg$exch, Leg$openClose, Leg$shortSaleSlot,
                   #Leg$designatedLocation) # NEW CODE
                   Leg$designatedLocation, Leg$exemptCode) # NEW CODE
      }
      order <- c(order, "0", "0") # NEW CODE  -> orderComboLegsCount, smartComboRoutingParamsCount
    }
  }
  order <- c(order, "", Order$discretionaryAmt, Order$goodAfterTime,
             Order$goodTillDate, Order$faGroup, Order$faMethod, Order$faPercentage,
             Order$faProfile, Order$shortSaleSlot, Order$designatedLocation,
             Order$exemptCode, Order$ocaType, Order$rule80A, Order$settlingFirm,
             Order$allOrNone, Order$minQty, Order$percentOffset, Order$eTradeOnly,
             Order$firmQuoteOnly, Order$nbboPriceCap, Order$auctionStrategy,
             Order$startingPrice, Order$stockRefPrice, Order$delta,
             Order$stockRangeLower, Order$stockRangeUpper, Order$overridePercentageConstraints,
             Order$volatility, Order$volatilityType, Order$deltaNeutralOrderType,
             Order$deltaNeutralAuxPrice, 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$algoStrategy,
             Order$whatIf, "")

  writeBin(order, con)
  assign(".Last.orderId", as.integer(Order$orderId), .IBrokersEnv)
  invisible(as.integer(Order$orderId))
}

# SPX options - conId_1 and conId_2
leg1 = IBrokers::twsComboLeg(conId_1, action='SELL', ratio=1, exchange='CBOE'))
leg2 = IBrokers::twsComboLeg(conId_2, action='SELL', ratio=1, exchange='CBOE'))
bag = IBrokers::twsBAG(leg1, leg2)
bag$symbol = 'SPX'
bag$exch     = 'CBOE'

order = IBrokers::twsOrder(
    orderId       = 9999,
    orderType  = 'SNAP MID',
    auxPrice     = '0',
    lmtPrice      = '',
    openClose  = '',
    goodAfterTime = '',
    tif               = 'GTC',
    outsideRTH = '1',
    action        = 'BUY',
    totalQuantity = 1,
    transmit      = TRUE)

IBrokers::placeOrder(twsconn, bag, order)