Getting accounting data out of interactive brokers API into python with swigibpy
This is the very last put up. Not the very last put up of the weblog; which can be suitable news or terrible. But the final put up in my short series on using swigibpy to engage with the C API for interactive brokers (IB).
Interactive brokers now have a local python API. An updated model of this submit which uses that API is right here:http://qoppac.Blogspot.Co.Uk/2017/03/placing-orders-in-native-python-ib-api.Html
Having were given a few fees and submitted some orders we need to know whether or not we made any cash or not. Although the code is rather trivial, interpreting the results calls for a few knowledge.
Http://qoppac.Blogspot.Co.United kingdom/2017/03/getting-role-and-accounting-statistics.Html
So once more you need to get the code from the subsequent repo.
The instance code to run is in test5_IB.Py and wrapper_v5.Py. This will give your effects with stay or simulated Gateway / TWS consultation walking (it likely won't produce some thing of interest with a demo account but you may nonetheless comply with the code). Note that IB have these days up to date their Gateway software so that you might need to re-download.
The output from test5_IB.Py need to be something like what's in green under.
Expiry is 20140908
Portfolio
([('3KTB', '20140617', 12, 106.0, 1272000000.0, 105842090.65714166, 1894912.11, 0.0, 'DU99', 'KRW'), ('BTP', '20140606', 2, 123.2049942, 246409.Ninety nine, 121025.33335, 4359.32, 0.Zero, 'DU99', 'EUR'), ('EMG', '', 1100000, 0.91125, 1002374.99, 0.85376155, 63237.28, 0.0, 'DU99', 'GBP')]
account info
[('AccountCode', 'DU99', '', 'DU99'), ('AccountReady', 'true', '', 'DU99'), ('AccountType', 'INDIVIDUAL', '', 'DU99'),
<SNIP>
, ('WarrantValue', '0', 'USD', 'DU99')]
Contract info - again?
Note we reuse the contract information code in http://qoppac.Blogspot.Co.Uk/2014/05/the-setting-of-orders-to-interactive.Html
The reason we do this is as before to efficiently identify our positions we want the yyyymmdd expiry related to the contract; even though the matching up process is not executed here.
Positions
We're going to use a single client function to get both accounting and position data. However both of these are going to be looking at streamed accounting updates. This is returned by two different kinds of wrapper function.
Since penning this weblog IB have added an API call to get positions without delay - so there are much less clunky methods of doing this than I display here.
From wrapper_v5.Py, elegance IBclient:
def get_IB_account_data(self):
self.Cb.Init_portfolio_data()
self.Cb.Init_error()
## Turn on the streaming of accounting records
self.Tws.ReqAccountUpdates(True, self.Accountid)
start_time=time.Time()
finished=False
iserror=False
whilst now not completed and now not iserror:
finished=self.Cb.Flag_finished_contractdetails
iserror=self.Cb.Flag_iserror
if (time.time() - start_time) > MAX_WAIT_SECONDS:
finished=True
print "Didn't get an quit for account replace, is probably missing stuff"
bypass
## Turn off the streaming
## Note portfolio_structure may also be updated
self.Tws.ReqAccountUpdates(False, self.Accountid)
portfolio_data=self.Cb.Data_portfoliodata
account_value=self.Cb.Data_accountvalue
if iserror:
print self.Cb.Error_msg
print "Problem getting details"
go back None
return (account_value, portfolio_data)
From wrapper_v5.Py, elegance IBWrapper:
def init_portfolio_data(self):
if "data_portfoliodata" no longer in dir(self):
setattr(self, "data_portfoliodata", [])
if "data_accountvalue" now not in dir(self):
setattr(self, "data_accountvalue", [])
setattr(self, "flag_finished_portfolio", False)
def updatePortfolio(self, agreement, role, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName):
"""
Add a row to the portfolio shape
"""
portfolio_structure=self.Data_portfoliodata
portfolio_structure.Append((contract.Image, agreement.Expiry, function, marketPrice, marketValue, averageCost,
unrealizedPNL, realizedPNL, accountName, settlement.Forex))
## account price
def updateAccountValue(self, key, cost, foreign money, accountName):
"""
Populates account cost dictionary
"""
account_value=self.Data_accountvalue
account_value.Append((key, value, foreign money, accountName))
def accountDownloadEnd(self, accountName):
"""
Finished can examine portfolio_structure and account_value
"""
setattr(self, "flag_finished_portfolio", True)
So as soon as we start streaming each the portfolio_structure and account_value global variables start updating. Note that with portfolio_structure we've the equal 'gotcha' as earlier than, namely that we can not simply drop the contract item into the worldwide variable, as all we will get is a pointer that is meaningless out of doors of the wrapper technique. Instead we want to shop particular matters of interest like settlement.Symbol.
Portfolio information
The output portfolio_data will be a list of tuples (contract.symbol, contract.expiry, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName, contract.currency). Note that the value, cost, PNL will be in local currency. You can extract exchange rates from the account_value information - which I discuss below.Lets take an example:
('BTP', '20140606', 2, 123.2049942, 246409.Ninety nine, 121025.33335, 4359.32, 0.Zero, 'DU99', 'EUR')
This is the June 2014 BTP (Italian 10 year bond) which I am long 2 in account DU99 (not my real account quantity) that's trading at 123.205 Euros per settlement. I ought to use the contract information from above to match this to the yyyymm contracts my gadget is aware of approximately. My two contracts are well worth Euro 246,410 due to the fact every settlement rate factor is worth a thousand Euros (I can get this records from the settlement information name).
I actually bought every of these items for 121,half Euros every (so 121.1/2 in fee factors). This unwell conceived lending of 1 / 4 of a million Euros to the most unstable authorities in the Euro area has to date earned me Euros 4359.32 (246,410 minus 2 * 121,0.5; or 2 * [123.205 - 121.025] * one thousand).
Note my found out PnL is zero given that I manifestly haven't sold any of those futures yet (no quick profit taking for account DU99).
Here is the corresponding alternate price from the account_value output.
[... ("ExchangeRate", 0.815491, "EUR", "DU99"),....
("ExchangeRate", 1.00000, "GBP", "DU99"),... ]
From this we will make out that my base currency is GBP, and 1 Euro is well worth zero.815491 GBP. So I can convert my sick gotten gains in monopoly cash ECB issued Euros 4359.32 * zero.815491 = ?3,555 in real money.
For more information see the net documentation
Note be cautious approximately using comparisions between these portfolio snapshots from exclusive instances to calculate your profits. They may not take trades into consideration thoroughly, and when you have offered some thing absolutely or hadn't sold it for the first photo the comparision wont' work.
Finally also be very careful about using these snapshots to work out what positions you have. Firstly it is common to get the position coming back repeated times. So you will need to filter out duplicates. Secondly positions may sometimes not appear at all.
I use my own record of trades to find out what my current position should be. I compare this to the IB snapshot throughout the day. If there are any breaks in the reconciliation I temporarily halt trading. Occasionally this is because IB has sent me a fill I haven't picked up, or because the IB position snapshot is missing some contracts.
Accounting records
The account_value output could be a completely long listing of tuples. Each one includes (keyname, price, forex, account number). Currency BASE indicates it is the debts base currency (GBP for me). Here are some of the greater interesting account price entries.
- ExchangeRate: This is what we use in the get positions example above.
- FuturesPNL: This is how much we have made trading futures today, by currency. BASE is the total in base currency.
- StockMarketValue: Self explanatory
- NetLiquidation: This is what is my account worth if I close all my positions out (ignoring commissions and bid-ask). Its what I use to ultimately determine the total profit and loss used for rescaling my risk capital.
- CashBalance: Quite self explanatory. Negative means you have borrowed money. BASE is the net of your balances converted into base currency.
When you initially do a futures trade in a non BASE country you will have to borrow money for initial margin. Only if you move into profit beyond this will you have no net borrowing. IB charges you for borrowing money! This is done at LIBOR+spread so is expensive for currencies with higher interest rates (this spread is also why I use IMM's to get direct currency exposure). You can flatten out your exposure by doing a spot FX trade. Personally I try and keep a small positive balance in all currencies, although not excessive as this means I am taking on currency risk. Note you can't trade all possible pairs eg if you find you can't buy AUDGBP then try selling GBPAUD instead. The exception is Korea where you can't hold any speculative currency exposure i.e. not arising from margin requirements in other kinds of trading. All you are allowed to do is flatten your Korean currency position back to zero.
There are many extra keywords than proven above. The quality advice I even have for seeking to understand what all of them imply is to start with a smooth simulated account (a demo account is not any proper because you are uncovered to different peoples random buying and selling, and the account will frequently be 'empty'). Take a unload of the account price output, then do a exchange. Take every other sell off, then look forward to fees to transport. By comparing each dump you should be able to see how account price, margin, coins and so on interact. This is quite time ingesting but virtually worth it for an perception into how the IB money owed function for the type of instruments you want to change.
Anything lacking?
I haven't blanketed the full gamut of what you can get from the IB API. There are some newer strategies put in considering the fact that I commenced the use of it to get positions and account summary information. There is a far richer sort of rate and option information that is to be had. I have not looked at fundamental information, choice data, scanners and controlled bills because I don't use them. However I desire there is enough meat in this series of examples to get you started out the usage of IB with swigibpy, and to keep away from losing time trying to apprehend some of the more bizarre behaviour.
This is the final of a chain of 5 posts on constructing a simple interface in python to the IB API the usage of swigiby. The first four posts are:
http://qoppac.Blogspot.Co.United kingdom/2014/03/the use of-swigibpy-so-that-python-will-play.Html
http://qoppac.Blogspot.Co.Uk/2014/04/getting-fees-out-of-ib-api-with.Html
http://qoppac.Blogspot.Co.Uk/2014/04/streaming-costs-from-ib-api-swigibpy.Html
http://qoppac.Blogspot.Co.United kingdom/2014/05/the-putting-of-orders-to-interactive.Html
If you've observed this collection useful then your next steps is probably to learn how to design a scientific trading strategy, and to apprehend the nuts and bolts of making a fully automatic device.