Commit 570322c4 authored by Dr.李's avatar Dr.李

added execution pipeline

parent cae62afe
......@@ -21,7 +21,7 @@ class ExecutionPipeline(object):
turn_over, planed_pos = 0., target_pos
for executor in self.executors:
turn_over, planed_pos = executor.execute(target_pos)
turn_over, planed_pos = executor.execute(planed_pos)
executed_pos = planed_pos
......
......@@ -8,6 +8,7 @@ Created on 2017-9-22
from typing import Tuple
import pandas as pd
from PyFin.Math.Accumulators import MovingStandardDeviation
from PyFin.Math.Accumulators import MovingAverage
from alphamind.execution.baseexecutor import ExecutorBase
......@@ -16,6 +17,7 @@ class TargetVolExecutor(ExecutorBase):
def __init__(self, window=30, target_vol=0.01):
super().__init__()
self.m_vol = MovingStandardDeviation(window=window, dependency='return')
self.m_leverage = MovingAverage(window=window, dependency='leverage')
self.target_vol = target_vol
self.multiplier = 1.
......@@ -28,11 +30,16 @@ class TargetVolExecutor(ExecutorBase):
return turn_over, target_pos
else:
c_vol = self.m_vol.result()
self.multiplier = c_vol / self.target_vol
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
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)
# -*- coding: utf-8 -*-
"""
Created on 2017-9-25
@author: cheng.li
"""
import unittest
from collections import deque
import numpy as np
import pandas as pd
from alphamind.execution.pipeline import ExecutionPipeline
from alphamind.execution.thresholdexecutor import ThresholdExecutor
from alphamind.execution.targetvolexecutor import TargetVolExecutor
class TestExecutionPipelin(unittest.TestCase):
def test_execution_pipeline(self):
n = 100
window = 60
target_vol = 0.01
turn_over_threshold = 0.5
executor1 = TargetVolExecutor(window=window, target_vol=target_vol)
executor2 = ThresholdExecutor(turn_over_threshold=turn_over_threshold)
execution_pipeline = ExecutionPipeline(executors=[executor1, executor2])
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))
codes = np.array(list(range(n)))
ret_deq = deque(maxlen=window)
for i, row in enumerate(return_total):
weights = np.random.randint(0, 100, n)
weights = weights / weights.sum()
pos = pd.DataFrame({'code': codes, 'weight': weights})
turn_over, executed_pos = execution_pipeline.execute(pos)
daily_return = row @ executed_pos.weight.values.flatten()
data_dict = {'return': daily_return}
execution_pipeline.update(data_dict=data_dict)
ret_deq.append(daily_return)
......@@ -25,13 +25,13 @@ class TestTargetVolExecutor(unittest.TestCase):
return_2 = np.random.randn(2000, n) * 0.2
return_total = np.concatenate((return_1, return_2))
weigths = np.ones(n) / n
weights = 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})
pos = pd.DataFrame({'code': codes, 'weight': weights})
turn_over, executed_pos = executor.execute(pos)
if i >= window:
......@@ -41,7 +41,7 @@ class TestTargetVolExecutor(unittest.TestCase):
executed_pos.equals(pos)
executor.set_current(executed_pos)
daily_return = row @ weigths
daily_return = row @ weights
data_dict = {'return': daily_return}
executor.update(data_dict=data_dict)
ret_deq.append(daily_return)
......
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