{ "info": { "author": "Christopher Singley", "author_email": "csingley@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Intended Audience :: Financial and Insurance Industry", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3 :: Only", "Topic :: Office/Business", "Topic :: Office/Business :: Financial", "Topic :: Office/Business :: Financial :: Accounting", "Topic :: Office/Business :: Financial :: Investment", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Utilities" ], "description": "=========================================================\nPython parser for Interactive Brokers Flex XML statements\n=========================================================\n\n``ibflex`` is a Python library for converting brokerage statement data in\nInteractive Brokers' Flex XML format into standard Python data structures,\nso it can be conveniently processed and analyzed with Python scripts.\n\n*N.B. This module has nothing to do with programmatic trading.\nIt's about reading brokerage reports.*\n\n``ibflex`` is compatible with Python version 3.7+. The parser has no\ndependencies beyond the Python standard library (although the optional client\nfor fetching Flex Statements from Interactive Brokers' server does depend\non `requests`_ ).\n\n**This module is alpha software!** It works and it's useful, but the\nAPI, data structures, etc. are likely to see major changes. Several XML\nschemata are missing, and a few of the more newly-introduced attributes\nfor the existing schemata. There are probably bugs.\n\n`Pull requests`_ are welcome.\n\n\nBreaking Changes in Version 0.13\n===================================\n\nDon't upgrade to version 0.13 if you don't want to rewrite your code.\n\nVersion 0.13 is a near-complete rewrite, with different data structures.\nInstead of returning nested dictionaries, ``ibflex.parser.parse()`` now\nreturns object instances (subclasses of ``ibflex.Types.FlexElement``).\nAs such, values are retrieved by attribute \"dot access\" rather than dictionary\nkey lookups. See below for an example.\n\nThe more interesting/useful enumerated values from the Flex reference\n(e.g. trade notes, corporate action types) are now parsed into Python Enums.\n\nAll sequences are tuples instead of lists. Everything is immutable.\n\nThere's now a hard dependency on Python 3.7; the whole library is built on\ndataclasses and PEP 484 type hinting.\n\nSorry for the disruption, but it was necessary to transition the library from a\nquick hack to a solid foundation that is much more maintainable. The basic\ndata structure (instance attribute access rather than dict keys) is not expected to\nchange again.\n\n\nInstallation\n============\n::\n\n pip install ibflex\n\n\nFlex Parser\n===========\nThe primary facility provided is the ``ibflex.parser`` module, which parses\nFlex-format XML data into a hierarchy of Python objects whose structure\ncorresponds to that of the original Flex statements, with the data converted\ninto appropriate Python types (datetime.datetime, decimal.Decimal, etc.)\n\nUsage example:\n\n.. code:: python\n\n In [1]: from ibflex import parser\n\n In [2]: response = parser.parse(\"2017-01_ibkr.xml\")\n\n In [3]: response\n Out[3]: FlexQueryResponse(queryName='SCP Everything', type='AF', len(FlexStatements)=1)\n\n In [4]: stmt = response.FlexStatements[0]\n\n In [5]: stmt\n Out[5]: FlexStatement(accountId='U770993', fromDate=datetime.date(2017, 1, 2), toDate=datetime.date(2017, 1, 31), period=None, whenGenerated=datetime.datetime(2017, 5, 10, 11, 41, 38), len(CashReport)=3, len(EquitySummaryInBase)=23, len(StmtFunds)=344, len(ChangeInPositionValues)=2, len(OpenPositions)=2140, len(FxPositions)=1, len(Trades)=339, len(CorporateActions)=1, len(CashTransactions)=4, len(InterestAccruals)=1, len(ChangeInDividendAccruals)=5, len(OpenDividendAccruals)=2, len(SecuritiesInfo)=30, len(ConversionRates)=550)\n\n In [6]: trade = stmt.Trades[-1]\n\n In [7]: trade\n Out[7]: Trade(transactionType=, openCloseIndicator=, buySell=, orderType=, assetCategory=, accountId='U770993', currency='USD', fxRateToBase=Decimal('1'), symbol='WMIH', description='WMIH CORP', conid='105068604', cusip=None, isin=None, listingExchange=None, multiplier=Decimal('1'), strike=None, expiry=None, putCall=None, tradeID='1742757182', reportDate=datetime.date(2017, 1, 30), tradeDate=datetime.date(2017, 1, 30), tradeTime=datetime.time(15, 39, 36), settleDateTarget=datetime.date(2017, 2, 2), exchange='BYX', quantity=Decimal('-8'), tradePrice=Decimal('1.4'), tradeMoney=Decimal('-11.2'), taxes=Decimal('0'), ibCommission=Decimal('-0.00680792'), ibCommissionCurrency='USD', netCash=Decimal('11.19319208'), netCashInBase=None, closePrice=Decimal('1.4'), notes=(,), cost=Decimal('-10.853621'), mtmPnl=Decimal('0'), origTradePrice=Decimal('0'), origTradeDate=None, origTradeID=None, origOrderID='0', openDateTime=None, fifoPnlRealized=Decimal('0.339571'), capitalGainsPnl=None, levelOfDetail='EXECUTION', ibOrderID='865480117', orderTime=datetime.datetime(2017, 1, 30, 15, 39, 36), changeInPrice=Decimal('0'), changeInQuantity=Decimal('0'), proceeds=Decimal('11.2'), fxPnl=Decimal('0'), clearingFirmID=None, transactionID='7248583136', holdingPeriodDateTime=None, ibExecID='0001090f.588f449a.01.01', brokerageOrderID=None, orderReference=None, volatilityOrderLink=None, exchOrderId=None, extExecID='S2367553204796', traderID=None, isAPIOrder=False, acctAlias='SCP 0-0', model=None, securityID=None, securityIDType=None, principalAdjustFactor=None, dateTime=None, underlyingConid=None, underlyingSecurityID=None, underlyingSymbol=None, underlyingListingExchange=None, issuer=None, sedol=None, whenRealized=None, whenReopened=None)\n\n In [8]: print(f\"{trade.tradeDate} {trade.buySell.name} {abs(trade.quantity)} {trade.symbol} @ {trade.tradePrice} {trade.currency}\")\n 2017-01-30 SELL 8 WMIH @ 1.4 USD\n\n In [9]: pos = stmt.OpenPositions[-1]\n\n In [10]: pos\n Out[10]: OpenPosition(side=, assetCategory=, accountId='U770993', currency='USD', fxRateToBase=Decimal('1'), reportDate=datetime.date(2017, 1, 31), symbol='VXX', description='IPATH S&P 500 VIX S/T FU ETN', conid='242500577', securityID=None, cusip=None, isin=None, multiplier=Decimal('1'), position=Decimal('-75'), markPrice=Decimal('19.42'), positionValue=Decimal('-1456.5'), openPrice=Decimal('109.210703693'), costBasisPrice=Decimal('109.210703693'), costBasisMoney=Decimal('-8190.802777'), fifoPnlUnrealized=Decimal('6734.302777'), levelOfDetail='LOT', openDateTime=datetime.datetime(2015, 8, 24, 9, 28, 9), holdingPeriodDateTime=datetime.datetime(2015, 8, 24, 9, 28, 9), securityIDType=None, issuer=None, underlyingConid=None, underlyingSymbol=None, code=(), originatingOrderID='699501861', originatingTransactionID='5634129129', accruedInt=None, acctAlias='SCP 0-0', model=None, sedol=None, percentOfNAV=None, strike=None, expiry=None, putCall=None, principalAdjustFactor=None, listingExchange=None, underlyingSecurityID=None, underlyingListingExchange=None, positionValueInBase=None, unrealizedCapitalGainsPnl=None, unrealizedlFxPnl=None)\n\n In [11]: print(f\"{trade.tradeDate} {trade.buySell.name} {abs(trade.quantity)} {trade.symbol} @ {trade.tradePrice} {trade.currency}\")\n 2017-01-30 SELL 8 WMIH @ 1.4 USD\n\n In [12]: [sec for sec in stmt.SecuritiesInfo if sec.conid == trade.conid][0]\n Out[12]: SecurityInfo(assetCategory=, symbol='WMIH', description='WMIH CORP', conid='105068604', securityID=None, cusip=None, isin=None, listingExchange=None, underlyingSecurityID=None, underlyingListingExchange=None, underlyingConid=None, underlyingCategory=None, subCategory=None, multiplier=Decimal('1'), strike=None, expiry=None, maturity=None, issueDate=None, type=None, sedol=None, securityIDType=None, underlyingSymbol=None, issuer=None, putCall=None, principalAdjustFactor=Decimal('1'), code=())\n\n\nFlex Query Report Configuration\n===============================\nConfigure Flex statements through `Interactive Brokers account management`_ .\nReports > Flex Queries > Custom Flex Queries > Configure\n\nYou can configure whatever you like and ibflex should parse it, with these exceptions:\n\n * You can't use European-style date formats (dd/MM/yy or dd/MM/yyyy).\n Just accept the default (yyyyMMdd) or get with the program and use ISO-8601 (yyyy-MM-dd).\n\n * You should use some delimiter between dates & times. The default delimiter\n (semicolon) is fastest to process.\n\n * For the Trades section of the statement, you can't select the options at the\n top for \"Symbol Summary\", \"Asset Class\", or \"Orders\". These will blow up\n the parser. It's fine to check the box for \"Asset Class\" down below, along\n with the other selections for XML attributes.\n\n\nFlex Client\n===========\nOnce you've defined various Flex queries, you can generate an access token\nthat will allow you to generate statements and download them through the web\nAPI, instead of logging in to get them.\n\nReports > Settings > FlexWeb Service\n\nOnce you've got that set up - armed with the token, and the ID# of the desired\nFlex query - ``ibflex.client`` contains the facilities necessary to retrieve\nthem:\n\n.. code:: python\n\n In [1]: from ibflex import client\n In [2]: token = '111111111111111111111111'\n In [3]: query_id = '111111'\n In [4]: response = client.download(token, query_id)\n In [5]: response[:215]\n Out[5]: b'\\n\\n\\n'\n\n\nYou can also just execute client.main() as a script:\n\n.. code:: bash\n\n $ python client.py -t 111111111111111111111111 -q 111111 > 2018-01_ibkr.xml\n\n\nFinally, setup.py installs a script at ``~/.local/bin/flexget``... cron-tastic!\n\n.. code:: bash\n\n $ flexget -t 111111111111111111111111 -q 111111 > 2018-01_ibkr.xml\n\n\nResources\n=========\n* Interactive Brokers `Activity Flex Query Reference`_\n* Interactive Brokers `FlexWeb Service Reference`_\n* `capgains`_ - package that uses ibflex (inter alia) to calculate realized gains\n* `ib-flex-analyzer`_ - Analyze your Interactive Brokers Flex XML reports with pandas\n\n.. _Pull requests: https://github.com/csingley/ibflex/pull/new/master\n.. _requests: https://github.com/requests/requests\n.. _Interactive Brokers account management: https://gdcdyn.interactivebrokers.com/sso/Login\n.. _Activity Flex Query Reference: https://www.interactivebrokers.com/en/software/reportguide/reportguide.htm#reportguide/activity_flex_query_reference.htm\n.. _FlexWeb Service Reference: https://www.interactivebrokers.com/en/software/am/am/reports/flex_web_service_version_3.htm\n.. _capgains: https://github.com/csingley/capgains\n.. _ib-flex-analyzer: https://github.com/wesm/ib-flex-analyzer\n\n\n", "description_content_type": "text/x-rst", "docs_url": null, "download_url": "https://github.com/csingley/ibflex/tarball/0.13", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/csingley/ibflex", "keywords": "Interactive Brokers,ibkr,flex,xml", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "ibflex", "package_url": "https://pypi.org/project/ibflex/", "platform": "", "project_url": "https://pypi.org/project/ibflex/", "project_urls": { "Download": "https://github.com/csingley/ibflex/tarball/0.13", "Homepage": "https://github.com/csingley/ibflex" }, "release_url": "https://pypi.org/project/ibflex/0.13/", "requires_dist": [ "requests; extra == 'web'" ], "requires_python": ">=3.7", "summary": "Parse Interactive Brokers Flex XML reports and convert to Python types", "version": "0.13" }, "last_serial": 5519983, "releases": { "0.11": [ { "comment_text": "", "digests": { "md5": "df137398ad03b0901b85199c0a9f02ba", "sha256": "d06720f86355c38a6ca83bbea57a9af68bcd3055a8839e72919650f70c98d43d" }, "downloads": -1, "filename": "ibflex-0.11.tar.gz", "has_sig": false, "md5_digest": "df137398ad03b0901b85199c0a9f02ba", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15771, "upload_time": "2018-02-02T13:18:39", "url": "https://files.pythonhosted.org/packages/f3/73/7fb2f77abc839e4099ba2bc322fe59a2f2077fb0340d9ea10ffc73117417/ibflex-0.11.tar.gz" } ], "0.12": [ { "comment_text": "", "digests": { "md5": "081a81d39df58b7414a9fd01b7a670e4", "sha256": "e9cd67464d4c075a127a722fff87ac9930650699ad81767c0877d0e347970c6d" }, "downloads": -1, "filename": "ibflex-0.12.tar.gz", "has_sig": false, "md5_digest": "081a81d39df58b7414a9fd01b7a670e4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19022, "upload_time": "2018-12-29T13:10:45", "url": "https://files.pythonhosted.org/packages/5f/bf/bbec7a6e9d038f5907f65fe8ea9f3260f5917c402424d2c7e2b89913cd0a/ibflex-0.12.tar.gz" } ], "0.13": [ { "comment_text": "", "digests": { "md5": "f782758e338966664e47e7c86a5c6498", "sha256": "29d9216732f052963d6915911ad269689eadcccd518bec1bff14831a23914a33" }, "downloads": -1, "filename": "ibflex-0.13-py3-none-any.whl", "has_sig": false, "md5_digest": "f782758e338966664e47e7c86a5c6498", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.7", "size": 25961, "upload_time": "2019-07-11T20:23:59", "url": "https://files.pythonhosted.org/packages/cc/56/79d39ecb692dde88b22e4eca5e82e097af6a65b119f532a4ee46fbf203aa/ibflex-0.13-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c1a9012515cef414bd3ed10995ec6bf8", "sha256": "808c54edd9c9e5fbcfe655ea266919fc396fcdf9c209e6abf325b3628e3635f6" }, "downloads": -1, "filename": "ibflex-0.13.tar.gz", "has_sig": false, "md5_digest": "c1a9012515cef414bd3ed10995ec6bf8", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.7", "size": 28719, "upload_time": "2019-07-11T20:24:01", "url": "https://files.pythonhosted.org/packages/4d/e2/8225a5698b0eb2cbe19416d3757e1b9e80dee02bcb5b1282bbd5b5cf4f72/ibflex-0.13.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "f782758e338966664e47e7c86a5c6498", "sha256": "29d9216732f052963d6915911ad269689eadcccd518bec1bff14831a23914a33" }, "downloads": -1, "filename": "ibflex-0.13-py3-none-any.whl", "has_sig": false, "md5_digest": "f782758e338966664e47e7c86a5c6498", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.7", "size": 25961, "upload_time": "2019-07-11T20:23:59", "url": "https://files.pythonhosted.org/packages/cc/56/79d39ecb692dde88b22e4eca5e82e097af6a65b119f532a4ee46fbf203aa/ibflex-0.13-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c1a9012515cef414bd3ed10995ec6bf8", "sha256": "808c54edd9c9e5fbcfe655ea266919fc396fcdf9c209e6abf325b3628e3635f6" }, "downloads": -1, "filename": "ibflex-0.13.tar.gz", "has_sig": false, "md5_digest": "c1a9012515cef414bd3ed10995ec6bf8", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.7", "size": 28719, "upload_time": "2019-07-11T20:24:01", "url": "https://files.pythonhosted.org/packages/4d/e2/8225a5698b0eb2cbe19416d3757e1b9e80dee02bcb5b1282bbd5b5cf4f72/ibflex-0.13.tar.gz" } ] }