class TargetVolExecutor(ExecutorBase): def __init__(self, window=30, target_vol=0.01): super().__init__() self.m_vol = MovingStandardDeviation(window, 'return') self.m_leverage = MovingAverage(window, 'leverage') self.target_vol = target_vol self.multiplier = 1. def execute(self, target_pos: pd.DataFrame) -> Tuple[float, pd.DataFrame]: if not self.m_vol.isFull(): if self.current_pos.empty: turn_over = target_pos.weight.abs().sum() else: turn_over = self.calc_turn_over(target_pos, self.current_pos) return turn_over, target_pos else: c_vol = self.m_vol.result() c_leverage = self.m_leverage.result() self.multiplier = self.target_vol / c_vol * c_leverage candidate_pos = target_pos.copy() candidate_pos[ 'weight'] = candidate_pos.weight.values * self.multiplier turn_over = self.calc_turn_over(candidate_pos, self.current_pos) return turn_over, candidate_pos def set_current(self, current_pos: pd.DataFrame): super().set_current(current_pos) self.m_leverage.push({'leverage': current_pos.weight.abs().sum()}) def update(self, data_dict: dict): self.m_vol.push(data_dict)
def testMovingAverager(self): window = 120 total = 2500 mv = MovingAverage(window, dependency='z') runningSum = 0.0 con = [] for i in range(total): value = float(i) con.append(value) mv.push(dict(z=value)) runningSum += value if i >= window: runningSum -= con[0] con = con[1:] if i >= window - 1: expected = runningSum / window calculated = mv.result() self.assertAlmostEqual(calculated, expected, 15, "at index {0:d}\n" "Average expected: {1:f}\n" "Average calculated: {2:f}".format(i, expected, calculated))
def testMovingAverager(self): window = 120 total = 2500 mv = MovingAverage(window, dependency='z') runningSum = 0.0 con = [] for i in range(total): value = float(i) con.append(value) mv.push(dict(z=value)) runningSum += value if i >= window: runningSum -= con[0] con = con[1:] if i >= window - 1: expected = runningSum / window calculated = mv.result() self.assertAlmostEqual( calculated, expected, 15, "at index {0:d}\n" "Average expected: {1:f}\n" "Average calculated: {2:f}".format(i, expected, calculated))
def testShiftValueHolder(self): ma = MovingAverage(10, 'close') with self.assertRaises(ValueError): _ = Shift(ma, N=0) test = Shift(ma, N=1) test.push(dict(close=2.0)) ma.push(dict(close=2.0)) previous = ma.result() test.push(dict(close=5.0)) ma.push(dict(close=5.0)) self.assertAlmostEqual(previous, test.result()) previous = ma.result() test.push(dict(close=10.0)) self.assertAlmostEqual(previous, test.result())
n = 3000 m = 3000 index = pd.date_range(dt.datetime(1990, 1, 1), dt.datetime(1990, 1, 1) + dt.timedelta(days=m - 1)) index = np.repeat(index, n) df = pd.DataFrame(np.random.randn(n * m, 3), columns=['x', 'y', 'z'], index=index) df['c'] = matlib.repmat(np.linspace(0, n - 1, n, dtype=int), 1, m)[0] start = dt.datetime.now() t = MA(20, 'x') / MA(30, 'y') res = t.transform(df, category_field='c') print("Finance-Python (analysis): {0}s".format(dt.datetime.now() - start)) start = dt.datetime.now() groups = df.groupby('c') res = groups['x'].rolling(20).mean() / groups['y'].rolling(30).mean() print("Pandas (group by): {0}s".format(dt.datetime.now() - start)) start = dt.datetime.now() t = MovingAverage(20, 'x') / MovingAverage(30, 'x') res = t.transform(df) print("Finance-Python (accumulator): {0}s".format(dt.datetime.now() - start)) start = dt.datetime.now() res = df['x'].rolling(20).mean() / df['x'].rolling(30).mean() print("Pandas (group by): {0}s".format(dt.datetime.now() - start))
def __init__(self, window=30, target_vol=0.01): super().__init__() self.m_vol = MovingStandardDeviation(window, 'return') self.m_leverage = MovingAverage(window, 'leverage') self.target_vol = target_vol self.multiplier = 1.