-
Notifications
You must be signed in to change notification settings - Fork 855
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added more unit tests. Added more Python versions. Removed need to se…
…t ENVVAR for example scripts.
- Loading branch information
1 parent
6f9ed09
commit 47b9b32
Showing
19 changed files
with
238 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[report] | ||
exclude_lines = | ||
# Have to re-enable the standard pragma | ||
pragma: no cover | ||
|
||
# Don't complain if tests don't hit defensive assertion code: | ||
raise NotImplementedError |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# 0.1.1 | ||
|
||
* Removed the need to specify a CSV data directory as an environment variable by adding a default of the current working directory of the executed script | ||
* Addes CI support for Python 3.5, 3.6 and 3.8 in addition to 3.7 | ||
* Added some unit tests to improve test coverage slightly | ||
|
||
# 0.1.0 | ||
|
||
* Initial relase of QSTrader to PyPI |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
include README.md LICENSE | ||
include README.md LICENSE CHANGELOG.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
Click>=7.0 | ||
matplotlib>=3.1.1 | ||
matplotlib>=3.0.3 | ||
numpy>=1.17.1 | ||
pandas>=0.25.1 | ||
seaborn>=0.9.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from unittest.mock import Mock | ||
|
||
import pandas as pd | ||
import pytest | ||
import pytz | ||
|
||
from qstrader.alpha_model.fixed_signals import FixedSignalsAlphaModel | ||
|
||
|
||
@pytest.mark.parametrize( | ||
'signals', | ||
[ | ||
({'EQ:SPY': 0.75, 'EQ:AGG': 0.75, 'EQ:GLD': 0.75}), | ||
({'EQ:SPY': -0.25, 'EQ:AGG': -0.25, 'EQ:GLD': -0.25}) | ||
] | ||
) | ||
def test_fixed_signals_alpha_model(signals): | ||
""" | ||
Checks that the fixed signals alpha model correctly produces | ||
the same signals for each asset in the universe. | ||
""" | ||
universe = Mock() | ||
universe.get_assets.return_value = ['EQ:SPY', 'EQ:AGG', 'EQ:GLD'] | ||
|
||
alpha = FixedSignalsAlphaModel(universe=universe, signal_weights=signals) | ||
dt = pd.Timestamp('2019-01-01 15:00:00', tz=pytz.utc) | ||
|
||
assert alpha(dt) == signals |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from unittest.mock import Mock | ||
|
||
import pandas as pd | ||
import pytest | ||
import pytz | ||
|
||
from qstrader.alpha_model.single_signal import SingleSignalAlphaModel | ||
|
||
|
||
@pytest.mark.parametrize( | ||
'signal,expected_signals', | ||
[ | ||
(0.75, {'EQ:SPY': 0.75, 'EQ:AGG': 0.75, 'EQ:GLD': 0.75}), | ||
(-0.25, {'EQ:SPY': -0.25, 'EQ:AGG': -0.25, 'EQ:GLD': -0.25}) | ||
] | ||
) | ||
def test_single_signal_alpha_model(signal, expected_signals): | ||
""" | ||
Checks that the single signal alpha model correctly produces | ||
the same signal for each asset in the universe. | ||
""" | ||
universe = Mock() | ||
universe.get_assets.return_value = ['EQ:SPY', 'EQ:AGG', 'EQ:GLD'] | ||
|
||
alpha = SingleSignalAlphaModel(universe=universe, signal=signal) | ||
dt = pd.Timestamp('2019-01-01 15:00:00', tz=pytz.utc) | ||
|
||
assert alpha(dt) == expected_signals |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,8 @@ | |
[ | ||
( | ||
'empty on both sides', | ||
{}, [], []), | ||
{}, [], [] | ||
), | ||
( | ||
'partially intersecting set of assets', | ||
{ | ||
|
20 changes: 20 additions & 0 deletions
20
tests/unit/system/rebalance/test_buy_and_hold_rebalance.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import pandas as pd | ||
import pytest | ||
import pytz | ||
|
||
from qstrader.system.rebalance.buy_and_hold import BuyAndHoldRebalance | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"start_dt", [('2020-01-01'), ('2020-02-02')] | ||
) | ||
def test_buy_and_hold_rebalance(start_dt): | ||
""" | ||
Checks that the buy and hold rebalance sets the | ||
appropriate internal attributes. | ||
""" | ||
sd = pd.Timestamp(start_dt, tz=pytz.UTC) | ||
reb = BuyAndHoldRebalance(start_dt=sd) | ||
|
||
assert reb.start_dt == sd | ||
assert reb.rebalances == [sd] |
48 changes: 48 additions & 0 deletions
48
tests/unit/system/rebalance/test_end_of_month_rebalance.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import pandas as pd | ||
import pytest | ||
import pytz | ||
|
||
from qstrader.system.rebalance.end_of_month import EndOfMonthRebalance | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"start_date,end_date,pre_market,expected_dates,expected_time", | ||
[ | ||
( | ||
'2020-03-11', '2020-12-31', False, [ | ||
'2020-03-31', '2020-04-30', '2020-05-29', '2020-06-30', | ||
'2020-07-31', '2020-08-31', '2020-09-30', '2020-10-30', | ||
'2020-11-30', '2020-12-31' | ||
], '21:00:00' | ||
), | ||
( | ||
'2019-12-26', '2020-09-01', True, [ | ||
'2019-12-31', '2020-01-31', '2020-02-28', '2020-03-31', | ||
'2020-04-30', '2020-05-29', '2020-06-30', '2020-07-31', | ||
'2020-08-31' | ||
], '14:30:00' | ||
) | ||
] | ||
) | ||
def test_monthly_rebalance( | ||
start_date, end_date, pre_market, expected_dates, expected_time | ||
): | ||
""" | ||
Checks that the end of month (business day) rebalance provides | ||
the correct datetimes for the provided range. | ||
""" | ||
sd = pd.Timestamp(start_date, tz=pytz.UTC) | ||
ed = pd.Timestamp(end_date, tz=pytz.UTC) | ||
|
||
reb = EndOfMonthRebalance( | ||
start_dt=sd, end_dt=ed, pre_market=pre_market | ||
) | ||
|
||
actual_datetimes = reb._generate_rebalances() | ||
|
||
expected_datetimes = [ | ||
pd.Timestamp('%s %s' % (expected_date, expected_time), tz=pytz.UTC) | ||
for expected_date in expected_dates | ||
] | ||
|
||
assert actual_datetimes == expected_datetimes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import pandas as pd | ||
import pytest | ||
import pytz | ||
|
||
from qstrader.system.rebalance.weekly import WeeklyRebalance | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"start_date,end_date,weekday,pre_market,expected_dates,expected_time", | ||
[ | ||
( | ||
'2020-03-11', '2020-05-17', 'MON', False, [ | ||
'2020-03-16', '2020-03-23', '2020-03-30', '2020-04-06', | ||
'2020-04-13', '2020-04-20', '2020-04-27', '2020-05-04', | ||
'2020-05-11' | ||
], '21:00:00' | ||
), | ||
( | ||
'2019-12-26', '2020-02-07', 'WED', True, [ | ||
'2020-01-01', '2020-01-08', '2020-01-15', '2020-01-22', | ||
'2020-01-29', '2020-02-05' | ||
], '14:30:00' | ||
) | ||
] | ||
) | ||
def test_weekly_rebalance( | ||
start_date, end_date, weekday, pre_market, expected_dates, expected_time | ||
): | ||
""" | ||
Checks that the weekly rebalance provides the correct business | ||
datetimes for the provided range. | ||
""" | ||
sd = pd.Timestamp(start_date, tz=pytz.UTC) | ||
ed = pd.Timestamp(end_date, tz=pytz.UTC) | ||
|
||
reb = WeeklyRebalance( | ||
start_date=sd, end_date=ed, weekday=weekday, pre_market=pre_market | ||
) | ||
|
||
actual_datetimes = reb._generate_rebalances() | ||
|
||
expected_datetimes = [ | ||
pd.Timestamp('%s %s' % (expected_date, expected_time), tz=pytz.UTC) | ||
for expected_date in expected_dates | ||
] | ||
|
||
assert actual_datetimes == expected_datetimes | ||
|
||
|
||
def test_check_weekday_raises_value_error(): | ||
""" | ||
Checks that initialisation of WeeklyRebalance raises | ||
a ValueError if the weekday string is in the incorrect | ||
format. | ||
""" | ||
sd = pd.Timestamp('2020-01-01', tz=pytz.UTC) | ||
ed = pd.Timestamp('2020-02-01', tz=pytz.UTC) | ||
pre_market = True | ||
weekday = 'SUN' | ||
|
||
with pytest.raises(ValueError): | ||
WeeklyRebalance( | ||
start_date=sd, end_date=ed, weekday=weekday, pre_market=pre_market | ||
) |