Commit 729a28af authored by Dr.李's avatar Dr.李

made executors to return turn over

parent 3144c815
...@@ -7,14 +7,24 @@ Created on 2017-9-22 ...@@ -7,14 +7,24 @@ Created on 2017-9-22
import abc import abc
from typing import Tuple
import numpy as np
import pandas as pd import pandas as pd
class ExecutorBase(metaclass=abc.ABCMeta): class ExecutorBase(metaclass=abc.ABCMeta):
def __init__(self): def __init__(self):
pass self.current_pos = pd.DataFrame()
@abc.abstractmethod @abc.abstractmethod
def execute(self, target_pos: pd.DataFrame) -> pd.DataFrame: def execute(self, target_pos: pd.DataFrame) -> pd.DataFrame:
pass pass
\ No newline at end of file
@staticmethod
def calc_turn_over(target_pos: pd.DataFrame, current_pos: pd.DataFrame) -> float:
pos_merged = pd.merge(target_pos, current_pos, on=['code'], how='outer')
pos_merged.fillna(0, inplace=True)
pos_merged['industry'] = pos_merged['industry_x'].where(pos_merged['industry_x'] != 0, pos_merged['industry_y'])
turn_over = np.abs(pos_merged.weight_x - pos_merged.weight_y).sum()
return turn_over
...@@ -5,6 +5,7 @@ Created on 2017-9-22 ...@@ -5,6 +5,7 @@ Created on 2017-9-22
@author: cheng.li @author: cheng.li
""" """
from typing import Tuple
import pandas as pd import pandas as pd
from alphamind.execution.baseexecutor import ExecutorBase from alphamind.execution.baseexecutor import ExecutorBase
...@@ -14,5 +15,10 @@ class NaiveExecutor(ExecutorBase): ...@@ -14,5 +15,10 @@ class NaiveExecutor(ExecutorBase):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
def execute(self, target_pos: pd.DataFrame) -> pd.DataFrame: def execute(self, target_pos: pd.DataFrame) -> Tuple[float, pd.DataFrame]:
return target_pos.copy() if self.current_pos.empty:
turn_over = target_pos.weight.sum()
else:
turn_over = self.calc_turn_over(target_pos, self.current_pos)
self.current_pos = target_pos.copy()
return turn_over, target_pos.copy()
...@@ -5,7 +5,7 @@ Created on 2017-9-22 ...@@ -5,7 +5,7 @@ Created on 2017-9-22
@author: cheng.li @author: cheng.li
""" """
import numpy as np from typing import Tuple
import pandas as pd import pandas as pd
from alphamind.execution.baseexecutor import ExecutorBase from alphamind.execution.baseexecutor import ExecutorBase
...@@ -17,19 +17,16 @@ class ThresholdExecutor(ExecutorBase): ...@@ -17,19 +17,16 @@ class ThresholdExecutor(ExecutorBase):
self.threshold = turn_over_threshold self.threshold = turn_over_threshold
self.current_pos = pd.DataFrame() self.current_pos = pd.DataFrame()
def execute(self, target_pos: pd.DataFrame) -> pd.DataFrame: def execute(self, target_pos: pd.DataFrame) -> Tuple[float, pd.DataFrame]:
if self.current_pos.empty: if self.current_pos.empty:
self.current_pos = target_pos.copy() self.current_pos = target_pos.copy()
return target_pos.copy() return target_pos.weight.sum(), target_pos.copy()
else: else:
pos_merged = pd.merge(target_pos, self.current_pos, on=['code'], how='outer') turn_over = self.calc_turn_over(target_pos, self.current_pos)
pos_merged.fillna(0, inplace=True)
pos_merged['industry'] = pos_merged['industry_x'].where(pos_merged['industry_x'] != 0, pos_merged['industry_y'])
turn_over = np.abs(pos_merged.weight_x - pos_merged.weight_y).sum()
if turn_over >= self.threshold: if turn_over >= self.threshold:
self.current_pos = target_pos.copy() self.current_pos = target_pos.copy()
return self.current_pos.copy() return turn_over, self.current_pos.copy()
else: else:
return self.current_pos.copy() return 0., self.current_pos.copy()
...@@ -21,24 +21,27 @@ class TestThresholdExecutor(unittest.TestCase): ...@@ -21,24 +21,27 @@ class TestThresholdExecutor(unittest.TestCase):
executor = ThresholdExecutor(turn_over_threshold=0.5) executor = ThresholdExecutor(turn_over_threshold=0.5)
# 1st round # 1st round
executed_pos = executor.execute(target_pos) turn_over, executed_pos = executor.execute(target_pos)
self.assertTrue(target_pos.equals(executed_pos)) self.assertTrue(target_pos.equals(executed_pos))
self.assertAlmostEqual(turn_over, target_pos.weight.sum())
# 2nd round # 2nd round
target_pos = pd.DataFrame({'code': [1, 2, 4], target_pos = pd.DataFrame({'code': [1, 2, 4],
'weight': [0.3, 0.2, 0.5], 'weight': [0.3, 0.2, 0.5],
'industry': ['a', 'b', 'd']}) 'industry': ['a', 'b', 'd']})
executed_pos = executor.execute(target_pos) turn_over, executed_pos = executor.execute(target_pos)
self.assertTrue(target_pos.equals(executed_pos)) self.assertTrue(target_pos.equals(executed_pos))
self.assertTrue(executed_pos.equals(executor.current_pos)) self.assertTrue(executed_pos.equals(executor.current_pos))
self.assertAlmostEqual(turn_over, 1.2)
# 3nd round # 3nd round
target_pos = pd.DataFrame({'code': [1, 3, 4], target_pos = pd.DataFrame({'code': [1, 3, 4],
'weight': [0.3, 0.2, 0.5], 'weight': [0.3, 0.2, 0.5],
'industry': ['a', 'c', 'd']}) 'industry': ['a', 'c', 'd']})
executed_pos2 = executor.execute(target_pos) turn_over, executed_pos2 = executor.execute(target_pos)
self.assertTrue(executed_pos.equals(executed_pos2)) self.assertTrue(executed_pos.equals(executed_pos2))
self.assertAlmostEqual(turn_over, 0.)
if __name__ == '__main__': if __name__ == '__main__':
......
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