def test_robust_vol_calc_min_period(self): prices = get_data("syscore.tests.pricetestdata_min_period.csv") returns = prices.diff() vol = robust_vol_calc(returns, min_periods=9) self.assertAlmostEqual(vol.iloc[-1], 0.45829858614978286) vol = robust_vol_calc(returns, min_periods=10) self.assertTrue(np.isnan(vol.iloc[-1]))
def test_robust_vol_calc(self): prices = get_data("syscore.tests.pricetestdata.csv") returns = prices.diff() vol = robust_vol_calc(returns, days=35) self.assertAlmostEqual(vol.iloc[-1], 0.41905275480464305) vol = robust_vol_calc(returns, days=100) self.assertAlmostEqual(vol.iloc[-1], 0.43906619578902956)
def test_robust_vol_calc_floor(self): prices = get_data("syscore.tests.pricetestdata_vol_floor.csv") returns = prices.diff() vol = robust_vol_calc(returns) self.assertAlmostEqual(vol.iloc[-1], 0.54492982003602064) vol = robust_vol_calc(returns, vol_floor=False) self.assertAlmostEqual(vol.iloc[-1], 0.42134038479240132) vol = robust_vol_calc(returns, floor_min_quant=.5) self.assertAlmostEqual(vol.iloc[-1], 1.6582199589924964) vol = robust_vol_calc(returns, floor_min_periods=500) self.assertAlmostEqual(vol.iloc[-1], 0.42134038479240132) vol = robust_vol_calc(returns, floor_days=10, floor_min_periods=5) self.assertAlmostEqual(vol.iloc[-1], 0.42134038479240132)
def get_price_volatility(self, instrument_code): """ Get the daily % volatility; If a rawdata stage exists from there; otherwise work it out :param instrument_code: instrument to get values for :type instrument_code: str :returns: Tx1 pd.DataFrame KEY INPUT Note as an exception to the normal rule we cache this, as it sometimes comes from data >>> from pysystemtrade.systems.tests.testdata import get_test_object_futures_with_comb_forecasts >>> from pysystemtrade.systems.basesystem import System >>> (comb, fcs, rules, rawdata, data, config)=get_test_object_futures_with_comb_forecasts() >>> system=System([rawdata, rules, fcs, comb, PositionSizing()], data, config) >>> >>> system.positionSize.get_price_volatility("EDOLLAR").tail(2) vol 2015-12-10 0.055281 2015-12-11 0.059789 >>> >>> system2=System([ rules, fcs, comb, PositionSizing()], data, config) >>> >>> system2.positionSize.get_price_volatility("EDOLLAR").tail(2) vol 2015-12-10 0.055318 2015-12-11 0.059724 """ system = self.parent if hasattr(system, "rawdata"): daily_perc_vol = system.rawdata.get_daily_percentage_volatility( instrument_code) else: price = system.data.daily_prices(instrument_code) return_vol = robust_vol_calc(price.diff()) daily_perc_vol = 100.0 * return_vol / price return daily_perc_vol
def get_daily_returns_volatility(self, instrument_code): """ Get the daily return (not %) volatility from previous stage, or calculate KEY INPUT :param instrument_code: :type str: :returns: Tx1 pd.DataFrames """ system = self.parent if hasattr(system, "rawdata"): returns_vol = system.rawdata.daily_returns_volatility( instrument_code) else: price = self.get_daily_price(instrument_code) returns_vol = robust_vol_calc(price.diff()) return returns_vol
def ewmac_forecast_with_defaults(price, Lfast=32, Lslow=128): """ Calculate the ewmac trading fule forecast, given a price and EWMA speeds Lfast, Lslow and vol_lookback Assumes that 'price' is daily data This version recalculates the price volatility, and does not do capping or scaling :param price: The price or other series to use (assumed Tx1) :type price: pd.Series :param Lfast: Lookback for fast in days :type Lfast: int :param Lslow: Lookback for slow in days :type Lslow: int :returns: pd.DataFrame -- unscaled, uncapped forecast """ # price: This is the stitched price series # We can't use the price of the contract we're trading, or the volatility # will be jumpy # And we'll miss out on the rolldown. See # http://qoppac.blogspot.co.uk/2015/05/systems-building-futures-rolling.html # We don't need to calculate the decay parameter, just use the span # directly fast_ewma = price.ewm(span=Lfast).mean() slow_ewma = price.ewm(span=Lslow).mean() raw_ewmac = fast_ewma - slow_ewma vol = robust_vol_calc(price.diff()) return raw_ewmac / vol
def test_robust_vol_calc_min_value(self): prices = get_data("syscore.tests.pricetestdata_zero_vol.csv") returns = prices.diff() vol = robust_vol_calc(returns, vol_abs_min=0.01) self.assertEqual(vol.iloc[-1], 0.01)