Skip to content

Commit

Permalink
Repair IEX Market Data filtering, Stock endpoint tests (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
addisonlynch authored Apr 13, 2018
1 parent d6d7710 commit 69ec139
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 67 deletions.
30 changes: 15 additions & 15 deletions docs/source/whatsnew.rst
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
.. _whatsnew:

**********
What's New
**********

New features, bug fixes, and improvements for each release.

.. include:: whatsnew/v0.3.0.txt

Changelog
---------

See
`changelog <https://github.com/addisonlynch/iexfinance/blob/master/CHANGELOG.md>`__.
.. _whatsnew:

**********
What's New
**********

New features, bug fixes, and improvements for each release.

.. include:: whatsnew/v0.3.2.txt

Changelog
---------

See
`changelog <https://github.com/addisonlynch/iexfinance/blob/master/CHANGELOG.md>`__.
16 changes: 16 additions & 0 deletions docs/source/whatsnew/v0.3.2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.. _whatsnew_032:


v0.3.2 (TBA)
-------------------------

This is a minor release from 0.3.1, which repairs various bugs.


Bug Fixes
~~~~~~~~~

- IEX Market Data functions not filtering when symbol passed
`GH46 <https://github.com/addisonlynch/iexfinance/issues/46>`__
- Expected close test fails
`GH45 <https://github.com/addisonlynch/iexfinance/issues/45>`__
40 changes: 33 additions & 7 deletions iexfinance/market.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,21 @@ def __init__(self, symbols=None, output_format='json', **kwargs):
Additional request options
"""
if self.symbol_required:
if isinstance(symbols, str) and symbols:
self.symbols = [symbols]
elif isinstance(symbols, list) and len(symbols) in range(0, 10):
self.symbols = symbols
else:
syms = [symbols] if isinstance(symbols, str) else symbols
if isinstance(syms, list):
if len(syms) > self.symbol_limit:
raise ValueError("At most " + str(self.symbol_limit) +
"symbols may be entered at once.")
else:
if self.symbol_required:
raise ValueError("Please input a symbol or list of symbols.")
self.symbols = syms
self.output_format = output_format
super(Market, self).__init__(**kwargs)

@property
def params(self):
if self.symbol_required is True:
if self.symbols:
return {"symbols": ",".join(self.symbols)}
else:
return {}
Expand Down Expand Up @@ -94,6 +96,10 @@ def symbol_required(self):
"""
return False

@property
def symbol_limit(self):
raise NotImplementedError


class TOPS(Market):
""" Class to retrieve IEX TOPS data
Expand All @@ -110,6 +116,10 @@ class TOPS(Market):
def url(self):
return "tops"

@property
def symbol_limit(self):
return 10


class Last(Market):
""" Class to retrieve Last quote data
Expand All @@ -125,6 +135,10 @@ class Last(Market):
def url(self):
return "tops/last"

@property
def symbol_limit(self):
return 10


class DEEP(Market):
""" Class to retrieve DEEP order book data
Expand Down Expand Up @@ -153,6 +167,10 @@ def acc_pandas(self):
def symbol_required(self):
return True

@property
def symbol_limit(self):
return 1


class Book(Market):
""" Class to retrieve IEX DEEP Book data
Expand All @@ -167,10 +185,18 @@ class Book(Market):
-----
Will return empty outside of trading hours
"""
@property
def acc_pandas(self):
return False

@property
def url(self):
return "deep/book"

@property
def symbol_required(self):
return True

@property
def symbol_limit(self):
return 10
48 changes: 27 additions & 21 deletions tests/test_market.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,21 @@

class TestMarket(object):

@pytest.mark.xfail(reason="Market data only available during market open")
def setup_class(self):
self.bad = ["AAPL", "TSLA", "MSFT", "F", "GOOGL", "STM", "DAL",
"UVXY", "SPY", "DIA", "SVXY", "CMG", "LUV"]

def test_last_json_default(self):
ls = get_market_last()

assert isinstance(ls, list)
assert isinstance(ls, list) and len(ls) > 7500

@pytest.mark.xfail(reason="Market data only available during market open")
def test_last_json_syms(self):
ls = get_market_last("AAPL")
ls2 = get_market_last(["AAPL", "TSLA"])

assert isinstance(ls, list)
assert isinstance(ls2, list)
assert isinstance(ls, list) and len(ls) == 1
assert isinstance(ls2, list) and len(ls2) == 2

@pytest.mark.xfail(reason="Market data only available during market open")
def test_last_pandas(self):
Expand All @@ -31,21 +33,25 @@ def test_last_pandas(self):
assert isinstance(df2, DataFrame)
assert isinstance(df3, DataFrame)

@pytest.mark.xfail(reason="Market data only available during market open")
def test_last_too_many_symbols(self):
with pytest.raises(ValueError):
get_market_last(self.bad)

def test_TOPS_json_default(self):
ls = get_market_tops()

assert isinstance(ls, list)
assert isinstance(ls, list) and len(ls) > 7500

@pytest.mark.xfail(reason="Market data only available during market open")
def test_TOPS_json_syms(self):
ls = get_market_tops("AAPL")
ls2 = get_market_tops(["AAPL", "TSLA"])

assert isinstance(ls, list)
assert isinstance(ls2, list)
assert len(ls) == 1
assert len(ls2) == 2
assert isinstance(ls, list) and len(ls) == 1
assert isinstance(ls2, list) and len(ls2) == 2

def test_TOPS_too_many_symbols(self):
with pytest.raises(ValueError):
get_market_tops(self.bad)

@pytest.mark.xfail(reason="Market data only available during market open")
def test_TOPS_pandas(self):
Expand All @@ -55,38 +61,34 @@ def test_TOPS_pandas(self):
assert isinstance(df, DataFrame)
assert isinstance(df2, DataFrame)

@pytest.mark.xfail(reason="Market data only available during market open")
def test_DEEP_json_default(self):
with pytest.raises(ValueError):
get_market_deep()

@pytest.mark.xfail(reason="Market data only available during market open")
def test_DEEP_json_syms(self):
js = get_market_deep("AAPL")
js2 = get_market_deep(["AAPL", "TSLA"])

assert isinstance(js, dict)
assert isinstance(js2, dict)

@pytest.mark.xfail(reason="Market data only available during market open")
def test_DEEP_pandas(self):
with pytest.raises(ValueError):
get_market_deep("AAPL", output_format='pandas')

def test_DEEP_too_many_syms(self):
with pytest.raises(ValueError):
get_market_deep(["AAPL", "TSLA"], output_format='pandas')
get_market_deep(["AAPL", "TSLA"])

@pytest.mark.xfail(reason="Market data only available during market open")
def test_Book_json_default(self):
with pytest.raises(ValueError):
get_market_book()

@pytest.mark.xfail(reason="Market data only available during market open")
def test_Book_json_syms(self):
js = get_market_book("AAPL")
js2 = get_market_book(["AAPL", "TSLA"])

assert isinstance(js, dict)
assert isinstance(js2, dict)
assert isinstance(js, dict) and len(js) == 1
assert isinstance(js2, dict) and len(js2) == 2

@pytest.mark.xfail(reason="Market data only available during market open")
def test_Book_pandas(self):
Expand All @@ -95,3 +97,7 @@ def test_Book_pandas(self):

assert isinstance(df, DataFrame)
assert isinstance(df2, DataFrame)

def test_Book_too_many_symbols(self):
with pytest.raises(ValueError):
get_market_book(self.bad)
48 changes: 24 additions & 24 deletions tests/test_stock.py
Original file line number Diff line number Diff line change
Expand Up @@ -817,12 +817,12 @@ def test_single_historical_json(self):
assert len(f["AAPL"]) == 73

expected1 = f["AAPL"]["2017-02-09"]
assert expected1["close"] == 132.42
assert expected1["high"] == 132.445
assert expected1["close"] == pytest.approx(132.42, 3)
assert expected1["high"] == pytest.approx(132.445, 3)

expected2 = f["AAPL"]["2017-05-24"]
assert expected2["close"] == 153.34
assert expected2["high"] == 154.17
assert expected2["close"] == pytest.approx(153.34, 3)
assert expected2["high"] == pytest.approx(154.17, 3)

def test_single_historical_pandas(self):

Expand All @@ -833,12 +833,12 @@ def test_single_historical_pandas(self):
assert len(f) == 73

expected1 = f.loc["2017-02-09"]
assert expected1["close"] == 132.42
assert expected1["high"] == 132.445
assert expected1["close"] == pytest.approx(132.42, 3)
assert expected1["high"] == pytest.approx(132.445, 3)

expected2 = f.loc["2017-05-24"]
assert expected2["close"] == 153.34
assert expected2["high"] == 154.17
assert expected2["close"] == pytest.approx(153.34, 3)
assert expected2["high"] == pytest.approx(154.17, 3)

def test_batch_historical_json(self):

Expand All @@ -856,20 +856,20 @@ def test_batch_historical_json(self):
assert len(t) == 73

expected1 = a["2017-02-09"]
assert expected1["close"] == 132.42
assert expected1["high"] == 132.445
assert expected1["close"] == pytest.approx(132.42, 3)
assert expected1["high"] == pytest.approx(132.445, 3)

expected2 = a["2017-05-24"]
assert expected2["close"] == 153.34
assert expected2["high"] == 154.17
assert expected2["close"] == pytest.approx(153.34, 3)
assert expected2["high"] == pytest.approx(154.17, 3)

expected1 = t["2017-02-09"]
assert expected1["close"] == 269.20
assert expected1["high"] == 271.18
assert expected1["close"] == pytest.approx(269.20, 3)
assert expected1["high"] == pytest.approx(271.18, 3)

expected2 = t["2017-05-24"]
assert expected2["close"] == 310.22
assert expected2["high"] == 311.0
assert expected2["close"] == pytest.approx(310.22, 3)
assert expected2["high"] == pytest.approx(311.0, 3)

def test_batch_historical_pandas(self):

Expand All @@ -887,20 +887,20 @@ def test_batch_historical_pandas(self):
assert len(t) == 73

expected1 = a.loc["2017-02-09"]
assert expected1["close"] == 132.42
assert expected1["high"] == 132.445
assert expected1["close"] == pytest.approx(132.42, 3)
assert expected1["high"] == pytest.approx(132.445, 3)

expected2 = a.loc["2017-05-24"]
assert expected2["close"] == 153.34
assert expected2["high"] == 154.17
assert expected2["close"] == pytest.approx(153.34, 3)
assert expected2["high"] == pytest.approx(154.17, 3)

expected1 = t.loc["2017-02-09"]
assert expected1["close"] == 269.20
assert expected1["high"] == 271.18
assert expected1["close"] == pytest.approx(269.20, 3)
assert expected1["high"] == pytest.approx(271.18, 3)

expected2 = t.loc["2017-05-24"]
assert expected2["close"] == 310.22
assert expected2["high"] == 311.0
assert expected2["close"] == pytest.approx(310.22, 3)
assert expected2["high"] == pytest.approx(311.0, 3)

def test_invalid_dates(self):
start = datetime(2010, 5, 9)
Expand Down

0 comments on commit 69ec139

Please sign in to comment.