Commit 7dd0bb99 authored by Dr.李's avatar Dr.李

added tests for target vol executor

parent 0591851d
......@@ -30,3 +30,6 @@ class ExecutorBase(metaclass=abc.ABCMeta):
def set_current(self, current_pos: pd.DataFrame):
self.current_pos = current_pos.copy()
def update(self, data_dict: dict):
pass
......@@ -17,7 +17,7 @@ class NaiveExecutor(ExecutorBase):
def execute(self, target_pos: pd.DataFrame) -> Tuple[float, pd.DataFrame]:
if self.current_pos.empty:
turn_over = target_pos.weight.sum()
turn_over = target_pos.weight.abs().sum()
else:
turn_over = self.calc_turn_over(target_pos, self.current_pos)
self.current_pos = target_pos.copy()
......
......@@ -21,12 +21,18 @@ class TargetVolExecutor(ExecutorBase):
def execute(self, target_pos: pd.DataFrame) -> Tuple[float, pd.DataFrame]:
if not self.m_vol.isFull():
turn_over = self.calc_turn_over(target_pos, self.current_pos)
if self.current_pos.empty:
turn_over = target_pos.abs().weight.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()
self.multiplier = c_vol / self.target_vol
candidate_pos = target_pos.copy()
candidate_pos['weight'] = candidate_pos.weight * self.multiplier
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 update(self, data_dict: dict):
self.m_vol.push(data_dict)
......@@ -19,7 +19,7 @@ class ThresholdExecutor(ExecutorBase):
def execute(self, target_pos: pd.DataFrame) -> Tuple[float, pd.DataFrame]:
if self.current_pos.empty:
return target_pos.weight.sum(), target_pos
return target_pos.weight.abs().sum(), target_pos
else:
turn_over = self.calc_turn_over(target_pos, self.current_pos)
......
......@@ -6,13 +6,45 @@ Created on 2017-9-22
"""
import unittest
from collections import deque
import numpy as np
import pandas as pd
from alphamind.execution.targetvolexecutor import TargetVolExecutor
class TestTargetVolExecutor(unittest.TestCase):
def test_target_vol_executor(self):
n = 100
window = 30
target_vol = 0.01
executor = TargetVolExecutor(window=window, target_vol=target_vol)
return_1 = np.random.randn(2000, n) * 0.05
return_2 = np.random.randn(2000, n) * 0.2
return_total = np.concatenate((return_1, return_2))
weigths = np.ones(n) / n
codes = np.array(list(range(n)))
ret_deq = deque(maxlen=window)
for i, row in enumerate(return_total):
pos = pd.DataFrame({'code': codes, 'weight': weigths})
turn_over, executed_pos = executor.execute(pos)
if i >= window:
c_vol = np.std(ret_deq, ddof=1)
executed_pos.equals(pos * target_vol / c_vol)
else:
executed_pos.equals(pos)
executor.set_current(executed_pos)
daily_return = row @ weigths
data_dict = {'return': daily_return}
executor.update(data_dict=data_dict)
ret_deq.append(daily_return)
if __name__ == '__main__':
......
......@@ -30,6 +30,7 @@ from alphamind.tests.model.test_linearmodel import TestLinearModel
from alphamind.tests.model.test_loader import TestLoader
from alphamind.tests.execution.test_naiveexecutor import TestNaiveExecutor
from alphamind.tests.execution.test_thresholdexecutor import TestThresholdExecutor
from alphamind.tests.execution.test_targetvolexecutor import TestTargetVolExecutor
if __name__ == '__main__':
......@@ -51,6 +52,7 @@ if __name__ == '__main__':
TestLinearModel,
TestLoader,
TestNaiveExecutor,
TestThresholdExecutor],
TestThresholdExecutor,
TestTargetVolExecutor],
alpha_logger)
runner.run()
......@@ -42,4 +42,4 @@ u."AccountsPayablesTDays",u."AccountsPayablesTRate",u."AdminiExpenseRate",u."ART
left join tiny as t on m.trade_date = t.trade_date and m.code = t.code
left join experimental as e on m.trade_date = e.trade_date and m.code = e.code;
create UNIQUE index on full_factor_view (trade_date, code)
\ No newline at end of file
create UNIQUE index on full_factor_view (trade_date, code);
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment