Closed troyshu closed 10 years ago
thanks for the detailed report. I can reproduce using the code you provided and will investigate.
Looks like a problem accessing the contract object from separate threads.
The updatePortfolio
method is called in the callback thread and it appends to the global currentPositions
list. You then try to read from that in the main thread and kaboom. There is no problem accessing contract.symbol
from within the callback thread in updatePortfolio
.
Awesome, you're absolutely right! Thank you again for your help.
Below is the code that successfully grabs each position symbol and quantity, in case any one is interested
import datetime as dt
import sys
from time import sleep
from swigibpy import EWrapper, EPosixClientSocket, Contract, Order, TagValue,\
TagValueList
try:
input = raw_input
except:
pass
###
orderId = None
availableFunds = 0
netLiquidationValue = 0
currentPositions = {}
class PlaceOrderExample(EWrapper):
'''Callback object passed to TWS, these functions will be called directly
by TWS.
'''
def openOrderEnd(self):
'''Not relevant for our example'''
pass
def execDetails(self, id, contract, execution):
'''Not relevant for our example'''
pass
def managedAccounts(self, openOrderEnd):
'''Not relevant for our example'''
pass
###############
def nextValidId(self, validOrderId):
'''Capture the next order id'''
global orderId
orderId = validOrderId
def orderStatus(self, id, status, filled, remaining, avgFillPrice, permId,
parentId, lastFilledPrice, clientId, whyHeld):
print(("Order #%s - %s (filled %d, remaining %d, avgFillPrice %f,"
"last fill price %f)") % (
id, status, filled, remaining, avgFillPrice, lastFilledPrice))
def openOrder(self, orderID, contract, order, orderState):
print("Order opened for %s" % contract.symbol)
####account value
def updateAccountValue(self, key, value, currency, accountName):
global availableFunds
global netLiquidationValue
#get how much current available funds we have, also our net liquidation value
if currency == 'USD':
if key == 'AvailableFunds':
availableFunds = float(value)
elif key=='NetLiquidation':
netLiquidationValue = float(value)
def accountDownloadEnd(self,accountName):
print 'account download ended for %s' % (accountName)
def updateAccountTime(self,timestamp):
print 'account information pulled at %s' % (timestamp)
def updatePortfolio(self, contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accoutName):
#this only called when there are actually positions
global currentPositions
symbol = contract.symbol
currentPositions[symbol] = position
# Instantiate our callback object
callback = PlaceOrderExample()
# Instantiate a socket object, allowing us to call TWS directly. Pass our
# callback object so TWS can respond.
tws = EPosixClientSocket(callback)
# Connect to tws running on localhost
tws.eConnect("", 7496, 42)
#account updates
tws.reqAccountUpdates(True,'DU15068')
sleep(3)
print 'available funds: %s' % (availableFunds)
print 'net liquidation value: %s' % (netLiquidationValue)
print 'positions:'
for symbol in currentPositions:
print "%s: %s" % (symbol,currentPositions[symbol])
print("******************* Press ENTER to quit when done *******************\n")
input()
print("\nDisconnecting...")
tws.eDisconnect()
First, let me just say thank you so much for developing swigibpy, it makes interfacing with the Interactive Brokers API using Python infinitely easier (and, combined with the pandas library, can make some pretty powerful trading algos).
I'm running into the C++ memory error std::bad_alloc when trying to access properties (such as symbol) for any open Contracts in my account.
The below is an example (based off of the provided placeorder_example.py): it successfully gets all open positions in my account (the freely accessible IB demo account number is used here), but for any position, when I try to access a property of the Contract (e.g. contract.symbol), it throws the std::bad_alloc error.
Do you know how I could go about resolving this issue? Thank you for your help in advance!
(Because this example uses the demo account, you might have to run this code during market hours and make some trades in the demo account first, because the demo account seems to reset itself nightly, and obviously the code doesn't do anything when there aren't any open positions. Demo account downloadable at https://www.interactivebrokers.com/en/?f=%2Fen%2Fpagemap%2Fpagemap_demo.php, button "Try Individual Demo")