{ "info": { "author": "Brett Graves", "author_email": "alienbrett648@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ], "description": "# PyAlly\nPython3 wrapper for [Ally Invest brokerage API](https://www.ally.com/api/invest/documentation/getting-started/ \"Ally Invest API\")\n\nAlly Bank's investment platform is perfect for smaller investors who value a mature web/mobile interface, and low brokerage fees. I made this wrapper so that I could more easily integrate the platform with Python, and reduce the need for human oversight on my account.\n\nAfter setting up API keys, PyAlly can provide the basic/essential Ally brokerage transaction functions from a simple python request.\n\n## Supported features\n* Stock buy/sell/short/buy-to-cover orders\n* Query account transaction history\n* Represent account holdings\n* Query account holdings\n* Orders supported:\n * Market\n * Stop\n * Limit\n * Stop Limit\n * Stop Loss\n* Instrument quotes\n* Option trading\n\n## Requirements\n* requests-oathlib\n* matplotlib\n\n## Installation\n`pip3 install pyally`\n\nOnce the package is downloaded, we recommend setting environment variables to store Ally API credentials.\n\nLog into [Ally Invest](https://secure.ally.com), go to the specific account page, click Tools->API\n\n\n![Tools](https://github.com/alienbrett/PyAlly/blob/master/resources/tools.PNG?raw=true)\n\n\nFill out the API token application as a Personal Application\n\n\n![New Application](https://github.com/alienbrett/PyAlly/blob/master/resources/new_application.PNG?raw=true)\n\n\nEnter the API tokens and secrets into your environment variables \n\n\n![Details](https://github.com/alienbrett/PyAlly/blob/master/resources/details.PNG?raw=true)\n\n\nInsert the following into `~/.bashrc`:\n\n```bash\nexport ALLY_CONSUMER_KEY=XXXXXXXXXXXXXXXXXXXXXXXX\nexport ALLY_CONSUMER_SECRET=XXXXXXXXXXXXXXXXXXXXX\nexport ALLY_OATH_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXX\nexport ALLY_OATH_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXX\n```\n\n\n## Documentation\n\n#### Initialize\n```python\nimport ally\na = ally.Ally()\n```\n\n\n### Account Functions\n#### Transaction History\n```python\n#\tGet transaction history in JSON dictionary form\n#\t\t- Optionally specify account, if not in set in\n#\t\tenvironment\n#\t\t- Optionally specify type of transaction, must be \n#\t\t\t\"all\", \"bookkeeping\", or \"trade\"\n# [default \"all\"]\n# - Optionally specify time window for transactions, must be in \n# \"all\", \"today\", \"current_week\", \"current_month\", \"last_month\"\n# [default \"all\"]\ntrans_history = a.account_history(\n\taccount=12345678,\n\ttype=\"all\",\n range=\"current_week\"\n)\n```\n\n#### Current Account Holdings\n```python\n# Get current holdings for an account in JSON dict format\n# Uses default account if not specified\n# Optionally dump json to file\ncurrent_holdings = a.get_holdings(\n account=12345678,\n outfile=\"./holdings.json\"\n)\n```\n\n#### Holdings Pie Chart\n```python\n# Create pie graph of asset allocations for account, using matplotib\n# Dumps to file ./graph.png by default\n# Specify account optionally\n# - specify regen=True to prevent outputting cached graph [default False]\npie_file = a.holdings_chart(\n account=12345678,\n graph_file=\"./my_graph_file.png\",\n regen=True\n)\n```\n\n\n#### Live Quotes\n```python\n# Get quote:\n# Go to\n# https://www.ally.com/api/invest/documentation/market-ext-quotes-get-post/\n# to see available fields options\n# [defaults to None]\nquote = a.get_quote(\n symbols=\"SPY,ALLY\",\n fields=\"ask,bid,vol\"\n)\n```\n\n\n\n### Instruments\n\n#### Equity\n```python\nEquity(\"SPY\") # Perfectly equivalent statements\nInstrument('spy') # Perfectly equivalent statements\n```\n#### Option\n```python\nCall (\n instrument = Equity(\"spy\"), # Underlying\n maturity_date = \"2019-09-30\", # Expiration date\n strike = 290 # Strike\n)\n\nPut (\n instrument = Instrument(\"ALLY\"), # Underlying\n maturity_date = \"2019-10-18\", # Expiration date\n strike = 300 # Strike\n)\n```\n\n### Orders\n`Order( timespan, type, price, instrument, quantity)`\n```python\nmarket_buy = ally.order.Order(\n\n # Good for day order\n timespan = ally.order.Timespan('day'),\n\n # Buy order (to_open is True by defaul)\n type = ally.order.Buy(),\n\n # Market order\n price = ally.order.Market(),\n\n # Stock, symbol F\n instrument = ally.instrument.Equity('f'),\n\n # 1 share\n quantity = ally.order.Quantity(1)\n)\n```\n\n#### TimeInForce (Timespans)\n```python\n#### Timespans\nTimespan('day')\nTimespan('gtc')\nTimespan('marketonclose')\n```\n\n\n\n#### Types\n```python\nBuy() # Buy to open (default)\nBuy(to_open=False) # Buy to cover\n\nSell() # Sell short (default)\nSell(to_open=False) # Sell to close\n```\n\n\n\n#### Pricing\n```python\nMarket () # Give me anything\nLimit (69) # Execute at least as favorably as $69.00\nStop (4.20) # Stop order at $4.20\nStopLimit (\n Stop (10), # Stop at $10.00\n Limit (9.50) # No worse than $9.50\n)\nStopLoss (\n isBuy=False, # Interpret stop as less than current price\n pct=True, # Treat 'stop' as pct\n stop=5.0 # Stop at 5% from highest achieved after order placed\n)\nStopLoss (\n isBuy=True, # Interpret stop as less than current price\n pct=False, # Treat 'stop' as pct\n stop=5.0 # Stop at $5.00 above lowest price\n)\n```\n\n\n#### Quantity\n```python\nQuantity ( 15 ) # In shares or lots, for an option\n```\n\n#### Submitting an Order\n```python\nexec_status = a.submit_order(\n\n # specify order created, see above\n order=,\n\n # Can dry-run using preview=True, defaults to True\n # Must specify preview=False to actually execute\n preview=True,\n\n # Like always, if not specified in environment, use a specific account\n account=12345678\n)\n\n```\n\n\n## Author\n* [Brett Graves](https://github.com/alienbrett)\n\n## Contributing\nPlease contact me if you enjoyed the project or thought it could be improved. I do my best to code with quality but sometimes it is easier said than done. Anyone with an interest with an eye for detail is welcome to contribute.\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/alienbrett/PyAlly", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "pyally", "package_url": "https://pypi.org/project/pyally/", "platform": "", "project_url": "https://pypi.org/project/pyally/", "project_urls": { "Homepage": "https://github.com/alienbrett/PyAlly" }, "release_url": "https://pypi.org/project/pyally/0.2.4/", "requires_dist": null, "requires_python": "", "summary": "Ally Invest API Wrapper", "version": "0.2.4" }, "last_serial": 5733406, "releases": { "0.1.1": [ { "comment_text": "", "digests": { "md5": "ab3690d33accc8e23b9959553e602198", "sha256": "e6dd92894e669fd48c13f971554ae505f3070e9a06d96d68ec84d30b96b776e0" }, "downloads": -1, "filename": "pyally-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "ab3690d33accc8e23b9959553e602198", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 9097, "upload_time": "2019-08-10T22:28:37", "url": "https://files.pythonhosted.org/packages/65/8e/66790ea1cb360e42855e15a2ae6e6e04effd6e48093370bd07cbe81e2463/pyally-0.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "36fb27ff0abe3771cff72e2c50fb18d9", "sha256": "e6b196ef53ed38c5710ca29311c7afe0df5398f9759168d07b6c797a605b8dca" }, "downloads": -1, "filename": "pyally-0.1.1.tar.gz", "has_sig": false, "md5_digest": "36fb27ff0abe3771cff72e2c50fb18d9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8425, "upload_time": "2019-08-10T22:28:39", "url": "https://files.pythonhosted.org/packages/c8/bb/6e69dea2306863625b4dfccdfda46134a4f8f64c3da7eef2cdf4a44cca88/pyally-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "ba47ecde826982d5cfca65f33324fd65", "sha256": "48968ea563cdb3e1f5c90dc902871776a963b430fe6a473174e756828bbb361f" }, "downloads": -1, "filename": "pyally-0.1.2-py3-none-any.whl", "has_sig": false, "md5_digest": "ba47ecde826982d5cfca65f33324fd65", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 9588, "upload_time": "2019-08-10T23:15:29", "url": "https://files.pythonhosted.org/packages/d7/5e/87a03ce5d57d35613db621a436c3dca53316dd51357b00f4558ea055f928/pyally-0.1.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9936e8f1d9b8c323d7e47927416cbbc8", "sha256": "9bf50bd117bea33a31693f62e4441460b289816d4c3488912a480bf4b1e02ebc" }, "downloads": -1, "filename": "pyally-0.1.2.tar.gz", "has_sig": false, "md5_digest": "9936e8f1d9b8c323d7e47927416cbbc8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8668, "upload_time": "2019-08-10T23:15:31", "url": "https://files.pythonhosted.org/packages/44/f0/c3a4c04c2ae23fd5236c53d50a8de11398bec7f5499882bbbbb50a88972c/pyally-0.1.2.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "b173bc62c396103206e3f91f6b0f8694", "sha256": "de12c51aabbc41097754481f2583dbb3379252a9027bd69fc433c4d01d1119f0" }, "downloads": -1, "filename": "pyally-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "b173bc62c396103206e3f91f6b0f8694", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11824, "upload_time": "2019-08-22T18:36:38", "url": "https://files.pythonhosted.org/packages/8b/21/6639fd6f21448db3c541c8abc174a968b5671f8a0af873db58272b84ebb5/pyally-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f6d19e19150c0f48350d4cab44cc7d6a", "sha256": "dd1ec5f32e588832eb269901fef2a1c6d52eb611cb34b7d7db90eeedf5d5d120" }, "downloads": -1, "filename": "pyally-0.2.0.tar.gz", "has_sig": false, "md5_digest": "f6d19e19150c0f48350d4cab44cc7d6a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12150, "upload_time": "2019-08-22T18:36:39", "url": "https://files.pythonhosted.org/packages/d9/79/8044518862a46f19e79470b5f506ded526cf2e4c4b431e7a26771f68b9f3/pyally-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "b7435ade428baf34268c1b1e53306a0c", "sha256": "e9b64249adddc67dbd95f71a0b1d649883fe0167306ba12a9b3e52a4448a87be" }, "downloads": -1, "filename": "pyally-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "b7435ade428baf34268c1b1e53306a0c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11857, "upload_time": "2019-08-26T21:46:52", "url": "https://files.pythonhosted.org/packages/88/89/f50ac25f982391b07594d51bccd619e6774661fead079f1592db702a2d47/pyally-0.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9d3183a9b0af8ffb68249e95708f11a0", "sha256": "783d66e40d9481eac9260ff9d03e3b33af959cd2e61092599427db723977a090" }, "downloads": -1, "filename": "pyally-0.2.1.tar.gz", "has_sig": false, "md5_digest": "9d3183a9b0af8ffb68249e95708f11a0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12188, "upload_time": "2019-08-26T21:46:53", "url": "https://files.pythonhosted.org/packages/65/28/ac93626fd78a75ff9220d166f9a4146f7c9653ab32cb031464b6bc9075be/pyally-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "3a8b6fbb8a52277bf9f2621ff5e73b89", "sha256": "bd3ea648f1bf7097775b4cd09524e6129176417e4b993733e3e6e7d81cf03578" }, "downloads": -1, "filename": "pyally-0.2.2-py3-none-any.whl", "has_sig": false, "md5_digest": "3a8b6fbb8a52277bf9f2621ff5e73b89", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11859, "upload_time": "2019-08-26T21:50:44", "url": "https://files.pythonhosted.org/packages/9f/c2/d0a671cd9ccdc4df83abf08befaf8b2e74f423e5fbda599eecc6047706ac/pyally-0.2.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f5f70ebc2836d11cca7ea0facef0d9bb", "sha256": "47aefeace20c4d7f9b22841c28e0f996766b74c85eef19d3128eca5320fa4268" }, "downloads": -1, "filename": "pyally-0.2.2.tar.gz", "has_sig": false, "md5_digest": "f5f70ebc2836d11cca7ea0facef0d9bb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12193, "upload_time": "2019-08-26T21:50:46", "url": "https://files.pythonhosted.org/packages/70/75/568a9a0bfd84ecbbd36ad192b49d3a7a14d770b01c53667d2ff4e6f7402d/pyally-0.2.2.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "83e6c419061e7579712ca85e0e7d7610", "sha256": "c1e9b154d73008aa39b8fd979168a647d8cf43abc32b388ed16e8d08c6c9f948" }, "downloads": -1, "filename": "pyally-0.2.3-py3-none-any.whl", "has_sig": false, "md5_digest": "83e6c419061e7579712ca85e0e7d7610", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11857, "upload_time": "2019-08-26T21:54:48", "url": "https://files.pythonhosted.org/packages/e0/2a/1d5ff837084cab31f8b04e3e0f7c0e00a0a23cde5a3d2d3afd5edbd85534/pyally-0.2.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f7cba25289fbcda3a07da051db50650c", "sha256": "48e2ae7377d3d7d2878e80ad8bd0aaea5df52e26d6a414708519958336e5712f" }, "downloads": -1, "filename": "pyally-0.2.3.tar.gz", "has_sig": false, "md5_digest": "f7cba25289fbcda3a07da051db50650c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12191, "upload_time": "2019-08-26T21:54:50", "url": "https://files.pythonhosted.org/packages/ad/6b/fbff1b2e94168d79e19a3926dda852ca36dcd0b6bf0c39b229532a780f48/pyally-0.2.3.tar.gz" } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "0b17c23c9c10e5e0eb7b92c060b84a7d", "sha256": "b05ac7c0f0d9bd21b156839d1fb8147919134357e4fb128f7f173baeee7e327b" }, "downloads": -1, "filename": "pyally-0.2.4-py3-none-any.whl", "has_sig": false, "md5_digest": "0b17c23c9c10e5e0eb7b92c060b84a7d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11872, "upload_time": "2019-08-26T21:58:52", "url": "https://files.pythonhosted.org/packages/45/96/9dbc0228ad35383b0077c3395753c06b9f3614e0f3e8efe0fcbac7437d7d/pyally-0.2.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "778ec4ddd82fae53ac524b5265d42feb", "sha256": "508c41d4b74d7919729906c994859bdcdeafb9e63c283a9f86956ec028a48abb" }, "downloads": -1, "filename": "pyally-0.2.4.tar.gz", "has_sig": false, "md5_digest": "778ec4ddd82fae53ac524b5265d42feb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12197, "upload_time": "2019-08-26T21:58:54", "url": "https://files.pythonhosted.org/packages/97/d1/e059326c3c3787d538f523f97d0466229ef3c44efefdf98bff199f03467c/pyally-0.2.4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "0b17c23c9c10e5e0eb7b92c060b84a7d", "sha256": "b05ac7c0f0d9bd21b156839d1fb8147919134357e4fb128f7f173baeee7e327b" }, "downloads": -1, "filename": "pyally-0.2.4-py3-none-any.whl", "has_sig": false, "md5_digest": "0b17c23c9c10e5e0eb7b92c060b84a7d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11872, "upload_time": "2019-08-26T21:58:52", "url": "https://files.pythonhosted.org/packages/45/96/9dbc0228ad35383b0077c3395753c06b9f3614e0f3e8efe0fcbac7437d7d/pyally-0.2.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "778ec4ddd82fae53ac524b5265d42feb", "sha256": "508c41d4b74d7919729906c994859bdcdeafb9e63c283a9f86956ec028a48abb" }, "downloads": -1, "filename": "pyally-0.2.4.tar.gz", "has_sig": false, "md5_digest": "778ec4ddd82fae53ac524b5265d42feb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12197, "upload_time": "2019-08-26T21:58:54", "url": "https://files.pythonhosted.org/packages/97/d1/e059326c3c3787d538f523f97d0466229ef3c44efefdf98bff199f03467c/pyally-0.2.4.tar.gz" } ] }