fast-tradier-client


Namefast-tradier-client JSON
Version 1.1.4 PyPI version JSON
download
home_pagehttps://pypi.org/project/fast-tradier-client/
SummaryA Tradier client for trading stocks and options through Tradier API
upload_time2024-12-25 20:40:31
maintainerNone
docs_urlNone
authorTony W
requires_python>=3.7
licenseNone
keywords python fast-tradier-client tradier
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # fast_tradier_client in Python
Tradier client in python for trading stocks and options through Tradier API

#### Dependencies:
- jsonpickle
- httpx
- arrow
- autoscraper
- pandas
- python-interface

#### Dependencies for unit tests:
- pytest
- pytest_httpx
- pytest-asyncio

#### Examples below:
1. Test Account:
```python

from fast_tradier.models.account.Position import Position
from fast_tradier.models.market_data.Quote import Quote

account_position = {
    "cost_basis": 207.01,
    "date_acquired": "2018-08-08T14:41:11.405Z",
    "id": 130089,
    "quantity": 1.00000000,
    "symbol": "AAPL"
}

position = Position(**account_position)
print(position.to_json())
print(position.symbol)
print(position.date_acquired)
print('-------' * 10)

quote1 = {
        "symbol": "VXX190517P00016000",
        "description": "VXX May 17 2019 $16.00 Put",
        "exch": "Z",
        "type": "option",
        "last": None,
        "change": None,
        "volume": 0,
        "open": None,
        "high": None,
        "low": None,
        "close": None,
        "bid": 0.0,
        "ask": 0.01,
        "underlying": "VXX",
        "strike": 16.0,
        "change_percentage": None,
        "average_volume": 0,
        "last_volume": 0,
        "trade_date": 0,
        "prevclose": None,
        "week_52_high": 0.0,
        "week_52_low": 0.0,
        "bidsize": 0,
        "bidexch": "I",
        "bid_date": 1557167321000,
        "asksize": 618,
        "askexch": "Z",
        "ask_date": 1557168367000,
        "open_interest": 10,
        "contract_size": 100,
        "expiration_date": "2019-05-17",
        "expiration_type": "standard",
        "option_type": "put",
        "root_symbol": "VXX"
      }

my_q = Quote(**quote1)
print(my_q.symbol)
print(my_q.ask_date_datetime)
```

2. Test Client:
```python

from fast_tradier.FastTradierAsyncClient import FastTradierAsyncClient
from fast_tradier.FastTradierClient import FastTradierClient
from fast_tradier.models.market_data.Quote import Quote
from fast_tradier.models.trading.OptionOrder import OptionLeg, OptionOrder
from fast_tradier.models.trading.EquityOrder import EquityOrder
from fast_tradier.models.trading.Sides import OptionOrderSide, EquityOrderSide
from fast_tradier.models.trading.PriceTypes import OptionPriceType, EquityPriceType
from fast_tradier.models.trading.Duration import Duration

import asyncio

#TODO: replace the client_id and sandbox access token with yours
sandbox_client_id = 'VA123456789'
sandbox_at = 'abcdefghijklmnopqrstuvwxyzzzz'

def mock_order() -> OptionOrder:
    ticker = 'SPX'
    order_status = 'pending'
    option_symbols = ['SPXW_080823C4510', 'SPXW_080823C4520'] #TODO: replace option symbols
    sides = [OptionOrderSide.SellToOpen, OptionOrderSide.BuyToOpen]
    option_legs = []

    for i in range(len(sides)):
        opt_symbol = option_symbols[i]
        side = sides[i]
        option_legs.append(OptionLeg(underlying_symbol=ticker, option_symbol=opt_symbol, side=side, quantity=1))

    option_order = OptionOrder(ticker=ticker,
                            price=1.2,
                            price_type=OptionPriceType.Credit,
                            duration=Duration.Day,
                            option_legs=option_legs)
    return option_order

def mock_equity_order() -> EquityOrder:
    symbol = 'SPY'
    price = 379.0
    quantity = 1.0
    return EquityOrder(ticker=symbol, quantity=quantity, price=price, side=EquityOrderSide.Buy, price_type=EquityPriceType.Limit, duration=Duration.Gtc)

async def async_test():
    tasks = []
    count = 4
    tradier_client = FastTradierAsyncClient(sandbox_at, sandbox_client_id, is_prod=False)
    
    quote1 = await tradier_client.get_quotes_async(['MSFT'])
    print('quote1 last price: ', quote1[0].last)

    for i in range(count):
        tasks.append(asyncio.ensure_future(tradier_client.place_option_order_async(mock_order())))

    order_ids = await asyncio.gather(*tasks)
    cancel_tasks = []
    for order_id in order_ids:
        print('order_id: ', order_id)
        cancel_tasks.append(asyncio.ensure_future(tradier_client.cancel_order_async(order_id)))
    
    is_canceled = await asyncio.gather(*cancel_tasks)
    for canceled in is_canceled:
        print('canceled? ', canceled)
    
    ### test equity order:
    equity_order = mock_equity_order()
    order_id = await tradier_client.place_equity_order_async(equity_order)
    print('equity order id: ', order_id)
    equity_order_canceled = await tradier_client.cancel_order_async(order_id)
    print('equity order canceld? ', equity_order_canceled)

    ### get option chain for spx
    ticker = 'spx'
    expiration = '2023-08-31' #TODO: replace the expiration date
    opt_chain_result = await tradier_client.get_option_chain_async(symbol=ticker, expiration=expiration)
    print('result of option chain: ', opt_chain_result)
    positions = await tradier_client.get_positions_async()
    print('positions: ', positions)

    print('------' * 10)
    balances = await tradier_client.get_account_balance_async()
    print('balances: ', balances.total_cash)
    if hasattr(balances, 'pdt') and balances.pdt is not None:
        print('balances.pdt.to_json(): ', balances.pdt.to_json())
    elif hasattr(balances, 'margin') and balances.margin is not None:
        print('balances.margin.to_json: ', balances.margin.to_json())
    elif hasattr(balances, 'cash') and balances.cash is not None:
        print('balances.cash.to_json: ', balances.cash.to_json())

def sync_test():
    count = 4
    tradier_client = FastTradierClient(sandbox_at, sandbox_client_id, is_prod=False)
    quote1 = tradier_client.get_quotes(['MSFT'])
    print('quote1 last price: ', quote1[0].last)

    order_id = tradier_client.place_option_order(mock_order())
    print('option order id: ', order_id)
    canceled_order = tradier_client.cancel_order(order_id)
    print('canceled order? ', canceled_order)

    ### test equity order:
    equity_order = mock_equity_order()
    order_id = tradier_client.place_equity_order(equity_order)
    print('equity order id: ', order_id)
    equity_order_canceled = tradier_client.cancel_order(order_id)
    print('equity order canceld? ', equity_order_canceled)

    ### get option chain for spx
    ticker = 'spx'
    expiration = '2023-08-31' #TODO: replace the expiration date
    opt_chain_result = tradier_client.get_option_chain(symbol=ticker, expiration=expiration)
    print('result of option chain: ', opt_chain_result)
    positions = tradier_client.get_positions()
    print('positions: ', positions)

    print('------' * 10)
    balances = tradier_client.get_account_balance()
    print('balances: ', balances.total_cash)
    if hasattr(balances, 'dt') and balances.pdt is not None:
        print('balances.pdt.to_json(): ', balances.pdt.to_json())
    elif hasattr(balances, 'margin') and balances.margin is not None:
        print('balances.margin.to_json: ', balances.margin.to_json())
    elif hasattr(balances, 'cash') and balances.cash is not None:
        print('balances.cash.to_json: ', balances.cash.to_json())

asyncio.run(async_test())
print('-------finished async tests--------')
sync_test()
print('-------finished sync tests-------')
```

3. Test model like `TradierQuote`:

```python
import json
from fast_tradier.models.market_data.TradierQuote import TradierQuote
from fast_tradier.models.trading.OptionOrder import OptionOrder, OptionLeg
from fast_tradier.models.trading.Sides import OptionOrderSide
from fast_tradier.models.trading.PriceTypes import OptionPriceType
from fast_tradier.models.trading.Duration import Duration

quote1 = TradierQuote(symbol='spx', type='stock', open=1000.0, high=2012.1, low=1999.0, close=4910.1, volume=30000, bid=1.2, ask=2.3, last_price=4.3)
json_obj = quote1.serialize()
print('serialize: ', json_obj)

quote2 = TradierQuote.deserialize_from_json(json_obj)
print('quote2.ask: ', quote2.ask)

print('--------' * 10)
ticker = 'SPX'
order_status = 'pending'
option_symbols = ['SPXW_052223C4225', 'SPXW_052223C4235']
sides = ['sell_to_open', 'buy_to_open']
option_legs = []

for i in range(len(sides)):
    opt_symbol = option_symbols[i]
    side = sides[i]
    option_legs.append(OptionLeg(underlying_symbol=ticker, option_symbol=opt_symbol, side=side, quantity=1))

option_order = OptionOrder(ticker=ticker,
                           price=100.0,
                           price_type=OptionPriceType.Market,
                           duration=Duration.Day,
                           option_legs=option_legs)

order_json = option_order.to_json()
print('option_order json: ', order_json)
parsable_json = option_order.serialize()
print('parsable order json: ', parsable_json)
option_order2 = OptionOrder.deserialize_from_json(parsable_json)
print('option_order2.price: ', option_order2.price)

```

4. Get history quotes

```
from fast_tradier.utils.TimeUtils import TimeUtils
from fast_tradier.models.trading.Interval import Interval
from fast_tradier.FastTradierAsyncClient import FastTradierAsyncClient

import pandas as pd

ticker = 'AAPL'
start_date = TimeUtils.past_date(days_ago = 100)
end_date = TimeUtils.today_date()

tradier_client = FastTradierAsyncClient(sandbox_at, sandbox_client_id, is_prod=False)

history_quotes = await tradier_client.get_history_async(symbol=ticker, start_date=start_date, end_date=end_date, interval=Interval.Daily)
print(history_quotes)
if history_quotes is not None:
    print(history_quotes.head())

```

5. Real time quote

As of 8/6/2023, Tradier does not provide real time quote for index like SPX, instead its quote has 15 minute delay. To help solve this problem, the constructor of `FastTradierAsyncClient` and `FastTradierClient` takes an optional object for getting real time quote.

To implement the interface `IRealTimeQuoteProvider`, reference to `YFinanceQuoteProvider` that uses web scraping to get real time quote from Yahoo Finance.

```python
from fast_tradier.utils.YFinanceQuoteProvider import YFinanceQuoteProvider
from fast_tradier.FastTradierAsyncClient import FastTradierAsyncClient

yfin_real_quote_provider = YFinanceQuoteProvider()
tradier_client = FastTradierAsyncClient(sandbox_at, sandbox_client_id, is_prod=False real_time_quote_provider=yfin_real_quote_provider)

```

            

Raw data

            {
    "_id": null,
    "home_page": "https://pypi.org/project/fast-tradier-client/",
    "name": "fast-tradier-client",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "python, fast-tradier-client, tradier",
    "author": "Tony W",
    "author_email": "Tony Wang <ivytony@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/2a/a3/3c1b71aea77eb9bf3dd88b2d8ff73a639538822abcf3001b3358e8c3a344/fast_tradier_client-1.1.4.tar.gz",
    "platform": null,
    "description": "# fast_tradier_client in Python\nTradier client in python for trading stocks and options through Tradier API\n\n#### Dependencies:\n- jsonpickle\n- httpx\n- arrow\n- autoscraper\n- pandas\n- python-interface\n\n#### Dependencies for unit tests:\n- pytest\n- pytest_httpx\n- pytest-asyncio\n\n#### Examples below:\n1. Test Account:\n```python\n\nfrom fast_tradier.models.account.Position import Position\nfrom fast_tradier.models.market_data.Quote import Quote\n\naccount_position = {\n    \"cost_basis\": 207.01,\n    \"date_acquired\": \"2018-08-08T14:41:11.405Z\",\n    \"id\": 130089,\n    \"quantity\": 1.00000000,\n    \"symbol\": \"AAPL\"\n}\n\nposition = Position(**account_position)\nprint(position.to_json())\nprint(position.symbol)\nprint(position.date_acquired)\nprint('-------' * 10)\n\nquote1 = {\n        \"symbol\": \"VXX190517P00016000\",\n        \"description\": \"VXX May 17 2019 $16.00 Put\",\n        \"exch\": \"Z\",\n        \"type\": \"option\",\n        \"last\": None,\n        \"change\": None,\n        \"volume\": 0,\n        \"open\": None,\n        \"high\": None,\n        \"low\": None,\n        \"close\": None,\n        \"bid\": 0.0,\n        \"ask\": 0.01,\n        \"underlying\": \"VXX\",\n        \"strike\": 16.0,\n        \"change_percentage\": None,\n        \"average_volume\": 0,\n        \"last_volume\": 0,\n        \"trade_date\": 0,\n        \"prevclose\": None,\n        \"week_52_high\": 0.0,\n        \"week_52_low\": 0.0,\n        \"bidsize\": 0,\n        \"bidexch\": \"I\",\n        \"bid_date\": 1557167321000,\n        \"asksize\": 618,\n        \"askexch\": \"Z\",\n        \"ask_date\": 1557168367000,\n        \"open_interest\": 10,\n        \"contract_size\": 100,\n        \"expiration_date\": \"2019-05-17\",\n        \"expiration_type\": \"standard\",\n        \"option_type\": \"put\",\n        \"root_symbol\": \"VXX\"\n      }\n\nmy_q = Quote(**quote1)\nprint(my_q.symbol)\nprint(my_q.ask_date_datetime)\n```\n\n2. Test Client:\n```python\n\nfrom fast_tradier.FastTradierAsyncClient import FastTradierAsyncClient\nfrom fast_tradier.FastTradierClient import FastTradierClient\nfrom fast_tradier.models.market_data.Quote import Quote\nfrom fast_tradier.models.trading.OptionOrder import OptionLeg, OptionOrder\nfrom fast_tradier.models.trading.EquityOrder import EquityOrder\nfrom fast_tradier.models.trading.Sides import OptionOrderSide, EquityOrderSide\nfrom fast_tradier.models.trading.PriceTypes import OptionPriceType, EquityPriceType\nfrom fast_tradier.models.trading.Duration import Duration\n\nimport asyncio\n\n#TODO: replace the client_id and sandbox access token with yours\nsandbox_client_id = 'VA123456789'\nsandbox_at = 'abcdefghijklmnopqrstuvwxyzzzz'\n\ndef mock_order() -> OptionOrder:\n    ticker = 'SPX'\n    order_status = 'pending'\n    option_symbols = ['SPXW_080823C4510', 'SPXW_080823C4520'] #TODO: replace option symbols\n    sides = [OptionOrderSide.SellToOpen, OptionOrderSide.BuyToOpen]\n    option_legs = []\n\n    for i in range(len(sides)):\n        opt_symbol = option_symbols[i]\n        side = sides[i]\n        option_legs.append(OptionLeg(underlying_symbol=ticker, option_symbol=opt_symbol, side=side, quantity=1))\n\n    option_order = OptionOrder(ticker=ticker,\n                            price=1.2,\n                            price_type=OptionPriceType.Credit,\n                            duration=Duration.Day,\n                            option_legs=option_legs)\n    return option_order\n\ndef mock_equity_order() -> EquityOrder:\n    symbol = 'SPY'\n    price = 379.0\n    quantity = 1.0\n    return EquityOrder(ticker=symbol, quantity=quantity, price=price, side=EquityOrderSide.Buy, price_type=EquityPriceType.Limit, duration=Duration.Gtc)\n\nasync def async_test():\n    tasks = []\n    count = 4\n    tradier_client = FastTradierAsyncClient(sandbox_at, sandbox_client_id, is_prod=False)\n    \n    quote1 = await tradier_client.get_quotes_async(['MSFT'])\n    print('quote1 last price: ', quote1[0].last)\n\n    for i in range(count):\n        tasks.append(asyncio.ensure_future(tradier_client.place_option_order_async(mock_order())))\n\n    order_ids = await asyncio.gather(*tasks)\n    cancel_tasks = []\n    for order_id in order_ids:\n        print('order_id: ', order_id)\n        cancel_tasks.append(asyncio.ensure_future(tradier_client.cancel_order_async(order_id)))\n    \n    is_canceled = await asyncio.gather(*cancel_tasks)\n    for canceled in is_canceled:\n        print('canceled? ', canceled)\n    \n    ### test equity order:\n    equity_order = mock_equity_order()\n    order_id = await tradier_client.place_equity_order_async(equity_order)\n    print('equity order id: ', order_id)\n    equity_order_canceled = await tradier_client.cancel_order_async(order_id)\n    print('equity order canceld? ', equity_order_canceled)\n\n    ### get option chain for spx\n    ticker = 'spx'\n    expiration = '2023-08-31' #TODO: replace the expiration date\n    opt_chain_result = await tradier_client.get_option_chain_async(symbol=ticker, expiration=expiration)\n    print('result of option chain: ', opt_chain_result)\n    positions = await tradier_client.get_positions_async()\n    print('positions: ', positions)\n\n    print('------' * 10)\n    balances = await tradier_client.get_account_balance_async()\n    print('balances: ', balances.total_cash)\n    if hasattr(balances, 'pdt') and balances.pdt is not None:\n        print('balances.pdt.to_json(): ', balances.pdt.to_json())\n    elif hasattr(balances, 'margin') and balances.margin is not None:\n        print('balances.margin.to_json: ', balances.margin.to_json())\n    elif hasattr(balances, 'cash') and balances.cash is not None:\n        print('balances.cash.to_json: ', balances.cash.to_json())\n\ndef sync_test():\n    count = 4\n    tradier_client = FastTradierClient(sandbox_at, sandbox_client_id, is_prod=False)\n    quote1 = tradier_client.get_quotes(['MSFT'])\n    print('quote1 last price: ', quote1[0].last)\n\n    order_id = tradier_client.place_option_order(mock_order())\n    print('option order id: ', order_id)\n    canceled_order = tradier_client.cancel_order(order_id)\n    print('canceled order? ', canceled_order)\n\n    ### test equity order:\n    equity_order = mock_equity_order()\n    order_id = tradier_client.place_equity_order(equity_order)\n    print('equity order id: ', order_id)\n    equity_order_canceled = tradier_client.cancel_order(order_id)\n    print('equity order canceld? ', equity_order_canceled)\n\n    ### get option chain for spx\n    ticker = 'spx'\n    expiration = '2023-08-31' #TODO: replace the expiration date\n    opt_chain_result = tradier_client.get_option_chain(symbol=ticker, expiration=expiration)\n    print('result of option chain: ', opt_chain_result)\n    positions = tradier_client.get_positions()\n    print('positions: ', positions)\n\n    print('------' * 10)\n    balances = tradier_client.get_account_balance()\n    print('balances: ', balances.total_cash)\n    if hasattr(balances, 'dt') and balances.pdt is not None:\n        print('balances.pdt.to_json(): ', balances.pdt.to_json())\n    elif hasattr(balances, 'margin') and balances.margin is not None:\n        print('balances.margin.to_json: ', balances.margin.to_json())\n    elif hasattr(balances, 'cash') and balances.cash is not None:\n        print('balances.cash.to_json: ', balances.cash.to_json())\n\nasyncio.run(async_test())\nprint('-------finished async tests--------')\nsync_test()\nprint('-------finished sync tests-------')\n```\n\n3. Test model like `TradierQuote`:\n\n```python\nimport json\nfrom fast_tradier.models.market_data.TradierQuote import TradierQuote\nfrom fast_tradier.models.trading.OptionOrder import OptionOrder, OptionLeg\nfrom fast_tradier.models.trading.Sides import OptionOrderSide\nfrom fast_tradier.models.trading.PriceTypes import OptionPriceType\nfrom fast_tradier.models.trading.Duration import Duration\n\nquote1 = TradierQuote(symbol='spx', type='stock', open=1000.0, high=2012.1, low=1999.0, close=4910.1, volume=30000, bid=1.2, ask=2.3, last_price=4.3)\njson_obj = quote1.serialize()\nprint('serialize: ', json_obj)\n\nquote2 = TradierQuote.deserialize_from_json(json_obj)\nprint('quote2.ask: ', quote2.ask)\n\nprint('--------' * 10)\nticker = 'SPX'\norder_status = 'pending'\noption_symbols = ['SPXW_052223C4225', 'SPXW_052223C4235']\nsides = ['sell_to_open', 'buy_to_open']\noption_legs = []\n\nfor i in range(len(sides)):\n    opt_symbol = option_symbols[i]\n    side = sides[i]\n    option_legs.append(OptionLeg(underlying_symbol=ticker, option_symbol=opt_symbol, side=side, quantity=1))\n\noption_order = OptionOrder(ticker=ticker,\n                           price=100.0,\n                           price_type=OptionPriceType.Market,\n                           duration=Duration.Day,\n                           option_legs=option_legs)\n\norder_json = option_order.to_json()\nprint('option_order json: ', order_json)\nparsable_json = option_order.serialize()\nprint('parsable order json: ', parsable_json)\noption_order2 = OptionOrder.deserialize_from_json(parsable_json)\nprint('option_order2.price: ', option_order2.price)\n\n```\n\n4. Get history quotes\n\n```\nfrom fast_tradier.utils.TimeUtils import TimeUtils\nfrom fast_tradier.models.trading.Interval import Interval\nfrom fast_tradier.FastTradierAsyncClient import FastTradierAsyncClient\n\nimport pandas as pd\n\nticker = 'AAPL'\nstart_date = TimeUtils.past_date(days_ago = 100)\nend_date = TimeUtils.today_date()\n\ntradier_client = FastTradierAsyncClient(sandbox_at, sandbox_client_id, is_prod=False)\n\nhistory_quotes = await tradier_client.get_history_async(symbol=ticker, start_date=start_date, end_date=end_date, interval=Interval.Daily)\nprint(history_quotes)\nif history_quotes is not None:\n    print(history_quotes.head())\n\n```\n\n5. Real time quote\n\nAs of 8/6/2023, Tradier does not provide real time quote for index like SPX, instead its quote has 15 minute delay. To help solve this problem, the constructor of `FastTradierAsyncClient` and `FastTradierClient` takes an optional object for getting real time quote.\n\nTo implement the interface `IRealTimeQuoteProvider`, reference to `YFinanceQuoteProvider` that uses web scraping to get real time quote from Yahoo Finance.\n\n```python\nfrom fast_tradier.utils.YFinanceQuoteProvider import YFinanceQuoteProvider\nfrom fast_tradier.FastTradierAsyncClient import FastTradierAsyncClient\n\nyfin_real_quote_provider = YFinanceQuoteProvider()\ntradier_client = FastTradierAsyncClient(sandbox_at, sandbox_client_id, is_prod=False real_time_quote_provider=yfin_real_quote_provider)\n\n```\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A Tradier client for trading stocks and options through Tradier API",
    "version": "1.1.4",
    "project_urls": {
        "Bug Tracker": "https://bitbucket.org/rcholic/fast-tradier-client/jira?statuses=new&statuses=indeterminate&sort=-updated&page=1",
        "Homepage": "https://bitbucket.org/rcholic/fast-tradier-client"
    },
    "split_keywords": [
        "python",
        " fast-tradier-client",
        " tradier"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2aa33c1b71aea77eb9bf3dd88b2d8ff73a639538822abcf3001b3358e8c3a344",
                "md5": "cab5960972c5fee6ef532a17d942d764",
                "sha256": "46feaeadf8f01b226268bbf2342f6a6226c02454703c9b00632d1258d015e4f0"
            },
            "downloads": -1,
            "filename": "fast_tradier_client-1.1.4.tar.gz",
            "has_sig": false,
            "md5_digest": "cab5960972c5fee6ef532a17d942d764",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 19076,
            "upload_time": "2024-12-25T20:40:31",
            "upload_time_iso_8601": "2024-12-25T20:40:31.258782Z",
            "url": "https://files.pythonhosted.org/packages/2a/a3/3c1b71aea77eb9bf3dd88b2d8ff73a639538822abcf3001b3358e8c3a344/fast_tradier_client-1.1.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-12-25 20:40:31",
    "github": false,
    "gitlab": false,
    "bitbucket": true,
    "codeberg": false,
    "bitbucket_user": "rcholic",
    "bitbucket_project": "fast-tradier-client",
    "lcname": "fast-tradier-client"
}
        
Elapsed time: 0.40993s