Skip to content

Commit

Permalink
0.8.13 多头持仓对象新增最小持仓间隔控制 (waditu#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
zengbin93 committed Jan 14, 2022
1 parent 651584b commit bd16663
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 1 deletion.
9 changes: 9 additions & 0 deletions czsc/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ def __init__(self, symbol: str,
hold_long_a: float = 0.5,
hold_long_b: float = 0.8,
hold_long_c: float = 1.0,
long_min_interval: int = None,
cost: float = 0.003,
T0: bool = False):
"""多头持仓对象
Expand All @@ -369,13 +370,15 @@ def __init__(self, symbol: str,
:param hold_long_a: 首次开多仓后的仓位
:param hold_long_b: 第一次加多后的仓位
:param hold_long_c: 第二次加多后的仓位
:param long_min_interval: 两次开多仓之间的最小时间间隔,单位:秒
:param cost: 双边交易成本,默认为千分之三
:param T0: 是否允许T0交易,默认为 False 表示不允许T0交易
"""
assert 0 <= hold_long_a <= hold_long_b <= hold_long_c <= 1.0

self.pos_changed = False
self.symbol = symbol
self.long_min_interval = long_min_interval
self.cost = cost
self.T0 = T0
self.pos_map = {
Expand Down Expand Up @@ -500,6 +503,12 @@ def update(self, dt: datetime, op: Operate, price: float, bid: int, op_desc: str
old_pos = self.pos

if state == 'hold_money' and op == Operate.LO:
if self.long_min_interval and self.operates:
assert self.operates[-1]['op'] == Operate.LE
# 当前和上次平多仓时间的间隔(秒)小于 long_min_interval,不允许开仓
if (dt - self.operates[-1]['dt']).total_seconds() < self.long_min_interval:
return

self.long_open()
pos_changed = True
self.today_pos = self.pos
Expand Down
54 changes: 53 additions & 1 deletion test/test_objects.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# coding: utf-8
from collections import OrderedDict
import pandas as pd
from czsc.objects import Signal, Factor, Event, Freq, Operate, PositionLong
from czsc.objects import Signal, Factor, Event, Freq, Operate, PositionLong, PositionShort


def test_signal():
Expand Down Expand Up @@ -213,3 +213,55 @@ def test_position_long_t0():
assert len(pos_long.pairs) == 1
pos_long.evaluate_operates()


def test_position_long_min_interval():
"""测试T0逻辑"""
pos_long = PositionLong(symbol="000001.XSHG", T0=False, long_min_interval=3600*72)

pos_long.update(dt=pd.to_datetime('2021-01-01'), op=Operate.HO, price=100, bid=0)
assert not pos_long.pos_changed and pos_long.pos == 0

pos_long.update(dt=pd.to_datetime('2021-01-02'), op=Operate.LO, price=100, bid=1, op_desc="首次开仓测试")
assert pos_long.pos_changed and pos_long.pos == 0.5

pos_long.update(dt=pd.to_datetime('2021-01-02'), op=Operate.LA1, price=100, bid=3)
assert pos_long.pos_changed and pos_long.pos == 0.8

pos_long.update(dt=pd.to_datetime('2021-01-02'), op=Operate.LA2, price=100, bid=5)
assert pos_long.pos_changed and pos_long.pos == 1

# T0 平仓信号不生效
pos_long.update(dt=pd.to_datetime('2021-01-02'), op=Operate.LE, price=100, bid=8)
assert not pos_long.pos_changed and pos_long.pos == 1

pos_long.update(dt=pd.to_datetime('2021-01-03'), op=Operate.LE, price=100, bid=10)
assert pos_long.pos_changed and pos_long.pos == 0

assert len(pos_long.pairs) == 1

pos_long.update(dt=pd.to_datetime('2021-01-04'), op=Operate.LE, price=100, bid=11)
assert not pos_long.pos_changed and pos_long.pos == 0

# 测试最小开仓间隔
pos_long.update(dt=pd.to_datetime('2021-01-04'), op=Operate.LO, price=100, bid=12, op_desc="第二次开仓测试")
assert not pos_long.pos_changed and pos_long.pos == 0

pos_long.update(dt=pd.to_datetime('2021-01-05'), op=Operate.LO, price=100, bid=13, op_desc="第二次开仓测试")
assert not pos_long.pos_changed and pos_long.pos == 0

pos_long.update(dt=pd.to_datetime('2021-01-06'), op=Operate.LO, price=100, bid=14, op_desc="第二次开仓测试")
assert pos_long.pos_changed and pos_long.pos == 0.5

pos_long.update(dt=pd.to_datetime('2021-01-09'), op=Operate.LA1, price=100, bid=15)
assert pos_long.pos_changed and pos_long.pos == 0.8

pos_long.update(dt=pd.to_datetime('2021-01-10'), op=Operate.LA2, price=100, bid=16)
assert pos_long.pos_changed and pos_long.pos == 1

assert len(pos_long.pairs) == 1

print(pos_long.evaluate_operates())


# TODO: 编写空头持仓对象的单元测试

0 comments on commit bd16663

Please sign in to comment.