Skip to content

Commit

Permalink
Merge pull request #242 from bug-or-feature/0_0_16_fixes
Browse files Browse the repository at this point in the history
fixes for 0.0.16 version
  • Loading branch information
bug-or-feature authored Jan 1, 2022
2 parents b34e453 + 2c708a4 commit 400f7ba
Show file tree
Hide file tree
Showing 13 changed files with 91 additions and 95 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ jobs:
python-version: 3.8

- name: Install Poetry
uses: abatilo/actions-poetry@v2.0.0
uses: abatilo/actions-poetry@v2.1.4
with:
poetry-version: 1.1.6
poetry-version: 1.1.12

- name: Install dependencies
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ jobs:
with:
python-version: '3.x'
- name: Install Poetry
uses: abatilo/[email protected].2
uses: abatilo/[email protected].4
with:
poetry-version: 1.1.6
poetry-version: 1.1.12
- name: Build and publish
env:
PYPI_USERNAME: ${{ secrets.PYPI_USERNAME }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: [ 3.6, 3.7, 3.8, 3.9 ]
python-version: [ 3.7, 3.8, 3.9 ]

steps:

Expand All @@ -25,9 +25,9 @@ jobs:
python-version: ${{ matrix.python-version }}

- name: Install Poetry
uses: abatilo/actions-poetry@v2.0.0
uses: abatilo/actions-poetry@v2.1.4
with:
poetry-version: 1.1.6
poetry-version: 1.1.12

- name: Install dependencies
run: |
Expand Down
43 changes: 23 additions & 20 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@
trading_ig
==========

A lightweight Python wrapper for the IG Markets API. Simplifies access to the IG REST and Streaming APIs
with a live or demo account.
A lightweight Python wrapper for the IG Markets API. Simplifies access to the IG REST and Streaming APIs.

What is it?
-----------
Expand All @@ -53,40 +52,44 @@ https://labs.ig.com/

NOTE: this is not an IG project. Use it at your own risk

Installation
Dependencies
------------

From `Python package index <https://pypi.org/project/trading_ig/>`_::
A number of dependencies in this project are marked as 'optional', this is *by design*. There is a brief
explanation in `this FAQ item <https://trading_ig.readthedocs.io/en/latest/faq.html#why-are-some-dependencies-pandas-munch-marked-as-optional-in-pyproject-toml>`_.

$ pip install trading_ig
For full details, see `pyproject.toml <https://github.com/ig-python/ig-markets-api-python-library/blob/master/pyproject.toml>`_

with `Poetry <https://python-poetry.org/>`_::
Installation
------------

$ git clone https://github.com/ig-python/ig-markets-api-python-library
$ cd ig-markets-api-python-library
$ poetry install
This project uses `Poetry <https://python-poetry.org/>`_.

or with optional packages::
Adding to an existing Poetry project::

$ poetry install --extras "pandas munch"
$ poetry add trading_ig

From source::
With all the optional dependencies::

$ poetry add trading_ig[pandas,munch,tenacity]

Cloning the project with Poetry::

$ git clone https://github.com/ig-python/ig-markets-api-python-library
$ cd ig-markets-api-python-library
$ python setup.py install
$ poetry install

or direct from Github::
And with all optional dependencies::

$ pip install git+https://github.com/ig-python/ig-markets-api-python-library
$ poetry install --extras "pandas munch tenacity"

Dependencies
------------
Installing with pip::

$ pip install trading_ig

* `requests <https://pypi.org/project/requests/>`_
* `pycryptodome <https://pypi.org/project/pycryptodome/>`_
And with all optional dependencies::

For full details, see `pyproject.toml <https://github.com/ig-python/ig-markets-api-python-library/blob/master/pyproject.toml>`_
$ pip install trading_ig pandas munch tenacity

Docs
----
Expand Down
25 changes: 18 additions & 7 deletions docs/source/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -275,15 +275,26 @@ dependencies. `Poetry <https://python-poetry.org/>`_
support was added with version 0.0.10 (July 2021). The old style config was removed with version 0.0.14


Why is ``pandas`` an optional dependency in ``pyproject.toml``?
---------------------------------------------------------------
.. _why-is-pandas-an-optional-dependency-in-pyproject-toml:
.. _optional_dependencies:

Two reasons:
Why are some dependencies marked as optional in ``pyproject.toml``?
-------------------------------------------------------------------

Flexibility:

* The original intent of the project was that ``pandas`` and ``munch`` usage was optional. At a low level the
IG APIs return JSON data in the response body, and this library aims to be a flexible as possible in how
applications use it. If your project has pandas available, then this library will convert the response into a pandas
DataFrame where it makes sense to do so. Examples are historical price data, or account activity. If not, it just
returns a dict of the response data. It's the same for munch - fetching market info for a given epic will return
a munch object if that library is available in your environment, or a dict if not

* if this project is defined as a dependency in a higher level project (ie as a library), it should not
define which version of pandas is used. That should be defined in the parent project

* the original intent of the project was that ``pandas`` usage was optional, and that the code should work either
with or without
* flexibility - if this project is defined as a dependency in a project, ie as a library, it should not define
which version of ``pandas`` is used. That should be defined in the parent project
* ``tenacity`` support was added in version 0.0.10 as one possible way to handle the IG rate limits, but there are many
other ways to do so. To be as flexible as possible for users of this library, tenacity is also marked optional

How do I find the epic for market 'X'?
--------------------------------------
Expand Down
7 changes: 3 additions & 4 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
trading_ig
==========

A lightweight Python wrapper for the IG Markets API. Simplifies access to the IG REST and Streaming APIs
with a live or demo account.
A lightweight Python wrapper for the IG Markets API. Simplifies access to the IG REST and Streaming APIs.

What is it?
-----------
Expand All @@ -21,8 +20,8 @@ NOTE: this is not an IG project. Use it at your own risk
Dependencies
------------

* `requests <https://pypi.org/project/requests/>`_
* `pycryptodome <https://pypi.org/project/pycryptodome/>`_
A number of dependencies in this project are marked as 'optional', this is *by design*. There is a brief
explanation in :ref:`this FAQ item <optional-dependencies>`.

For full details, see `pyproject.toml <https://github.com/ig-python/ig-markets-api-python-library/blob/master/pyproject.toml>`_

Expand Down
24 changes: 14 additions & 10 deletions docs/source/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,33 @@ Quickstart
Installation
------------

From `Python package index <https://pypi.org/project/trading_ig/>`_::
This project uses `Poetry <https://python-poetry.org/>`_.

$ pip install trading_ig
Adding to an existing Poetry project::

$ poetry add trading_ig

With all the optional dependencies::

$ poetry add trading_ig[pandas,munch,tenacity]

with `Poetry <https://python-poetry.org/>`_::
Cloning the project with Poetry::

$ git clone https://github.com/ig-python/ig-markets-api-python-library
$ cd ig-markets-api-python-library
$ poetry install

or with optional packages::
And with all optional dependencies::

$ poetry install --extras "pandas munch tenacity"

From source::
Installing with pip::

$ git clone https://github.com/ig-python/ig-markets-api-python-library
$ cd ig-markets-api-python-library
$ python setup.py install
$ pip install trading_ig

or direct from Github::
And with all optional dependencies::

$ pip install git+https://github.com/ig-python/ig-markets-api-python-library
$ pip install trading_ig pandas munch tenacity


Configuration
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ classifiers = [
"Operating System :: OS Independent",
"Programming Language :: Cython",
"Programming Language :: Python",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Topic :: Scientific/Engineering",
"Topic :: Software Development :: Libraries",
"License :: OSI Approved :: BSD License",
]

[tool.poetry.dependencies]
python = ">=3.6.1,<4.0"
python = ">=3.7,<4.0"
requests = "^2.24"
pycryptodome = "^3.9"
requests-cache = "^0.5"
Expand Down
2 changes: 1 addition & 1 deletion tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def test_fetch_account_activity_v2_dates(self, ig_service):
assert isinstance(response, pd.DataFrame)

def test_fetch_account_activity_from(self, ig_service: IGService):
to_date = datetime(2021, 7, 31)
to_date = datetime.now() - timedelta(days=3)
from_date = to_date - timedelta(days=7)
response = ig_service.fetch_account_activity(from_date=from_date)
assert isinstance(response, pd.DataFrame)
Expand Down
21 changes: 0 additions & 21 deletions trading_ig/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,10 @@
from __future__ import absolute_import, division, print_function


from .version import (
__author__,
__copyright__,
__credits__,
__license__,
__version__,
__maintainer__,
__author_email__,
__status__,
__url__,
)

from .rest import IGService
from .stream import IGStreamService

__all__ = [
"IGService",
"IGStreamService",
"__author__",
"__copyright__",
"__credits__",
"__license__",
"__version__",
"__maintainer__",
"__author_email__",
"__status__",
"__url__",
]
29 changes: 17 additions & 12 deletions trading_ig/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,18 @@
from Crypto.PublicKey import RSA
from requests import Session
from urllib.parse import urlparse, parse_qs
import pandas as pd

import numpy as np
from pandas import json_normalize
from datetime import timedelta, datetime
from .utils import _HAS_PANDAS, _HAS_MUNCH
from .utils import conv_resol, conv_datetime, conv_to_ms, DATE_FORMATS, munchify
from tenacity import Retrying
from .utils import conv_resol, conv_datetime, conv_to_ms, DATE_FORMATS

if _HAS_MUNCH:
from .utils import munchify

if _HAS_PANDAS:
from .utils import pd, np
from pandas import json_normalize


logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -115,7 +119,8 @@ def delete(self, endpoint, params, session, version):
session.headers.update({'_method': 'DELETE'})
response = session.post(url, data=json.dumps(params))
logging.info(f"DELETE (POST) '{endpoint}', resp {response.status_code}")
del session.headers['_method']
if '_method' in session.headers:
del session.headers['_method']
return response

def req(self, action, endpoint, params, session, version):
Expand Down Expand Up @@ -152,7 +157,7 @@ def __init__(
session=None,
return_dataframe=_HAS_PANDAS,
return_munch=_HAS_MUNCH,
retryer: Retrying = None
retryer=None
):
"""Constructor, calls the method required to connect to
the API (accepts acc_type = LIVE or DEMO)"""
Expand Down Expand Up @@ -704,7 +709,7 @@ def fetch_deal_by_deal_reference(self, deal_reference, session=None):
action = "read"
for i in range(5):
response = self._req(action, endpoint, params, session, version)
if response.status_code == 404 or response.status_code == 405:
if response.status_code == 404:
logger.info("Deal reference %s not found, retrying." % deal_reference)
time.sleep(1)
else:
Expand Down Expand Up @@ -1327,10 +1332,10 @@ def mid_prices(self, prices, version):
df.index = pd.to_datetime(df.index, format="%Y-%m-%dT%H:%M:%S")
df.index.name = "DateTime"

df['Open'] = (df['openPrice.bid'] + df['openPrice.ask']) / 2
df['High'] = (df['highPrice.bid'] + df['highPrice.ask']) / 2
df['Low'] = (df['lowPrice.bid'] + df['lowPrice.ask']) / 2
df['Close'] = (df['closePrice.bid'] + df['closePrice.ask']) / 2
df['Open'] = df[['openPrice.bid', 'openPrice.ask']].mean(axis=1)
df['High'] = df[['highPrice.bid', 'highPrice.ask']].mean(axis=1)
df['Low'] = df[['lowPrice.bid', 'lowPrice.ask']].mean(axis=1)
df['Close'] = df[['closePrice.bid', 'closePrice.ask']].mean(axis=1)

df = df.drop(columns=['snapshotTime', 'openPrice.lastTraded', 'closePrice.lastTraded',
'highPrice.lastTraded', 'lowPrice.lastTraded',
Expand Down
8 changes: 6 additions & 2 deletions trading_ig/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,24 @@
import six

logger = logging.getLogger(__name__)
logger.setLevel(logging.WARNING)

OPT_URL = "https://trading_ig.readthedocs.io/en/latest/faq.html#optional-dependencies"

try:
import pandas as pd
import numpy as np # noqa
except ImportError:
_HAS_PANDAS = False
logger.info("Can't import pandas")
logger.warning(f"pandas is not present in the environment. See {OPT_URL}")
else:
_HAS_PANDAS = True

try:
from munch import munchify # noqa
except ImportError:
_HAS_MUNCH = False
logger.info("Can't import munch")
logger.warning(f"munch is not present in the environment. See {OPT_URL}")
else:
_HAS_MUNCH = True

Expand Down
9 changes: 0 additions & 9 deletions trading_ig/version.py

This file was deleted.

0 comments on commit 400f7ba

Please sign in to comment.