TST: Update to empyrical, increase test coverage

ENH: Resolve rebase conflict by using updated example_data.tar

TST: Increase test coverage for risk portion of zipline
This commit is contained in:
Ana Ruelas committed 2016-08-23 13:49:43 -04:00
1 parent 902865cf71
commit f0af856c13
69 files changed
+222 -172

No files matched your search

@@ -1,4 +1,4 @@
"%PYTHON%" setup.py install
"%PYTHON%" setup.py install
if errorlevel 1 exit 1
:: Add more build steps here, if they are necessary.
@@ -1,6 +1,6 @@
#!/bin/bash
$PYTHON setup.py install
$PYTHON setup.py install
# Add more build steps here, if they are necessary.
+33
View File
@@ -0,0 +1,33 @@
package:
name: empyrical
version: "0.1.9"
source:
fn: empyrical-0.1.9.tar.gz
url: https://pypi.python.org/packages/15/6b/de1d277d4342d2cecc8134f4935248853f32299cdd9b01728b0ec420c350/empyrical-0.1.9.tar.gz
md5: 2c8b928cae192fc9cb8b7104608eec56
requirements:
build:
- python
- setuptools
- numpy x.x
- pandas >=0.16.1
- scipy >=0.15.1
- bottleneck >=1.0.0
run:
- python
- numpy x.x
- pandas >=0.16.1
- scipy >=0.15.1
- bottleneck >=1.0.0
about:
home: https://github.com/quantopian/empyrical
license: Apache Software License
summary: 'empyrical is a Python library with performance and risk statistics\ncommonly used in quantitative finance'
# See
# http://docs.continuum.io/conda/build.html for
# more information about meta.yaml
-27
View File
@@ -1,27 +0,0 @@
package:
name: qrisk
version: "0.1.4"
source:
fn: qrisk-0.1.4.tar.gz
url: https://files.pythonhosted.org/packages/49/c9/81924d56e8173c4e92d60f5e59143dd345a0bf015508f85683ed9c2efd27/qrisk-0.1.4.tar.gz
md5: 24a76bcb960e82ade86bf115e87c5f53
requirements:
build:
- python
- setuptools
- numpy x.x
- pandas >=0.16.1
- scipy >=0.15.1
run:
- python
- numpy x.x
- pandas >=0.16.1
- scipy >=0.15.1
about:
home: https://github.com/quantopian/qrisk
license: Apache Software License
summary: 'qrisk is a Python library with performance and risk statistics\ncommonly used in quantitative finance'
+1 -1
View File
@@ -64,4 +64,4 @@ intervaltree==2.1.0
cachetools==1.1.5
# For financial risk calculations
qrisk==0.1.4
empyrical>=0.1.9
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
{"last_row": {"0": 2768, "5": 16338, "6": 19107, "4": 13569, "2": 8306, "8": 24645, "1": 5537, "3": 10800, "7": 21876}, "calendar": [631238400000000000, 631324800000000000, 631411200000000000, 631497600000000000, 631756800000000000, 631843200000000000, 631929600000000000, 632016000000000000, 632102400000000000, 632361600000000000, 632448000000000000, 632534400000000000, 632620800000000000, 632707200000000000, 632966400000000000, 633052800000000000, 633139200000000000, 633225600000000000, 633312000000000000, 633571200000000000, 633657600000000000, 633744000000000000, 633830400000000000, 633916800000000000, 634176000000000000, 634262400000000000, 634348800000000000, 634435200000000000, 634521600000000000, 634780800000000000, 634867200000000000, 634953600000000000, 635040000000000000, 635126400000000000, 635472000000000000, 635558400000000000, 635644800000000000, 635731200000000000, 635990400000000000, 636076800000000000, 636163200000000000, 636249600000000000, 636336000000000000, 636595200000000000, 636681600000000000, 636768000000000000, 636854400000000000, 636940800000000000, 637200000000000000, 637286400000000000, 637372800000000000, 637459200000000000, 637545600000000000, 637804800000000000, 637891200000000000, 637977600000000000, 638064000000000000, 638150400000000000, 638409600000000000, 638496000000000000, 638582400000000000, 638668800000000000, 638755200000000000, 639014400000000000, 639100800000000000, 639187200000000000, 639273600000000000, 639360000000000000, 639619200000000000, 639705600000000000, 639792000000000000, 639878400000000000, 640224000000000000, 640310400000000000, 640396800000000000, 640483200000000000, 640569600000000000, 640828800000000000, 640915200000000000, 641001600000000000, 641088000000000000, 641174400000000000, 641433600000000000, 641520000000000000, 641606400000000000, 641692800000000000, 641779200000000000, 642038400000000000, 642124800000000000, 642211200000000000, 642297600000000000, 642384000000000000, 642643200000000000, 642729600000000000, 642816000000000000, 642902400000000000, 642988800000000000, 643248000000000000, 643334400000000000, 643420800000000000, 643507200000000000, 643593600000000000, 643939200000000000, 644025600000000000, 644112000000000000, 644198400000000000, 644457600000000000, 644544000000000000, 644630400000000000, 644716800000000000, 644803200000000000, 645062400000000000, 645148800000000000, 645235200000000000, 645321600000000000, 645408000000000000, 645667200000000000, 645753600000000000, 645840000000000000, 645926400000000000, 646012800000000000, 646272000000000000, 646358400000000000, 646444800000000000, 646531200000000000, 646617600000000000, 646876800000000000, 646963200000000000, 647136000000000000, 647222400000000000, 647481600000000000, 647568000000000000, 647654400000000000, 647740800000000000, 647827200000000000, 648086400000000000, 648172800000000000, 648259200000000000, 648345600000000000, 648432000000000000, 648691200000000000, 648777600000000000, 648864000000000000, 648950400000000000, 649036800000000000, 649296000000000000, 649382400000000000, 649468800000000000, 649555200000000000, 649641600000000000, 649900800000000000, 649987200000000000, 650073600000000000, 650160000000000000, 650246400000000000, 650505600000000000, 650592000000000000, 650678400000000000, 650764800000000000, 650851200000000000, 651110400000000000, 651196800000000000, 651283200000000000, 651369600000000000, 651456000000000000, 651715200000000000, 651801600000000000, 651888000000000000, 651974400000000000, 652060800000000000, 652406400000000000, 652492800000000000, 652579200000000000, 652665600000000000, 652924800000000000, 653011200000000000, 653097600000000000, 653184000000000000, 653270400000000000, 653529600000000000, 653616000000000000, 653702400000000000, 653788800000000000, 653875200000000000, 654134400000000000, 654220800000000000, 654307200000000000, 654393600000000000, 654480000000000000, 654739200000000000, 654825600000000000, 654912000000000000, 654998400000000000, 655084800000000000, 655344000000000000, 655430400000000000, 655516800000000000, 655603200000000000, 655689600000000000, 655948800000000000, 656035200000000000, 656121600000000000, 656208000000000000, 656294400000000000, 656553600000000000, 656640000000000000, 656726400000000000, 656812800000000000, 656899200000000000, 657158400000000000, 657244800000000000, 657331200000000000, 657417600000000000, 657504000000000000, 657763200000000000, 657849600000000000, 657936000000000000, 658022400000000000, 658108800000000000, 658368000000000000, 658454400000000000, 658540800000000000, 658627200000000000, 658713600000000000, 658972800000000000, 659059200000000000, 659145600000000000, 659318400000000000, 659577600000000000, 659664000000000000, 659750400000000000, 659836800000000000, 659923200000000000, 660182400000000000, 660268800000000000, 660355200000000000, 660441600000000000, 660528000000000000, 660787200000000000, 660873600000000000, 660960000000000000, 661046400000000000, 661132800000000000, 661392Line truncated
@@ -0,0 +1 @@
{"names": ["open", "high", "low", "close", "volume", "day", "id"]}
@@ -0,0 +1 @@
{"nbytes": 98584, "shape": [24646], "cbytes": 131072}
@@ -0,0 +1 @@
{"chunklen": 32768, "dtype": "uint32", "expectedlen": 24646, "dflt": 0, "cparams": {"shuffle": true, "clevel": 5}}
@@ -0,0 +1 @@
{"nbytes": 98584, "shape": [24646], "cbytes": 131072}
@@ -0,0 +1 @@
{"chunklen": 32768, "dtype": "uint32", "expectedlen": 24646, "dflt": 0, "cparams": {"shuffle": true, "clevel": 5}}
@@ -0,0 +1 @@
{"nbytes": 98584, "shape": [24646], "cbytes": 131072}
@@ -0,0 +1 @@
{"chunklen": 32768, "dtype": "uint32", "expectedlen": 24646, "dflt": 0, "cparams": {"shuffle": true, "clevel": 5}}
@@ -0,0 +1 @@
{"nbytes": 98584, "shape": [24646], "cbytes": 131072}
@@ -0,0 +1 @@
{"chunklen": 32768, "dtype": "uint32", "expectedlen": 24646, "dflt": 0, "cparams": {"shuffle": true, "clevel": 5}}
@@ -0,0 +1 @@
{"nbytes": 98584, "shape": [24646], "cbytes": 131072}
@@ -0,0 +1 @@
{"chunklen": 32768, "dtype": "uint32", "expectedlen": 24646, "dflt": 0, "cparams": {"shuffle": true, "clevel": 5}}
@@ -0,0 +1 @@
{"nbytes": 98584, "shape": [24646], "cbytes": 131072}
@@ -0,0 +1 @@
{"chunklen": 32768, "dtype": "uint32", "expectedlen": 24646, "dflt": 0, "cparams": {"shuffle": true, "clevel": 5}}
@@ -0,0 +1 @@
{"nbytes": 98584, "shape": [24646], "cbytes": 131072}
@@ -0,0 +1 @@
{"chunklen": 32768, "dtype": "uint32", "expectedlen": 24646, "dflt": 0, "cparams": {"shuffle": true, "clevel": 5}}
@@ -0,0 +1 @@
{"market_closes": [10521900, 10523340, 10524780, 10526220, 10530540, 10531980, 10533420, 10534860, 10536300, 10540620, 10542060, 10543500, 10544940, 10546380, 10550700, 10552140, 10553580, 10555020, 10556460, 10560780, 10562220, 10563660, 10565100, 10566540, 10570860, 10572300, 10573740, 10575180, 10576620, 10580940, 10582380, 10583820, 10585260, 10586700, 10592460, 10593900, 10595340, 10596780, 10601100, 10602540, 10603980, 10605420, 10606860, 10611180, 10612620, 10614060, 10615500, 10616940, 10621260, 10622700, 10624140, 10625580, 10627020, 10631340, 10632780, 10634220, 10635660, 10637100, 10641420, 10642860, 10644300, 10645740, 10647180, 10651440, 10652880, 10654320, 10655760, 10657200, 10661520, 10662960, 10664400, 10665840, 10671600, 10673040, 10674480, 10675920, 10677360, 10681680, 10683120, 10684560, 10686000, 10687440, 10691760, 10693200, 10694640, 10696080, 10697520, 10701840, 10703280, 10704720, 10706160, 10707600, 10711920, 10713360, 10714800, 10716240, 10717680, 10722000, 10723440, 10724880, 10726320, 10727760, 10733520, 10734960, 10736400, 10737840, 10742160, 10743600, 10745040, 10746480, 10747920, 10752240, 10753680, 10755120, 10756560, 10758000, 10762320, 10763760, 10765200, 10766640, 10768080, 10772400, 10773840, 10775280, 10776720, 10778160, 10782480, 10783920, 10786800, 10788240, 10792560, 10794000, 10795440, 10796880, 10798320, 10802640, 10804080, 10805520, 10806960, 10808400, 10812720, 10814160, 10815600, 10817040, 10818480, 10822800, 10824240, 10825680, 10827120, 10828560, 10832880, 10834320, 10835760, 10837200, 10838640, 10842960, 10844400, 10845840, 10847280, 10848720, 10853040, 10854480, 10855920, 10857360, 10858800, 10863120, 10864560, 10866000, 10867440, 10868880, 10874640, 10876080, 10877520, 10878960, 10883280, 10884720, 10886160, 10887600, 10889040, 10893360, 10894800, 10896240, 10897680, 10899120, 10903440, 10904880, 10906320, 10907760, 10909200, 10913520, 10914960, 10916400, 10917840, 10919280, 10923600, 10925040, 10926480, 10927920, 10929360, 10933680, 10935120, 10936560, 10938000, 10939440, 10943760, 10945200, 10946640, 10948080, 10949520, 10953900, 10955340, 10956780, 10958220, 10959660, 10963980, 10965420, 10966860, 10968300, 10969740, 10974060, 10975500, 10976940, 10978380, 10979820, 10984140, 10985580, 10987020, 10989900, 10994220, 10995660, 10997100, 10998540, 10999980, 11004300, 11005740, 11007180, 11008620, 11010060, 11014380, 11015820, 11017260, 11018700, 11020140, 11024460, 11025900, 11027340, 11028780, 11030220, 11034540, 11037420, 11038860, 11040300, 11044620, 11047500, 11048940, 11050380, 11054700, 11056140, 11057580, 11059020, 11060460, 11064780, 11066220, 11067660, 11069100, 11070540, 11074860, 11076300, 11077740, 11079180, 11080620, 11084940, 11086380, 11087820, 11089260, 11090700, 11095020, 11096460, 11097900, 11099340, 11100780, 11105100, 11106540, 11107980, 11109420, 11110860, 11116620, 11118060, 11119500, 11120940, 11125260, 11126700, 11128140, 11129580, 11131020, 11135340, 11136780, 11138220, 11139660, 11141100, 11145420, 11146860, 11148300, 11149740, 11151180, 11155500, 11156940, 11158380, 11159820, 11161260, 11165580, 11167020, 11168460, 11169900, 11175660, 11177100, 11178540, 11179980, 11181420, 11185680, 11187120, 11188560, 11190000, 11191440, 11195760, 11197200, 11198640, 11200080, 11201520, 11205840, 11207280, 11208720, 11210160, 11211600, 11215920, 11217360, 11218800, 11220240, 11221680, 11226000, 11227440, 11228880, 11230320, 11231760, 11236080, 11237520, 11238960, 11240400, 11241840, 11246160, 11247600, 11249040, 11250480, 11251920, 11257680, 11259120, 11260560, 11262000, 11266320, 11267760, 11269200, 11270640, 11272080, 11276400, 11277840, 11279280, 11280720, 11282160, 11286480, 11287920, 11289360, 11290800, 11292240, 11296560, 11298000, 11299440, 11300880, 11302320, 11306640, 11308080, 11309520, 11312400, 11316720, 11318160, 11319600, 11321040, 11322480, 11326800, 11328240, 11329680, 11331120, 11332560, 11336880, 11338320, 11339760, 11341200, 11342640, 11346960, 11348400, 11349840, 11351280, 11352720, 11357040, 11358480, 11359920, 11361360, 11362800, 11367120, 11368560, 11370000, 11371440, 11372880, 11377200, 11378640, 11380080, 11381520, 11382960, 11387280, 11388720, 11390160, 11391600, 11393040, 11398800, 11400240, 11401680, 11403120, 11407440, 11408880, 11410320, 11411760, 11413200, 11417520, 11418960, 11420400, 11421840, 11423280, 11427600, 11429040, 11430480, 11431920, 11433360, 11437680, 11439120, 11440560, 11442000, 11443440, 11447760, 11449200, 11450640, 11452080, 11453520, 11457840, 11459280, 11460720, 11462160, 11463600, 11467920, 11469360, 11470800, 11472240, 11473680, 11478060, 11479500, 11480940, 11482380, 11483820, 11488140, 11489580, 11491020, 11492460, 11493900, 11498220, 11499660, 11501100, 11502540, 11503980, 11508300, 11509740, 11511180, 11512620, 11514060, 11518380, 11519820, 11521260, 11524140, 11528460, 11529900, 11531340, 11532780, 11534220, 11538540, 11539980, 11541420, 11542860, 11544300, 11548620, 11550060, 11551500, Line truncated
Whitespace-only changes.
+4 -10
View File
@@ -17,15 +17,11 @@ import numpy as np
import pandas as pd
import zipline.finance.risk as risk
from zipline.utils import factory
import pandas as pd
from zipline.testing.fixtures import WithTradingEnvironment, ZiplineTestCase
from zipline.finance.trading import SimulationParameters
from . import answer_key
ANSWER_KEY = answer_key.ANSWER_KEY
RETURNS_BASE = 0.01
RETURNS = [RETURNS_BASE] * 251
@@ -38,16 +34,10 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
def init_instance_fixtures(self):
super(TestRisk, self).init_instance_fixtures()
<<<<<<< 30f5a8fcfa4a194f05d58f50cf0a2b06dd8085cc
start_session = pd.Timestamp("2006-01-01", tz='UTC')
end_session = pd.Timestamp("2006-12-29", tz='UTC')
=======
start_date = pd.Timestamp('2006-01-01', tz=pytz.utc)
end_date = pd.Timestamp('2006-12-29', tz=pytz.utc)
>>>>>>> ENH: Change datetime.datetime to pd.Timestamp in tests
self.sim_params = SimulationParameters(
start_session=start_session,
end_session=end_session,
@@ -150,3 +140,7 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
all(isinstance(x, float)
for x in self.cumulative_metrics.max_drawdowns),
True)
def test_representation(self):
assert all([metric in self.cumulative_metrics.__repr__() for metric in
self.cumulative_metrics.METRIC_NAMES])
+147 -72
View File
@@ -17,8 +17,6 @@ import datetime
import calendar
import pandas as pd
import numpy as np
import pytz
import pandas as pd
import zipline.finance.risk as risk
from zipline.utils import factory
@@ -26,6 +24,8 @@ from zipline.utils import factory
from zipline.finance.trading import SimulationParameters
from zipline.testing.fixtures import WithTradingEnvironment, ZiplineTestCase
from zipline.finance.risk.period import RiskMetricsPeriod
RETURNS_BASE = 0.01
RETURNS = [RETURNS_BASE] * 251
@@ -38,17 +38,14 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
def init_instance_fixtures(self):
super(TestRisk, self).init_instance_fixtures()
start_session = pd.Timestamp("2006-01-01", tz='UTC')
end_session = self.trading_calendar.minute_to_session_label(
self.start_session = pd.Timestamp("2006-01-01", tz='UTC')
self.end_session = self.trading_calendar.minute_to_session_label(
pd.Timestamp("2006-12-31", tz='UTC'),
direction="previous"
)
self.sim_params = SimulationParameters(
start_session=start_session,
end_session=end_session,
start_session=self.start_session,
end_session=self.end_session,
trading_calendar=self.trading_calendar,
)
self.algo_returns = factory.create_returns_from_list(
@@ -63,16 +60,15 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
self.algo_returns,
self.sim_params,
benchmark_returns=self.benchmark_returns,
trading_schedule=self.trading_schedule,
trading_calendar=self.trading_calendar,
treasury_curves=self.env.treasury_curves,
)
def test_factory(self):
returns = [0.1] * 100
r_objects = factory.create_returns_from_list(returns, self.sim_params)
self.assertTrue(r_objects.index[-1] <= self.end_date)
self.assertTrue(r_objects.index[0] >= self.start_date)
self.assertTrue(r_objects.sample().values[0] == 0.1)
self.assertTrue(r_objects.index[-1] <=
pd.Timestamp('2006-12-31', tz='UTC'))
def test_drawdown(self):
np.testing.assert_equal(
@@ -123,7 +119,7 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
[20, 19, 23, 19, 22, 22, 20, 23, 20, 22, 21, 20])
def test_benchmark_volatility(self):
# Volatility is calculated by a qrisk function so testing
# Volatility is calculated by a empyrical function so testing
# of period volatility will be limited to determine if the value is
# numerical. This tests for its existence and format.
np.testing.assert_equal(
@@ -170,7 +166,7 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
DECIMAL_PLACES)
def test_algorithm_volatility(self):
# Volatility is calculated by a qrisk function so testing
# Volatility is calculated by a empyrical function so testing
# of period volatility will be limited to determine if the value is
# numerical. This tests for its existence and format.
np.testing.assert_equal(
@@ -191,7 +187,7 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
True)
def test_algorithm_sharpe(self):
# The sharpe ratio is calculated by a qrisk function so testing
# The sharpe ratio is calculated by a empyrical function so testing
# of period sharpe ratios will be limited to determine if the value is
# numerical. This tests for its existence and format.
np.testing.assert_equal(
@@ -212,7 +208,7 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
True)
def test_algorithm_downside_risk(self):
# Downside risk is calculated by a qrisk function so testing
# Downside risk is calculated by a empyrical function so testing
# of period downside risk will be limited to determine if the value is
# numerical. This tests for its existence and format.
np.testing.assert_equal(
@@ -233,7 +229,7 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
True)
def test_algorithm_sortino(self):
# The sortino ratio is calculated by a qrisk function so testing
# The sortino ratio is calculated by a empyrical function so testing
# of period sortino ratios will be limited to determine if the value is
# numerical. This tests for its existence and format.
np.testing.assert_equal(
@@ -254,9 +250,9 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
True)
def test_algorithm_information(self):
# The information ratio is calculated by a qrisk function so testing
# of period information ratio will be limited to determine if the value
# is numerical. This tests for its existence and format.
# The information ratio is calculated by a empyrical function
# testing of period information ratio will be limited to determine
# if the value is numerical. This tests for its existence and format.
np.testing.assert_equal(
all(isinstance(x.information, float)
for x in self.metrics.month_periods),
@@ -275,7 +271,7 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
True)
def test_algorithm_beta(self):
# Beta is calculated by a qrisk function so testing
# Beta is calculated by a empyrical function so testing
# of period beta will be limited to determine if the value is
# numerical. This tests for its existence and format.
np.testing.assert_equal(
@@ -296,7 +292,7 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
True)
def test_algorithm_alpha(self):
# Alpha is calculated by a qrisk function so testing
# Alpha is calculated by a empyrical function so testing
# of period alpha will be limited to determine if the value is
# numerical. This tests for its existence and format.
np.testing.assert_equal(
@@ -316,49 +312,6 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
for x in self.metrics.year_periods),
True)
def test_algorithm_covariance(self):
np.testing.assert_almost_equal(
[x.algorithm_covariance for x in self.metrics.month_periods],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
DECIMAL_PLACES)
np.testing.assert_almost_equal(
[x.algorithm_covariance
for x in self.metrics.three_month_periods],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
DECIMAL_PLACES)
np.testing.assert_almost_equal(
[x.algorithm_covariance
for x in self.metrics.six_month_periods],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
DECIMAL_PLACES)
np.testing.assert_almost_equal(
[x.algorithm_covariance
for x in self.metrics.year_periods],
[0.0],
DECIMAL_PLACES)
def test_benchmark_variance(self):
np.testing.assert_almost_equal(
[x.benchmark_variance
for x in self.metrics.month_periods],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
DECIMAL_PLACES)
np.testing.assert_almost_equal(
[x.benchmark_variance
for x in self.metrics.three_month_periods],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
DECIMAL_PLACES)
np.testing.assert_almost_equal(
[x.benchmark_variance
for x in self.metrics.six_month_periods],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
DECIMAL_PLACES)
np.testing.assert_almost_equal(
[x.benchmark_variance
for x in self.metrics.year_periods],
[0.0],
DECIMAL_PLACES)
def test_treasury_returns(self):
returns = factory.create_returns_from_range(self.sim_params)
metrics = risk.RiskReport(returns, self.sim_params,
@@ -407,13 +360,33 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
[0.0500])
def test_benchmarkrange(self):
self.check_year_range(
pd.Timestamp('2008-01-01', tz=pytz.utc),
2)
start_session = self.trading_calendar.minute_to_session_label(
pd.Timestamp("2008-01-01", tz='UTC')
)
end_session = self.trading_calendar.minute_to_session_label(
pd.Timestamp("2010-01-01", tz='UTC'), direction="previous"
)
sim_params = SimulationParameters(
start_session=start_session,
end_session=end_session,
trading_calendar=self.trading_calendar,
)
returns = factory.create_returns_from_range(sim_params)
metrics = risk.RiskReport(returns, self.sim_params,
trading_calendar=self.trading_calendar,
treasury_curves=self.env.treasury_curves,
benchmark_returns=self.env.benchmark_returns)
self.check_metrics(metrics, 24, start_session)
def test_partial_month(self):
start = pd.Timestamp('1991-01-01', tz=pytz.utc)
start_session = self.trading_calendar.minute_to_session_label(
pd.Timestamp("1991-01-01", tz='UTC')
)
# 1992 and 1996 were leap years
total_days = 365 * 5 + 2
@@ -504,6 +477,108 @@ class TestRisk(WithTradingEnvironment, ZiplineTestCase):
end=col[-1]._end_session,
actual=len(col))
)
self.assert_month(start_date.month, col[-1]._end_session.month)
self.assert_last_day(col[-1]._end_session)
self.assert_month(start_date.month, col[-1].end_date.month)
self.assert_last_day(col[-1].end_date)
def test_algorithm_leverages(self):
# Max leverage for an algorithm with 'None' as leverage is 0.
np.testing.assert_equal(
[x.max_leverage for x in self.metrics.month_periods],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
np.testing.assert_equal(
[x.max_leverage for x in self.metrics.three_month_periods],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
np.testing.assert_equal(
[x.max_leverage for x in self.metrics.six_month_periods],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
np.testing.assert_equal(
[x.max_leverage for x in self.metrics.year_periods],
[0.0])
def test_returns_beyond_treasury(self):
# The last treasury value is used when return dates go beyond
# treasury curve data
treasury_curves = self.env.treasury_curves
treasury = treasury_curves[treasury_curves.index < self.start_session]
test_period = RiskMetricsPeriod(
start_session=self.start_session,
end_session=self.end_session,
returns=self.algo_returns,
benchmark_returns=self.benchmark_returns,
trading_calendar=self.trading_calendar,
treasury_curves=treasury,
algorithm_leverages=[.01, .02, .03]
)
assert test_period.treasury_curves.equals(treasury[-1:])
# This return period has a list instead of None for algorithm_leverages
# Confirm that max_leverage is set to the max of those values
assert test_period.max_leverage == .03
def test_index_mismatch_exception(self):
# An exception is raised when returns and benchmark returns
# have indexes that do not match
bench_params = SimulationParameters(
start_session=pd.Timestamp("2006-02-01", tz='UTC'),
end_session=pd.Timestamp("2006-02-28", tz='UTC'),
trading_calendar=self.trading_calendar,
)
benchmark = factory.create_returns_from_list(
[BENCHMARK_BASE]*19,
bench_params
)
with np.testing.assert_raises(Exception):
RiskMetricsPeriod(
start_session=self.start_session,
end_session=self.end_session,
returns=self.algo_returns,
benchmark_returns=benchmark,
trading_calendar=self.trading_calendar,
treasury_curves=self.env.treasury_curves,
)
def test_sharpe_value_when_null(self):
# Sharpe is displayed as '0.0' instead of np.nan
null_returns = factory.create_returns_from_list(
[0.0]*251,
self.sim_params
)
test_period = RiskMetricsPeriod(
start_session=self.start_session,
end_session=self.end_session,
returns=null_returns,
benchmark_returns=self.benchmark_returns,
trading_calendar=self.trading_calendar,
treasury_curves=self.env.treasury_curves,
)
assert test_period.sharpe == 0.0
def test_representation(self):
test_period = RiskMetricsPeriod(
start_session=self.start_session,
end_session=self.end_session,
returns=self.algo_returns,
benchmark_returns=self.benchmark_returns,
trading_calendar=self.trading_calendar,
treasury_curves=self.env.treasury_curves,
)
metrics = [
"algorithm_period_returns",
"benchmark_period_returns",
"excess_return",
"num_trading_days",
"benchmark_volatility",
"algorithm_volatility",
"sharpe",
"sortino",
"information",
"beta",
"alpha",
"max_drawdown",
"max_leverage",
"algorithm_returns",
"benchmark_returns",
]
representation = test_period.__repr__()
assert all([metric in representation for metric in metrics])
+4 -4
View File
@@ -873,10 +873,10 @@ def before_trading_start(context, data):
res2 = algo2.run(self.data_portal)
# FIXME I think we are getting Nans due to fixed benchmark,
# so dropping them for now.
res1 = res1.fillna(method='ffill')
res2 = res2.fillna(method='ffill')
# There are some np.NaN values in the first row because there is not
# enough data to calculate the metric, e.g. beta.
res1 = res1.fillna(value=0)
res2 = res2.fillna(value=0)
np.testing.assert_array_equal(res1, res2)
+2 -2
View File
@@ -1191,9 +1191,9 @@ class DataPortal(object):
if data_frequency == "minute":
freq_str = "1m"
calculated_bar_count = self._get_minute_count_for_transform(
calculated_bar_count = int(self._get_minute_count_for_transform(
dt, bars
)
))
else:
freq_str = "1d"
calculated_bar_count = bars
+1 -1
View File
@@ -27,7 +27,7 @@ from . risk import (
choose_treasury
)
from qrisk import (
from empyrical import (
alpha,
annual_volatility,
beta,
+4 -53
View File
@@ -16,8 +16,6 @@
import functools
import logbook
import numpy as np
import numpy.linalg as la
from six import iteritems
@@ -26,10 +24,11 @@ import pandas as pd
from . import risk
from . risk import check_entry
from qrisk import (
from empyrical import (
alpha,
annual_volatility,
beta,
cum_returns,
downside_risk,
information_ratio,
max_drawdown,
@@ -46,7 +45,6 @@ choose_treasury = functools.partial(risk.choose_treasury,
class RiskMetricsPeriod(object):
def __init__(self, start_session, end_session, returns, trading_calendar,
treasury_curves, benchmark_returns, algorithm_leverages=None):
if treasury_curves.index[-1] >= start_session:
mask = ((treasury_curves.index >= start_session) &
(treasury_curves.index <= end_session))
@@ -79,10 +77,10 @@ class RiskMetricsPeriod(object):
def calculate_metrics(self):
self.benchmark_period_returns = \
self.calculate_period_returns(self.benchmark_returns)
cum_returns(self.benchmark_returns).iloc[-1]
self.algorithm_period_returns = \
self.calculate_period_returns(self.algorithm_returns)
cum_returns(self.algorithm_returns).iloc[-1]
if not self.algorithm_returns.index.equals(
self.benchmark_returns.index
@@ -115,7 +113,6 @@ class RiskMetricsPeriod(object):
)
self.sharpe = sharpe_ratio(
self.algorithm_returns,
self.benchmark_returns
)
# The consumer currently expects a 0.0 value for sharpe in period,
# this differs from cumulative which was np.nan.
@@ -138,9 +135,6 @@ class RiskMetricsPeriod(object):
self.algorithm_returns,
self.benchmark_returns
)
self.algorithm_covariance, self.benchmark_variance, \
self.condition_number, self.eigen_values \
= self.calculate_covariance()
self.beta = beta(
self.algorithm_returns,
self.benchmark_returns
@@ -193,16 +187,12 @@ class RiskMetricsPeriod(object):
"sharpe",
"sortino",
"information",
"algorithm_covariance",
"benchmark_variance",
"beta",
"alpha",
"max_drawdown",
"max_leverage",
"algorithm_returns",
"benchmark_returns",
"condition_number",
"eigen_values"
]
for metric in metrics:
@@ -226,45 +216,6 @@ class RiskMetricsPeriod(object):
returns = returns[mask]
return returns
def calculate_period_returns(self, returns):
period_returns = (1. + returns).prod() - 1
return period_returns
def calculate_covariance(self):
"""
.. math::
\\beta_a = \\frac{\mathrm{Cov}(r_a,r_p)}{\mathrm{Var}(r_p)}
http://en.wikipedia.org/wiki/Beta_(finance)
"""
# it doesn't make much sense to calculate beta for less than two days,
# so return nan.
if len(self.algorithm_returns) < 2:
return np.nan, np.nan, np.nan, []
returns_matrix = np.vstack([self.algorithm_returns,
self.benchmark_returns])
C = np.cov(returns_matrix, ddof=1)
# If there are missing benchmark values, then we can't calculate the
# beta.
if not np.isfinite(C).all():
return np.nan, np.nan, np.nan, []
eigen_values = la.eigvals(C)
condition_number = max(eigen_values) / min(eigen_values)
algorithm_covariance = C[0][1]
benchmark_variance = C[1][1]
return (
algorithm_covariance,
benchmark_variance,
condition_number,
eigen_values
)
def calculate_max_leverage(self):
if self.algorithm_leverages is None:
return 0.0