stake


Namestake JSON
Version 0.8.2 PyPI version JSON
download
home_pagehttps://github.com/stabacco/stake-python
SummaryUnofficial https://hellostake.com API wrapper.
upload_time2024-03-08 11:52:30
maintainer
docs_urlNone
authorStefano Tabacco
requires_python>=3.8,<4.0.0
licenseApache-2.0
keywords stake trading stocks financial python
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
![Coverage](coverage.svg)[![Downloads](https://pepy.tech/badge/stake)](https://pepy.tech/project/stake)[![Downloads](https://pepy.tech/badge/stake/month)](https://pepy.tech/project/stake)

# Stake

**Stake** is an unofficial Python client for the [Stake](https://hellostake.com) trading platform.

This library wraps the current Stake api and allows common trade operations, such as submitting buy/sell requests, checking your portfolio etc...

Please note that, at the current stage, the Stake client is asynchronous.

## Installation

```$
pip install stake
```

## Quickstart

After you install the package, you will need to authenticate to Stake in order to get authorization to interact with your account.
In order to successfully issue requests to the Stake platform you will need to authenticate to it. Every requests to the Stake endpoints will need to contain a `Stake-Session-Token` in the request headers.

## Using an existing Session-Token

You can retrieve one of these `Stake-Session-Token` by using the developer tools in your browser (Network tab) and inspecting some of the request headers sent to some of the `https://global-prd-api.hellostake.com/` host. (For example, click on the wishlist of dashboard links to see some session-token authenticated requests)

They are usually valid for 30 days (be sure to enable that checkbox on login) and seem to get refreshed before expiry so you should be good to use them directly.

If you already have an existing token you can pass it on to the `StakeClient` as such:

```python

from stake import StakeClient, SessionTokenLoginRequest, CredentialsLoginRequest
import asyncio

login_request = SessionTokenLoginRequest()
async def print_user():
    async with StakeClient(login_request) as stake_session:
        print(stake_session.user.first_name)
        print(stake_session.headers.stake_session_token)

asyncio.run(print_user())
```

> **_NOTE:_** The default value of the token is read from the `STAKE_TOKEN` environment variable. If you have that env-var set you should be able to just use:
> `async with StakeClient() as stake_session: ...`

## Login with your credentials

If you prefer to pass in your username/password credentials to login instead, it's easy to do:

### If you do not have two-factor authentication enabled

```python

from stake import StakeClient, SessionTokenLoginRequest, CredentialsLoginRequest
import asyncio

login_request = CredentialsLoginRequest(
    username="youruser@name.com", # os.getenv("STAKE_USER") by default
    password="yoursecretpassword") # os.getenv("STAKE_PASS") by default

async def print_user(request: CredentialsLoginRequest):
    async with StakeClient(request) as stake_session:
        print(stake_session.user.first_name)
        print(stake_session.headers.stake_session_token)

asyncio.run(print_user(login_request))
```

### If you have two-factor authentication enabled

In this case you need to have your phone around, get the current code from the authenticator app and add it to the `CredentialsLoginRequest` as such:

```python
    login_request = CredentialsLoginRequest(username="youruser@name.com",password="yoursecretpassword",
        otp="Your-authenticator-app-code")
```

Obviously, this can become a bit inconvenient, since you will need to provide the otp code every time you instantiate a new `StakeClient` instance. Therefore, you could probably authenticate once with your credentials, retrieve the session token from the headers(`stake_session.headers.stake_session_token`), and store it in the `STAKE_TOKEN` env-var for subsequent usages.

## Choose your trading exchange

Stake can currently trade on the NY stock exchange (default for this library) as well as the Australian ASX. In order to choose which trading market to use you can initialize the client by specifying the `exchange` argument:

```python
import asyncio
from typing import Union

import stake


async def show_current_orders(
    current_exchange: Union[stake.constant.ASXUrl, stake.constant.NYSEUrl]
):
    async with stake.StakeClient(exchange=current_exchange) as stake_session:
        my_equities = await stake_session.orders.list()
        return my_equities

# ASX
print(asyncio.run(show_current_orders(stake.ASX)))

# NYSE
print(asyncio.run(show_current_orders(stake.NYSE)))

```

Alternatively you can call the `set_exchange` method on the `StakeClient` object.

One thing to note, is that the apis for the two exchanges are currently wildly different, and this reflects in some parts of this library as well.
You might find that the way you need to perform a trade (as well as the resulting response) is somewhat different when switching between exchanges.

As a rule of thumb the code for the ASX stake api resides in the `stake.asx` python package
while the one for the USA one is under the main `stake` namespace (for backwards compatibitity mostly, it might get moved to `stake.nyse` in the future).

## Examples

With `stake-python` you can do most of the operations that are available through the web app.

Here are some examples:

### Display the contents of your portfolio

```python
import stake
import asyncio
from stake.constant import NYSE

async def show_portfolio():
    # here the client will use the STAKE_TOKEN env var for authenticating
    async with stake.StakeClient(exchange=NYSE) as stake_session:
        my_equities = await stake_session.equities.list()
        for my_equity in my_equities.equity_positions:
            print(my_equity.symbol, my_equity.yearly_return_value)
        return my_equities

asyncio.run(show_portfolio())
```

Which will return something like:

```bash
AAPL 80.48
ADBE 251.35
GOOG 559.89
GRPN -13.77
HTZ -10.52
MSFT 97.14
NFLX 263.55
NIO 17.3
NVDA 410.04
OKTA 96.31
SHOP 690.68
SPOT 142.88
SQ 101.75
TQQQ 115.82
TSLA 402.37
VGT 130.08
ZM 331.1
```

### Buy/Sell shares

You can send buy/sell orders to the platform quite easily by just issuing trade requests.
Please check the `stake.trade` module for more details.

```python

import asyncio
import stake

async def example_limit_buy():
    symbol = "TSLA"
    async with stake.StakeClient() as stake_session:
        return await stake_session.trades.buy(
            stake.LimitBuyRequest(symbol=symbol, limitPrice=10, quantity=1000)
        )

asyncio.run(example_limit_buy())
```

To perform multiple requests at once you can use an `asyncio.gather` operation to run all the buy trades in parallel.

```python

import asyncio
import stake

async def example_stop_sell(symbol='TSLA'):
    """THis example will add a stop sell request for one of your equities"""
    async with stake.StakeClient() as stake_session:
        my_equities = await stake_session.equities.list()
        tsla_equity = [equity for equity in my_equities.equity_positions if equity.symbol == symbol][0]
        stop_price = round(tsla_equity.market_price - 0.025 * tsla_equity.market_price)
        stop_sell_request = stake.StopSellRequest(symbol=tsla_equity.symbol,
                                                  stopPrice=stop_price,
                                                  comment="My stop sell.",
                                                  quantity=tsla_equity.available_for_trading_qty)
        return await stake_session.trades.sell(request=stop_sell_request)

asyncio.run(example_stop_sell('MSFT'))
```

### Watchlists

These are some examples on how to interact with watchlists:

```python
import stake
import asyncio
from stake.watchlist import Watchlist

async def create_watchlist(name: str) -> "Watchlist":
    async with stake.StakeClient() as stake_session:
        request= stake.CreateWatchlistRequest(name = name)
        new_watchlist = await stake_session.watchlist.create_watchlist(request=request)
        return new_watchlist

asyncio.run(create_watchlist(name='My watchlist'))
```

```python
import stake
import asyncio
from stake.watchlist import Watchlist

async def update_watchlist(id: str, tickers: "List[str]") -> "Watchlist":
    async with stake.StakeClient() as stake_session:
        request= stake.UpdateWatchlistRequest(id=id, tickers=tickers)
        watchlist = await stake_session.watchlist.add_to_watchlist(request=request)
        return watchlist

asyncio.run(update_watchlist(id=WATCHLIST_ID, tickers=["TSLA", "MSFT", "GOOG"] ))
```

```python
import stake
import asyncio
from stake.watchlist import Watchlist

async def remove_from_watchlist(id: str, tickers: "List[str]") -> "Watchlist":
    async with stake.StakeClient() as stake_session:
        request= stake.UpdateWatchlistRequest(id=id, tickers=tickers)
        watchlist = await stake_session.watchlist.remove_from_watchlist(request=request)
        return watchlist

asyncio.run(remove_from_watchlist(id=WATCHLIST_ID, tickers=["TSLA", "GOOG"] ))

```

```python
import stake
import asyncio
from stake.watchlist import Watchlist

async def delete_watchlist(id: str) -> "Watchlist":
    async with stake.StakeClient() as stake_session:
        request= stake.DeleteWatchlistRequest(id=id)
        watchlist = await stake_session.watchlist.delete_watchlist(request=request)
        return watchlist

asyncio.run(delete_watchlist(id=WATCHLIST_ID))

```

For more examples, you can have a look at the unittests.

## Contributors

### Contributors on GitHub

- [Contributors](https://github.com/stabacco/stake-python/graphs/contributors)

## License

- see [LICENSE](https://github.com/stabacco/stake-python/blob/master/LICENSE.md) file

## Contact

- Created by [Stefano Tabacco](https://github.com/stabacco)

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/stabacco/stake-python",
    "name": "stake",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8,<4.0.0",
    "maintainer_email": "",
    "keywords": "stake,trading,stocks,financial,python",
    "author": "Stefano Tabacco",
    "author_email": "tabacco.stefano@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/ee/b0/7f4c668b9fa3050eeaeaf71ee3a2abf4b2696896e6d6167e8a7496b3c37d/stake-0.8.2.tar.gz",
    "platform": null,
    "description": "[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)\n![Coverage](coverage.svg)[![Downloads](https://pepy.tech/badge/stake)](https://pepy.tech/project/stake)[![Downloads](https://pepy.tech/badge/stake/month)](https://pepy.tech/project/stake)\n\n# Stake\n\n**Stake** is an unofficial Python client for the [Stake](https://hellostake.com) trading platform.\n\nThis library wraps the current Stake api and allows common trade operations, such as submitting buy/sell requests, checking your portfolio etc...\n\nPlease note that, at the current stage, the Stake client is asynchronous.\n\n## Installation\n\n```$\npip install stake\n```\n\n## Quickstart\n\nAfter you install the package, you will need to authenticate to Stake in order to get authorization to interact with your account.\nIn order to successfully issue requests to the Stake platform you will need to authenticate to it. Every requests to the Stake endpoints will need to contain a `Stake-Session-Token` in the request headers.\n\n## Using an existing Session-Token\n\nYou can retrieve one of these `Stake-Session-Token` by using the developer tools in your browser (Network tab) and inspecting some of the request headers sent to some of the `https://global-prd-api.hellostake.com/` host. (For example, click on the wishlist of dashboard links to see some session-token authenticated requests)\n\nThey are usually valid for 30 days (be sure to enable that checkbox on login) and seem to get refreshed before expiry so you should be good to use them directly.\n\nIf you already have an existing token you can pass it on to the `StakeClient` as such:\n\n```python\n\nfrom stake import StakeClient, SessionTokenLoginRequest, CredentialsLoginRequest\nimport asyncio\n\nlogin_request = SessionTokenLoginRequest()\nasync def print_user():\n    async with StakeClient(login_request) as stake_session:\n        print(stake_session.user.first_name)\n        print(stake_session.headers.stake_session_token)\n\nasyncio.run(print_user())\n```\n\n> **_NOTE:_** The default value of the token is read from the `STAKE_TOKEN` environment variable. If you have that env-var set you should be able to just use:\n> `async with StakeClient() as stake_session: ...`\n\n## Login with your credentials\n\nIf you prefer to pass in your username/password credentials to login instead, it's easy to do:\n\n### If you do not have two-factor authentication enabled\n\n```python\n\nfrom stake import StakeClient, SessionTokenLoginRequest, CredentialsLoginRequest\nimport asyncio\n\nlogin_request = CredentialsLoginRequest(\n    username=\"youruser@name.com\", # os.getenv(\"STAKE_USER\") by default\n    password=\"yoursecretpassword\") # os.getenv(\"STAKE_PASS\") by default\n\nasync def print_user(request: CredentialsLoginRequest):\n    async with StakeClient(request) as stake_session:\n        print(stake_session.user.first_name)\n        print(stake_session.headers.stake_session_token)\n\nasyncio.run(print_user(login_request))\n```\n\n### If you have two-factor authentication enabled\n\nIn this case you need to have your phone around, get the current code from the authenticator app and add it to the `CredentialsLoginRequest` as such:\n\n```python\n    login_request = CredentialsLoginRequest(username=\"youruser@name.com\",password=\"yoursecretpassword\",\n        otp=\"Your-authenticator-app-code\")\n```\n\nObviously, this can become a bit inconvenient, since you will need to provide the otp code every time you instantiate a new `StakeClient` instance. Therefore, you could probably authenticate once with your credentials, retrieve the session token from the headers(`stake_session.headers.stake_session_token`), and store it in the `STAKE_TOKEN` env-var for subsequent usages.\n\n## Choose your trading exchange\n\nStake can currently trade on the NY stock exchange (default for this library) as well as the Australian ASX. In order to choose which trading market to use you can initialize the client by specifying the `exchange` argument:\n\n```python\nimport asyncio\nfrom typing import Union\n\nimport stake\n\n\nasync def show_current_orders(\n    current_exchange: Union[stake.constant.ASXUrl, stake.constant.NYSEUrl]\n):\n    async with stake.StakeClient(exchange=current_exchange) as stake_session:\n        my_equities = await stake_session.orders.list()\n        return my_equities\n\n# ASX\nprint(asyncio.run(show_current_orders(stake.ASX)))\n\n# NYSE\nprint(asyncio.run(show_current_orders(stake.NYSE)))\n\n```\n\nAlternatively you can call the `set_exchange` method on the `StakeClient` object.\n\nOne thing to note, is that the apis for the two exchanges are currently wildly different, and this reflects in some parts of this library as well.\nYou might find that the way you need to perform a trade (as well as the resulting response) is somewhat different when switching between exchanges.\n\nAs a rule of thumb the code for the ASX stake api resides in the `stake.asx` python package\nwhile the one for the USA one is under the main `stake` namespace (for backwards compatibitity mostly, it might get moved to `stake.nyse` in the future).\n\n## Examples\n\nWith `stake-python` you can do most of the operations that are available through the web app.\n\nHere are some examples:\n\n### Display the contents of your portfolio\n\n```python\nimport stake\nimport asyncio\nfrom stake.constant import NYSE\n\nasync def show_portfolio():\n    # here the client will use the STAKE_TOKEN env var for authenticating\n    async with stake.StakeClient(exchange=NYSE) as stake_session:\n        my_equities = await stake_session.equities.list()\n        for my_equity in my_equities.equity_positions:\n            print(my_equity.symbol, my_equity.yearly_return_value)\n        return my_equities\n\nasyncio.run(show_portfolio())\n```\n\nWhich will return something like:\n\n```bash\nAAPL 80.48\nADBE 251.35\nGOOG 559.89\nGRPN -13.77\nHTZ -10.52\nMSFT 97.14\nNFLX 263.55\nNIO 17.3\nNVDA 410.04\nOKTA 96.31\nSHOP 690.68\nSPOT 142.88\nSQ 101.75\nTQQQ 115.82\nTSLA 402.37\nVGT 130.08\nZM 331.1\n```\n\n### Buy/Sell shares\n\nYou can send buy/sell orders to the platform quite easily by just issuing trade requests.\nPlease check the `stake.trade` module for more details.\n\n```python\n\nimport asyncio\nimport stake\n\nasync def example_limit_buy():\n    symbol = \"TSLA\"\n    async with stake.StakeClient() as stake_session:\n        return await stake_session.trades.buy(\n            stake.LimitBuyRequest(symbol=symbol, limitPrice=10, quantity=1000)\n        )\n\nasyncio.run(example_limit_buy())\n```\n\nTo perform multiple requests at once you can use an `asyncio.gather` operation to run all the buy trades in parallel.\n\n```python\n\nimport asyncio\nimport stake\n\nasync def example_stop_sell(symbol='TSLA'):\n    \"\"\"THis example will add a stop sell request for one of your equities\"\"\"\n    async with stake.StakeClient() as stake_session:\n        my_equities = await stake_session.equities.list()\n        tsla_equity = [equity for equity in my_equities.equity_positions if equity.symbol == symbol][0]\n        stop_price = round(tsla_equity.market_price - 0.025 * tsla_equity.market_price)\n        stop_sell_request = stake.StopSellRequest(symbol=tsla_equity.symbol,\n                                                  stopPrice=stop_price,\n                                                  comment=\"My stop sell.\",\n                                                  quantity=tsla_equity.available_for_trading_qty)\n        return await stake_session.trades.sell(request=stop_sell_request)\n\nasyncio.run(example_stop_sell('MSFT'))\n```\n\n### Watchlists\n\nThese are some examples on how to interact with watchlists:\n\n```python\nimport stake\nimport asyncio\nfrom stake.watchlist import Watchlist\n\nasync def create_watchlist(name: str) -> \"Watchlist\":\n    async with stake.StakeClient() as stake_session:\n        request= stake.CreateWatchlistRequest(name = name)\n        new_watchlist = await stake_session.watchlist.create_watchlist(request=request)\n        return new_watchlist\n\nasyncio.run(create_watchlist(name='My watchlist'))\n```\n\n```python\nimport stake\nimport asyncio\nfrom stake.watchlist import Watchlist\n\nasync def update_watchlist(id: str, tickers: \"List[str]\") -> \"Watchlist\":\n    async with stake.StakeClient() as stake_session:\n        request= stake.UpdateWatchlistRequest(id=id, tickers=tickers)\n        watchlist = await stake_session.watchlist.add_to_watchlist(request=request)\n        return watchlist\n\nasyncio.run(update_watchlist(id=WATCHLIST_ID, tickers=[\"TSLA\", \"MSFT\", \"GOOG\"] ))\n```\n\n```python\nimport stake\nimport asyncio\nfrom stake.watchlist import Watchlist\n\nasync def remove_from_watchlist(id: str, tickers: \"List[str]\") -> \"Watchlist\":\n    async with stake.StakeClient() as stake_session:\n        request= stake.UpdateWatchlistRequest(id=id, tickers=tickers)\n        watchlist = await stake_session.watchlist.remove_from_watchlist(request=request)\n        return watchlist\n\nasyncio.run(remove_from_watchlist(id=WATCHLIST_ID, tickers=[\"TSLA\", \"GOOG\"] ))\n\n```\n\n```python\nimport stake\nimport asyncio\nfrom stake.watchlist import Watchlist\n\nasync def delete_watchlist(id: str) -> \"Watchlist\":\n    async with stake.StakeClient() as stake_session:\n        request= stake.DeleteWatchlistRequest(id=id)\n        watchlist = await stake_session.watchlist.delete_watchlist(request=request)\n        return watchlist\n\nasyncio.run(delete_watchlist(id=WATCHLIST_ID))\n\n```\n\nFor more examples, you can have a look at the unittests.\n\n## Contributors\n\n### Contributors on GitHub\n\n- [Contributors](https://github.com/stabacco/stake-python/graphs/contributors)\n\n## License\n\n- see [LICENSE](https://github.com/stabacco/stake-python/blob/master/LICENSE.md) file\n\n## Contact\n\n- Created by [Stefano Tabacco](https://github.com/stabacco)\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "Unofficial  https://hellostake.com API wrapper.",
    "version": "0.8.2",
    "project_urls": {
        "Homepage": "https://github.com/stabacco/stake-python",
        "Repository": "https://github.com/stabacco/stake-python"
    },
    "split_keywords": [
        "stake",
        "trading",
        "stocks",
        "financial",
        "python"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6da742171544101aeb46932631d216621d0ece9564a3f17a573c32b8beb2af15",
                "md5": "9f4f7d0a00d79cab2c9de4ddaf87798d",
                "sha256": "3dc2c00532cc0997191a5b2edaf79ac8a31869a9eb46d56c7675873b6bf01932"
            },
            "downloads": -1,
            "filename": "stake-0.8.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "9f4f7d0a00d79cab2c9de4ddaf87798d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8,<4.0.0",
            "size": 32364,
            "upload_time": "2024-03-08T11:52:29",
            "upload_time_iso_8601": "2024-03-08T11:52:29.525943Z",
            "url": "https://files.pythonhosted.org/packages/6d/a7/42171544101aeb46932631d216621d0ece9564a3f17a573c32b8beb2af15/stake-0.8.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "eeb07f4c668b9fa3050eeaeaf71ee3a2abf4b2696896e6d6167e8a7496b3c37d",
                "md5": "a79b99513ad2931a4b1b5ddcd8e52ced",
                "sha256": "04e5c4a43456084e09d893c89a5ce46231614945ffa5ef00905cbba94c233414"
            },
            "downloads": -1,
            "filename": "stake-0.8.2.tar.gz",
            "has_sig": false,
            "md5_digest": "a79b99513ad2931a4b1b5ddcd8e52ced",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8,<4.0.0",
            "size": 27160,
            "upload_time": "2024-03-08T11:52:30",
            "upload_time_iso_8601": "2024-03-08T11:52:30.770064Z",
            "url": "https://files.pythonhosted.org/packages/ee/b0/7f4c668b9fa3050eeaeaf71ee3a2abf4b2696896e6d6167e8a7496b3c37d/stake-0.8.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-08 11:52:30",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "stabacco",
    "github_project": "stake-python",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "stake"
}
        
Elapsed time: 1.13935s