Commit 45eabfc1 authored by Dr.李's avatar Dr.李

added target turn over executor

parent 6e01cdaa
...@@ -27,3 +27,6 @@ class ExecutorBase(metaclass=abc.ABCMeta): ...@@ -27,3 +27,6 @@ class ExecutorBase(metaclass=abc.ABCMeta):
pos_merged.fillna(0, inplace=True) pos_merged.fillna(0, inplace=True)
turn_over = np.abs(pos_merged.weight_x - pos_merged.weight_y).sum() turn_over = np.abs(pos_merged.weight_x - pos_merged.weight_y).sum()
return turn_over return turn_over
def set_current(self, current_pos: pd.DataFrame):
self.current_pos = current_pos.copy()
...@@ -21,4 +21,4 @@ class NaiveExecutor(ExecutorBase): ...@@ -21,4 +21,4 @@ class NaiveExecutor(ExecutorBase):
else: else:
turn_over = self.calc_turn_over(target_pos, self.current_pos) turn_over = self.calc_turn_over(target_pos, self.current_pos)
self.current_pos = target_pos.copy() self.current_pos = target_pos.copy()
return turn_over, target_pos.copy() return turn_over, target_pos
# -*- coding: utf-8 -*-
"""
Created on 2017-9-22
@author: cheng.li
"""
from typing import Tuple
import pandas as pd
from PyFin.Math.Accumulators import MovingStandardDeviation
from alphamind.execution.baseexecutor import ExecutorBase
class TargetVolExecutor(ExecutorBase):
def __init__(self, window=30, target_vol=0.01):
super().__init__()
self.m_vol = MovingStandardDeviation(window=window, dependency='return')
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():
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
turn_over = self.calc_turn_over(candidate_pos, self.current_pos)
return turn_over, candidate_pos
...@@ -15,18 +15,15 @@ class ThresholdExecutor(ExecutorBase): ...@@ -15,18 +15,15 @@ class ThresholdExecutor(ExecutorBase):
def __init__(self, turn_over_threshold: float): def __init__(self, turn_over_threshold: float):
super().__init__() super().__init__()
self.threshold = turn_over_threshold self.threshold = turn_over_threshold
self.current_pos = pd.DataFrame()
def execute(self, target_pos: pd.DataFrame) -> Tuple[float, 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() return target_pos.weight.sum(), target_pos
return target_pos.weight.sum(), target_pos.copy()
else: else:
turn_over = self.calc_turn_over(target_pos, self.current_pos) turn_over = self.calc_turn_over(target_pos, self.current_pos)
if turn_over >= self.threshold * self.current_pos.weight.sum(): if turn_over >= self.threshold * self.current_pos.weight.sum():
self.current_pos = target_pos.copy() return turn_over, target_pos
return turn_over, self.current_pos.copy()
else: else:
return 0., self.current_pos.copy() return 0., self.current_pos.copy()
...@@ -20,6 +20,7 @@ class TestNaiveExecutor(unittest.TestCase): ...@@ -20,6 +20,7 @@ class TestNaiveExecutor(unittest.TestCase):
# 1st round # 1st round
executor = NaiveExecutor() executor = NaiveExecutor()
turn_over, executed_pos = executor.execute(target_pos) turn_over, executed_pos = executor.execute(target_pos)
executor.set_current(executed_pos)
self.assertAlmostEqual(turn_over, 1.0) self.assertAlmostEqual(turn_over, 1.0)
# 2nd round # 2nd round
...@@ -28,6 +29,7 @@ class TestNaiveExecutor(unittest.TestCase): ...@@ -28,6 +29,7 @@ class TestNaiveExecutor(unittest.TestCase):
'industry': ['a', 'b', 'd']}) 'industry': ['a', 'b', 'd']})
turn_over, executed_pos = executor.execute(target_pos) turn_over, executed_pos = executor.execute(target_pos)
executor.set_current(executed_pos)
self.assertAlmostEqual(turn_over, 1.2) self.assertAlmostEqual(turn_over, 1.2)
# 3rd round # 3rd round
...@@ -35,6 +37,7 @@ class TestNaiveExecutor(unittest.TestCase): ...@@ -35,6 +37,7 @@ class TestNaiveExecutor(unittest.TestCase):
'weight': [0.3, 0.2, 0.5], 'weight': [0.3, 0.2, 0.5],
'industry': ['a', 'c', 'd']}) 'industry': ['a', 'c', 'd']})
turn_over, executed_pos = executor.execute(target_pos) turn_over, executed_pos = executor.execute(target_pos)
executor.set_current(executed_pos)
self.assertAlmostEqual(turn_over, 0.4) self.assertAlmostEqual(turn_over, 0.4)
......
# -*- coding: utf-8 -*-
"""
Created on 2017-9-22
@author: cheng.li
"""
import unittest
from alphamind.execution.targetvolexecutor import TargetVolExecutor
class TestTargetVolExecutor(unittest.TestCase):
def test_target_vol_executor(self):
if __name__ == '__main__':
unittest.main()
\ No newline at end of file
...@@ -21,6 +21,7 @@ class TestThresholdExecutor(unittest.TestCase): ...@@ -21,6 +21,7 @@ class TestThresholdExecutor(unittest.TestCase):
# 1st round # 1st round
turn_over, executed_pos = executor.execute(target_pos) turn_over, executed_pos = executor.execute(target_pos)
executor.set_current(executed_pos)
self.assertTrue(target_pos.equals(executed_pos)) self.assertTrue(target_pos.equals(executed_pos))
self.assertAlmostEqual(turn_over, target_pos.weight.sum()) self.assertAlmostEqual(turn_over, target_pos.weight.sum())
...@@ -30,6 +31,7 @@ class TestThresholdExecutor(unittest.TestCase): ...@@ -30,6 +31,7 @@ class TestThresholdExecutor(unittest.TestCase):
'industry': ['a', 'b', 'd']}) 'industry': ['a', 'b', 'd']})
turn_over, executed_pos = executor.execute(target_pos) turn_over, executed_pos = executor.execute(target_pos)
executor.set_current(executed_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) self.assertAlmostEqual(turn_over, 1.2)
...@@ -39,6 +41,7 @@ class TestThresholdExecutor(unittest.TestCase): ...@@ -39,6 +41,7 @@ class TestThresholdExecutor(unittest.TestCase):
'weight': [0.3, 0.2, 0.5], 'weight': [0.3, 0.2, 0.5],
'industry': ['a', 'c', 'd']}) 'industry': ['a', 'c', 'd']})
turn_over, executed_pos2 = executor.execute(target_pos) turn_over, executed_pos2 = executor.execute(target_pos)
executor.set_current(executed_pos2)
self.assertTrue(executed_pos.equals(executed_pos2)) self.assertTrue(executed_pos.equals(executed_pos2))
self.assertAlmostEqual(turn_over, 0.) self.assertAlmostEqual(turn_over, 0.)
......
This source diff could not be displayed because it is too large. You can view the blob instead.
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