mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-23 12:50:22 +08:00
Merge pull request #464 from quantopian/expand_perf_packet
adding net leverage, long/short exposure, long/short position count
This commit is contained in:
@@ -49,3 +49,16 @@
|
||||
> # The standard deviation of the price in the last 3 days.
|
||||
> data[security].stdev(3)
|
||||
> ```
|
||||
|
||||
* New fields in Performance Period
|
||||
[PR464](https://github.com/quantopian/zipline/pull/464)
|
||||
|
||||
> Performance Period has new fields accessible in return value of to_dict:
|
||||
|
||||
> - gross leverage
|
||||
> - net leverage
|
||||
> - short exposure
|
||||
> - long exposure
|
||||
> - shorts count
|
||||
> - longs count
|
||||
|
||||
|
||||
@@ -53,6 +53,29 @@ oneday = timedelta(days=1)
|
||||
tradingday = timedelta(hours=6, minutes=30)
|
||||
|
||||
|
||||
def check_perf_period(pp,
|
||||
gross_leverage,
|
||||
net_leverage,
|
||||
long_exposure,
|
||||
longs_count,
|
||||
short_exposure,
|
||||
shorts_count):
|
||||
|
||||
perf_data = pp.to_dict()
|
||||
np.testing.assert_allclose(
|
||||
gross_leverage, perf_data['gross_leverage'], rtol=1e-3)
|
||||
np.testing.assert_allclose(
|
||||
net_leverage, perf_data['net_leverage'], rtol=1e-3)
|
||||
np.testing.assert_allclose(
|
||||
long_exposure, perf_data['long_exposure'], rtol=1e-3)
|
||||
np.testing.assert_allclose(
|
||||
longs_count, perf_data['longs_count'], rtol=1e-3)
|
||||
np.testing.assert_allclose(
|
||||
short_exposure, perf_data['short_exposure'], rtol=1e-3)
|
||||
np.testing.assert_allclose(
|
||||
shorts_count, perf_data['shorts_count'], rtol=1e-3)
|
||||
|
||||
|
||||
def check_account(account,
|
||||
settled_cash,
|
||||
equity_with_loan,
|
||||
@@ -865,6 +888,14 @@ class TestPositionPerformance(unittest.TestCase):
|
||||
|
||||
pp.calculate_performance()
|
||||
|
||||
check_perf_period(
|
||||
pp,
|
||||
gross_leverage=2.0,
|
||||
net_leverage=0.0,
|
||||
long_exposure=1000.0,
|
||||
longs_count=1,
|
||||
short_exposure=-1000.0,
|
||||
shorts_count=1)
|
||||
# Validate that the account attributes were updated.
|
||||
account = pp.as_account()
|
||||
check_account(account,
|
||||
@@ -889,6 +920,15 @@ class TestPositionPerformance(unittest.TestCase):
|
||||
# Validate that the account attributes were updated.
|
||||
account = pp.as_account()
|
||||
|
||||
check_perf_period(
|
||||
pp,
|
||||
gross_leverage=2.5,
|
||||
net_leverage=-0.25,
|
||||
long_exposure=900.0,
|
||||
longs_count=1,
|
||||
short_exposure=-1100.0,
|
||||
shorts_count=1)
|
||||
|
||||
check_account(account,
|
||||
settled_cash=1000.0,
|
||||
equity_with_loan=800.0,
|
||||
@@ -925,6 +965,15 @@ class TestPositionPerformance(unittest.TestCase):
|
||||
|
||||
pp.calculate_performance()
|
||||
|
||||
check_perf_period(
|
||||
pp,
|
||||
gross_leverage=10.0,
|
||||
net_leverage=10.0,
|
||||
long_exposure=10000.0,
|
||||
longs_count=1,
|
||||
short_exposure=0.0,
|
||||
shorts_count=0)
|
||||
|
||||
# Validate that the account attributes were updated.
|
||||
account = pp.as_account()
|
||||
check_account(account,
|
||||
@@ -944,6 +993,15 @@ class TestPositionPerformance(unittest.TestCase):
|
||||
|
||||
pp.calculate_performance()
|
||||
|
||||
check_perf_period(
|
||||
pp,
|
||||
gross_leverage=5.5,
|
||||
net_leverage=5.5,
|
||||
long_exposure=11000.0,
|
||||
longs_count=1,
|
||||
short_exposure=0.0,
|
||||
shorts_count=0)
|
||||
|
||||
# Validate that the account attributes were updated.
|
||||
account = pp.as_account()
|
||||
|
||||
@@ -1039,6 +1097,15 @@ class TestPositionPerformance(unittest.TestCase):
|
||||
|
||||
self.assertEqual(pp.pnl, 100, "gain of 1 on 100 shares should be 100")
|
||||
|
||||
check_perf_period(
|
||||
pp,
|
||||
gross_leverage=1.0,
|
||||
net_leverage=1.0,
|
||||
long_exposure=1100.0,
|
||||
longs_count=1,
|
||||
short_exposure=0.0,
|
||||
shorts_count=0)
|
||||
|
||||
# Validate that the account attributes were updated.
|
||||
account = pp.as_account()
|
||||
check_account(account,
|
||||
@@ -1242,6 +1309,15 @@ cost of sole txn in test"
|
||||
"drop of 1 on -100 shares should be 100"
|
||||
)
|
||||
|
||||
check_perf_period(
|
||||
pp,
|
||||
gross_leverage=0.8181,
|
||||
net_leverage=-0.8181,
|
||||
long_exposure=0.0,
|
||||
longs_count=0,
|
||||
short_exposure=-900.0,
|
||||
shorts_count=1)
|
||||
|
||||
# Validate that the account attributes.
|
||||
account = ppTotal.as_account()
|
||||
check_account(account,
|
||||
@@ -1337,6 +1413,15 @@ shares in position"
|
||||
"gain of 1 on 100 shares should be 300"
|
||||
)
|
||||
|
||||
check_perf_period(
|
||||
pp,
|
||||
gross_leverage=0.0,
|
||||
net_leverage=0.0,
|
||||
long_exposure=0.0,
|
||||
longs_count=0,
|
||||
short_exposure=0.0,
|
||||
shorts_count=0)
|
||||
|
||||
account = pp.as_account()
|
||||
check_account(account,
|
||||
settled_cash=1300.0,
|
||||
|
||||
@@ -320,25 +320,35 @@ class PerformancePeriod(object):
|
||||
def calculate_positions_value(self):
|
||||
return np.dot(self._position_amounts, self._position_last_sale_prices)
|
||||
|
||||
def _long_value(self):
|
||||
def _longs_count(self):
|
||||
longs = self._position_amounts[self._position_amounts > 0]
|
||||
return longs.count()
|
||||
|
||||
def _long_exposure(self):
|
||||
pos_values = self._position_amounts * self._position_last_sale_prices
|
||||
longs = pos_values[pos_values > 0]
|
||||
return longs.sum()
|
||||
|
||||
def _short_value(self):
|
||||
def _shorts_count(self):
|
||||
shorts = self._position_amounts[self._position_amounts < 0]
|
||||
return shorts.count()
|
||||
|
||||
def _short_exposure(self):
|
||||
pos_values = self._position_amounts * self._position_last_sale_prices
|
||||
shorts = pos_values[pos_values < 0]
|
||||
return shorts.sum()
|
||||
|
||||
def _gross_exposure(self):
|
||||
return self._long_value() + abs(self._short_value())
|
||||
return self._long_exposure() + abs(self._short_exposure())
|
||||
|
||||
def _net_exposure(self):
|
||||
return self.calculate_positions_value()
|
||||
|
||||
@property
|
||||
def _net_liquidation_value(self):
|
||||
return self.ending_cash + self._long_value() + self._short_value()
|
||||
return self.ending_cash + \
|
||||
self._long_exposure() + \
|
||||
self._short_exposure()
|
||||
|
||||
def _gross_leverage(self):
|
||||
net_liq = self._net_liquidation_value
|
||||
@@ -380,7 +390,12 @@ class PerformancePeriod(object):
|
||||
'returns': self.returns,
|
||||
'period_open': self.period_open,
|
||||
'period_close': self.period_close,
|
||||
'gross_leverage': self._gross_leverage()
|
||||
'gross_leverage': self._gross_leverage(),
|
||||
'net_leverage': self._net_leverage(),
|
||||
'short_exposure': self._short_exposure(),
|
||||
'long_exposure': self._long_exposure(),
|
||||
'longs_count': self._longs_count(),
|
||||
'shorts_count': self._shorts_count()
|
||||
}
|
||||
|
||||
return rval
|
||||
|
||||
Reference in New Issue
Block a user