Skip to content

Commit

Permalink
V0.9.27 更新一批代码 (#164)
Browse files Browse the repository at this point in the history
* 0.9.27 first commit

* 0.9.27 新增一开多平策略编写样例

* 0.9.27 优化持仓权重回测

* 0.9.27 统一ensemble_method回调函数的输入

* 0.9.27 trader 对象新增 weight_backtest

* 0.9.27 新增两个信号函数

* 0.9.27 update

* 0.9.27 update

* 0.9.27 新增几个信号函数
  • Loading branch information
zengbin93 authored Aug 19, 2023
1 parent ffc7240 commit 2d676f9
Show file tree
Hide file tree
Showing 21 changed files with 929 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ name: Python package

on:
push:
branches: [ master, V0.9.26 ]
branches: [ master, V0.9.27 ]
pull_request:
branches: [ master ]

Expand Down
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@
"120"
],
"typescript.locale": "zh-CN",
"python.analysis.typeCheckingMode": "basic",
}
4 changes: 2 additions & 2 deletions czsc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@
from czsc.utils.cache import home_path, get_dir_size, empty_cache_path


__version__ = "0.9.26"
__version__ = "0.9.27"
__author__ = "zengbin93"
__email__ = "zeng_bin8888@163.com"
__date__ = "20230726"
__date__ = "20230812"


def welcome():
Expand Down
7 changes: 4 additions & 3 deletions czsc/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,8 @@ def ubi_fxs(self) -> List[FX]:
@property
def ubi(self):
"""Unfinished Bi,未完成的笔"""
if not self.bars_ubi or not self.bi_list:
ubi_fxs = self.ubi_fxs
if not self.bars_ubi or not self.bi_list or not ubi_fxs:
return None

bars_raw = [y for x in self.bars_ubi for y in x.raw_bars]
Expand All @@ -387,8 +388,8 @@ def ubi(self):
"low_bar": low_bar,
"bars": self.bars_ubi,
"raw_bars": bars_raw,
"fxs": self.ubi_fxs,
"fx_a": self.ubi_fxs[0],
"fxs": ubi_fxs,
"fx_a": ubi_fxs[0],
}
return bi

Expand Down
5 changes: 5 additions & 0 deletions czsc/signals/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
cxt_eleven_bi_V230622,
cxt_range_oscillation_V230620,
cxt_intraday_V230701,
cxt_ubi_end_V230816,
cxt_bi_end_V230815,
cxt_bi_stop_V230815,
)


Expand Down Expand Up @@ -198,6 +201,8 @@
cat_macd_V230518,
cat_macd_V230520,
tas_macd_bc_V230803,
tas_macd_bc_V230804,
tas_macd_bc_ubi_V230804,
)

from czsc.signals.pos import (
Expand Down
142 changes: 139 additions & 3 deletions czsc/signals/cxt.py
Original file line number Diff line number Diff line change
Expand Up @@ -1863,7 +1863,7 @@ def cxt_intraday_V230701(cat: CzscSignals, **kwargs) -> OrderedDict:
assert 21 > di > 0, "di必须为大于0小于21的整数,暂不支持当日走势分类"
k1, k2, k3 = f"{freq1}#{freq2}_D{di}日_走势分类V230701".split('_')
v1 = "其他"
if '30分钟' not in cat.kas.keys() or '日线' not in cat.kas.keys():
if not cat.kas or freq1 not in cat.kas.keys() or freq2 not in cat.kas.keys():
return create_single_signal(k1=k1, k2=k2, k3=k3, v1=v1)

c1, c2 = cat.kas[freq1], cat.kas[freq2]
Expand All @@ -1889,11 +1889,11 @@ def cxt_intraday_V230701(cat: CzscSignals, **kwargs) -> OrderedDict:
zs1, zs2 = zs_list[0], zs_list[-1]
zs1_high, zs1_low = max([x.high for x in zs1]), min([x.low for x in zs1])
zs2_high, zs2_low = max([x.high for x in zs2]), min([x.low for x in zs2])
if _dir == "上涨" and zs1_high < zs2_low:
if _dir == "上涨" and zs1_high < zs2_low: # type: ignore
v1 = f"双中枢{_dir}"
return create_single_signal(k1=k1, k2=k2, k3=k3, v1=v1)

if _dir == "下跌" and zs1_low > zs2_high:
if _dir == "下跌" and zs1_low > zs2_high: # type: ignore
v1 = f"双中枢{_dir}"
return create_single_signal(k1=k1, k2=k2, k3=k3, v1=v1)

Expand All @@ -1908,3 +1908,139 @@ def cxt_intraday_V230701(cat: CzscSignals, **kwargs) -> OrderedDict:
v1 = "转折平衡市"

return create_single_signal(k1=k1, k2=k2, k3=k3, v1=v1)


def cxt_ubi_end_V230816(c: CZSC, **kwargs) -> OrderedDict:
"""当前是未完成笔的第几次新低或新高,用于笔结束辅助
参数模板:"{freq}_UBI_BE辅助V230816"
**信号逻辑:**
以向上未完成笔为例:取所有顶分型,计算创新高的底分型数量N,如果当前K线创新高,则新高次数为N+1
**信号列表:**
- Signal('日线_UBI_BE辅助V230816_新低_第4次_任意_0')
- Signal('日线_UBI_BE辅助V230816_新低_第5次_任意_0')
- Signal('日线_UBI_BE辅助V230816_新低_第6次_任意_0')
- Signal('日线_UBI_BE辅助V230816_新高_第2次_任意_0')
- Signal('日线_UBI_BE辅助V230816_新高_第3次_任意_0')
- Signal('日线_UBI_BE辅助V230816_新高_第4次_任意_0')
- Signal('日线_UBI_BE辅助V230816_新高_第5次_任意_0')
- Signal('日线_UBI_BE辅助V230816_新高_第6次_任意_0')
- Signal('日线_UBI_BE辅助V230816_新高_第7次_任意_0')
- Signal('日线_UBI_BE辅助V230816_新低_第2次_任意_0')
- Signal('日线_UBI_BE辅助V230816_新低_第3次_任意_0')
:param c: CZSC对象
:param kwargs:
:return: 信号识别结果
"""
freq = c.freq.value
k1, k2, k3 = f"{freq}_UBI_BE辅助V230816".split('_')
v1, v2 = '其他','其他'
ubi = c.ubi
if not ubi or len(ubi['fxs']) <= 2 or len(c.bars_ubi) <= 5:
return create_single_signal(k1=k1, k2=k2, k3=k3, v1=v1, v2=v2)

fxs = ubi['fxs']
if ubi['direction'] == Direction.Up:
fxs = [x for x in fxs if x.mark == Mark.G]
cnt = 1
cur_hfx = fxs[0]
for fx in fxs[1:]:
if fx.high > cur_hfx.high:
cnt += 1
cur_hfx = fx

if ubi['raw_bars'][-1].high > cur_hfx.high:
v1 = '新高'
v2 = f"第{cnt + 1}次"

if ubi['direction'] == Direction.Down:
fxs = [x for x in fxs if x.mark == Mark.D]
cnt = 1
cur_lfx = fxs[0]
for fx in fxs[1:]:
if fx.low < cur_lfx.low:
cnt += 1
cur_lfx = fx

if ubi['raw_bars'][-1].low < cur_lfx.low:
v1 = '新低'
v2 = f"第{cnt + 1}次"

return create_single_signal(k1=k1, k2=k2, k3=k3, v1=v1, v2=v2)


def cxt_bi_end_V230815(c: CZSC, **kwargs) -> OrderedDict:
"""一两根K线快速突破反向笔
参数模板:"{freq}_快速突破_BE辅助V230815"
**信号逻辑:**
以向上笔为例:右侧分型完成后第一根K线的最低价低于该笔的最低价,认为向上笔结束,反向向下笔开始。
**信号列表:**
- Signal('15分钟_快速突破_BE辅助V230815_向下_任意_任意_0')
- Signal('15分钟_快速突破_BE辅助V230815_向上_任意_任意_0')
:param c: CZSC对象
:param kwargs:
:return: 信号识别结果
"""
freq = c.freq.value
k1, k2, k3 = f"{freq}_快速突破_BE辅助V230815".split('_')
v1 = '其他'
if len(c.bi_list) < 5 or len(c.bars_ubi) >= 5:
return create_single_signal(k1=k1, k2=k2, k3=k3, v1=v1)

bi, last_bar = c.bi_list[-1], c.bars_ubi[-1]
if bi.direction == Direction.Up and last_bar.low < bi.low:
v1 = '向下'
if bi.direction == Direction.Down and last_bar.high > bi.high:
v1 = '向上'
return create_single_signal(k1=k1, k2=k2, k3=k3, v1=v1)


def cxt_bi_stop_V230815(c: CZSC, **kwargs) -> OrderedDict:
"""定位笔的止损距离大小
参数模板:"{freq}_距离{th}BP_止损V230815"
**信号逻辑:**
以向上笔为例:如果当前K线的收盘价高于该笔的最高价的1 - 0.5%,则认为在止损阈值内,否则认为在止损阈值外。
**信号列表:**
- Signal('15分钟_距离50BP_止损V230815_向下_阈值外_任意_0')
- Signal('15分钟_距离50BP_止损V230815_向上_阈值内_任意_0')
- Signal('15分钟_距离50BP_止损V230815_向下_阈值内_任意_0')
- Signal('15分钟_距离50BP_止损V230815_向上_阈值外_任意_0')
:param c: CZSC对象
:param kwargs:
- th: 止损距离阈值,单位为BP, 默认为50BP, 即0.5%
:return: 信号识别结果
"""
th = int(kwargs.get('th', 50))
freq = c.freq.value
k1, k2, k3 = f"{freq}_距离{th}BP_止损V230815".split('_')
v1, v2 = '其他', '其他'
if len(c.bi_list) < 5:
return create_single_signal(k1=k1, k2=k2, k3=k3, v1=v1)

bi, last_bar = c.bi_list[-1], c.bars_ubi[-1]
if bi.direction == Direction.Up:
v1 = '向下'
v2 = "阈值内" if last_bar.close > bi.high * (1 - th / 10000) else "阈值外"
if bi.direction == Direction.Down:
v1 = '向上'
v2 = "阈值内" if last_bar.close < bi.low * (1 + th / 10000) else "阈值外"
return create_single_signal(k1=k1, k2=k2, k3=k3, v1=v1, v2=v2)
2 changes: 1 addition & 1 deletion czsc/signals/pos.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ def pos_holds_V230807(cat: CzscTrader, **kwargs) -> OrderedDict:
k1, k2, k3 = f"{pos_name}_{freq1}N{n}M{m}T{t}_BS辅助V230807".split("_")
v1 = '其他'
# 如果没有持仓策略,则不产生信号
if not hasattr(cat, "positions"):
if not cat.kas or not hasattr(cat, "positions"):
return create_single_signal(k1=k1, k2=k2, k3=k3, v1=v1)

pos = [x for x in cat.positions if x.name == pos_name][0]
Expand Down
Loading

0 comments on commit 2d676f9

Please sign in to comment.