polars-ta 0.5.2__tar.gz → 0.5.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- polars_ta-0.5.4/.gitignore +160 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/PKG-INFO +13 -10
- {polars_ta-0.5.2 → polars_ta-0.5.4}/README.md +5 -0
- polars_ta-0.5.4/polars_ta/_version.py +1 -0
- polars_ta-0.5.4/polars_ta/labels/__init__.py +1 -0
- polars_ta-0.5.4/polars_ta/labels/_nb.py +40 -0
- polars_ta-0.5.4/polars_ta/labels/future.py +165 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/performance/returns.py +1 -7
- polars_ta-0.5.4/polars_ta/prefix/labels.py +1 -0
- polars_ta-0.5.4/polars_ta/ta/README.md +12 -0
- polars_ta-0.5.4/polars_ta/talib/README.md +12 -0
- polars_ta-0.5.4/polars_ta/tdx/README.md +10 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/utils/numba_.py +2 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/wq/arithmetic.py +151 -25
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/wq/cross_sectional.py +27 -15
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/wq/logical.py +3 -3
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/wq/preprocess.py +19 -42
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/wq/time_series.py +62 -33
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/wq/transformational.py +10 -5
- {polars_ta-0.5.2 → polars_ta-0.5.4}/pyproject.toml +12 -19
- polars_ta-0.5.2/polars_ta/_version.py +0 -1
- polars_ta-0.5.2/polars_ta.egg-info/PKG-INFO +0 -260
- polars_ta-0.5.2/polars_ta.egg-info/SOURCES.txt +0 -72
- polars_ta-0.5.2/polars_ta.egg-info/dependency_links.txt +0 -1
- polars_ta-0.5.2/polars_ta.egg-info/requires.txt +0 -8
- polars_ta-0.5.2/polars_ta.egg-info/top_level.txt +0 -1
- polars_ta-0.5.2/setup.cfg +0 -4
- polars_ta-0.5.2/setup.py +0 -3
- {polars_ta-0.5.2 → polars_ta-0.5.4}/LICENSE +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/__init__.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/candles/__init__.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/candles/cdl1.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/candles/cdl1_limit.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/candles/cdl2.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/noise.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/performance/__init__.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/performance/drawdown.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/prefix/__init__.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/prefix/cdl.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/prefix/reports.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/prefix/ta.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/prefix/talib.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/prefix/tdx.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/prefix/wq.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/reports/__init__.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/reports/cicc.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/ta/__init__.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/ta/momentum.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/ta/operators.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/ta/overlap.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/ta/price.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/ta/statistic.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/ta/transform.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/ta/volatility.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/ta/volume.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/talib/__init__.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/__init__.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/_chip.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/_nb.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/_slow.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/arithmetic.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/choice.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/energy.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/logical.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/moving_average.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/over_bought_over_sold.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/pattern.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/pattern_feature.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/pressure_support.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/reference.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/statistic.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/trend.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/trend_feature.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/tdx/volume.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/utils/__init__.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/utils/helper.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/utils/pandas_.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/utils/pit.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/utils/wrapper.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/wq/__init__.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/wq/_nb.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/wq/_slow.py +0 -0
- {polars_ta-0.5.2 → polars_ta-0.5.4}/polars_ta/wq/vector.py +0 -0
@@ -0,0 +1,160 @@
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
2
|
+
__pycache__/
|
3
|
+
*.py[cod]
|
4
|
+
*$py.class
|
5
|
+
|
6
|
+
# C extensions
|
7
|
+
*.so
|
8
|
+
|
9
|
+
# Distribution / packaging
|
10
|
+
.Python
|
11
|
+
build/
|
12
|
+
develop-eggs/
|
13
|
+
dist/
|
14
|
+
downloads/
|
15
|
+
eggs/
|
16
|
+
.eggs/
|
17
|
+
lib/
|
18
|
+
lib64/
|
19
|
+
parts/
|
20
|
+
sdist/
|
21
|
+
var/
|
22
|
+
wheels/
|
23
|
+
share/python-wheels/
|
24
|
+
*.egg-info/
|
25
|
+
.installed.cfg
|
26
|
+
*.egg
|
27
|
+
MANIFEST
|
28
|
+
|
29
|
+
# PyInstaller
|
30
|
+
# Usually these files are written by a python script from a template
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
32
|
+
*.manifest
|
33
|
+
*.spec
|
34
|
+
|
35
|
+
# Installer logs
|
36
|
+
pip-log.txt
|
37
|
+
pip-delete-this-directory.txt
|
38
|
+
|
39
|
+
# Unit test / coverage reports
|
40
|
+
htmlcov/
|
41
|
+
.tox/
|
42
|
+
.nox/
|
43
|
+
.coverage
|
44
|
+
.coverage.*
|
45
|
+
.cache
|
46
|
+
nosetests.xml
|
47
|
+
coverage.xml
|
48
|
+
*.cover
|
49
|
+
*.py,cover
|
50
|
+
.hypothesis/
|
51
|
+
.pytest_cache/
|
52
|
+
cover/
|
53
|
+
|
54
|
+
# Translations
|
55
|
+
*.mo
|
56
|
+
*.pot
|
57
|
+
|
58
|
+
# Django stuff:
|
59
|
+
*.log
|
60
|
+
local_settings.py
|
61
|
+
db.sqlite3
|
62
|
+
db.sqlite3-journal
|
63
|
+
|
64
|
+
# Flask stuff:
|
65
|
+
instance/
|
66
|
+
.webassets-cache
|
67
|
+
|
68
|
+
# Scrapy stuff:
|
69
|
+
.scrapy
|
70
|
+
|
71
|
+
# Sphinx documentation
|
72
|
+
docs/_build/
|
73
|
+
|
74
|
+
# PyBuilder
|
75
|
+
.pybuilder/
|
76
|
+
target/
|
77
|
+
|
78
|
+
# Jupyter Notebook
|
79
|
+
.ipynb_checkpoints
|
80
|
+
|
81
|
+
# IPython
|
82
|
+
profile_default/
|
83
|
+
ipython_config.py
|
84
|
+
|
85
|
+
# pyenv
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
88
|
+
# .python-version
|
89
|
+
|
90
|
+
# pipenv
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
94
|
+
# install all needed dependencies.
|
95
|
+
#Pipfile.lock
|
96
|
+
|
97
|
+
# poetry
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
100
|
+
# commonly ignored for libraries.
|
101
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
102
|
+
#poetry.lock
|
103
|
+
|
104
|
+
# pdm
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
106
|
+
#pdm.lock
|
107
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
108
|
+
# in version control.
|
109
|
+
# https://pdm.fming.dev/#use-with-ide
|
110
|
+
.pdm.toml
|
111
|
+
|
112
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
113
|
+
__pypackages__/
|
114
|
+
|
115
|
+
# Celery stuff
|
116
|
+
celerybeat-schedule
|
117
|
+
celerybeat.pid
|
118
|
+
|
119
|
+
# SageMath parsed files
|
120
|
+
*.sage.py
|
121
|
+
|
122
|
+
# Environments
|
123
|
+
.env
|
124
|
+
.venv
|
125
|
+
env/
|
126
|
+
venv/
|
127
|
+
ENV/
|
128
|
+
env.bak/
|
129
|
+
venv.bak/
|
130
|
+
|
131
|
+
# Spyder project settings
|
132
|
+
.spyderproject
|
133
|
+
.spyproject
|
134
|
+
|
135
|
+
# Rope project settings
|
136
|
+
.ropeproject
|
137
|
+
|
138
|
+
# mkdocs documentation
|
139
|
+
/site
|
140
|
+
|
141
|
+
# mypy
|
142
|
+
.mypy_cache/
|
143
|
+
.dmypy.json
|
144
|
+
dmypy.json
|
145
|
+
|
146
|
+
# Pyre type checker
|
147
|
+
.pyre/
|
148
|
+
|
149
|
+
# pytype static type analyzer
|
150
|
+
.pytype/
|
151
|
+
|
152
|
+
# Cython debug symbols
|
153
|
+
cython_debug/
|
154
|
+
|
155
|
+
# PyCharm
|
156
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
157
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
158
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
159
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
160
|
+
#.idea/
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: polars_ta
|
3
|
-
Version: 0.5.
|
3
|
+
Version: 0.5.4
|
4
4
|
Summary: polars expressions
|
5
5
|
Author-email: wukan <wu-kan@163.com>
|
6
6
|
License: MIT License
|
@@ -24,21 +24,19 @@ License: MIT License
|
|
24
24
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25
25
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26
26
|
SOFTWARE.
|
27
|
-
|
28
|
-
Keywords: polars,
|
27
|
+
License-File: LICENSE
|
28
|
+
Keywords: expression,polars,talib
|
29
29
|
Classifier: Development Status :: 4 - Beta
|
30
30
|
Classifier: Programming Language :: Python
|
31
31
|
Requires-Python: >=3.8
|
32
|
-
Description-Content-Type: text/markdown
|
33
|
-
License-File: LICENSE
|
34
|
-
Requires-Dist: polars>=1.28.0
|
35
|
-
Requires-Dist: polars-ols>=0.3.0
|
36
|
-
Requires-Dist: numpy
|
37
32
|
Requires-Dist: numba
|
33
|
+
Requires-Dist: numpy
|
38
34
|
Requires-Dist: pandas
|
35
|
+
Requires-Dist: polars-ols>=0.3.0
|
36
|
+
Requires-Dist: polars>=1.28.0
|
39
37
|
Provides-Extra: talib
|
40
|
-
Requires-Dist:
|
41
|
-
|
38
|
+
Requires-Dist: ta-lib; extra == 'talib'
|
39
|
+
Description-Content-Type: text/markdown
|
42
40
|
|
43
41
|
# polars_ta
|
44
42
|
|
@@ -248,6 +246,11 @@ mkdocs build
|
|
248
246
|
也可以通过以下链接导入:
|
249
247
|
https://polars-ta.readthedocs.io/en/latest/llms-full.txt
|
250
248
|
|
249
|
+
## 提示词
|
250
|
+
由于`llms-full.txt`信息不适合做提示词,所以`tools/prompt.py`提供了生成更简洁算子清单的功能。
|
251
|
+
|
252
|
+
用户也可以直接使用`prompt.txt`(欢迎提示词工程专家帮忙改进,做的更准确)
|
253
|
+
|
251
254
|
## 参考
|
252
255
|
|
253
256
|
- https://github.com/pola-rs/polars
|
@@ -206,6 +206,11 @@ mkdocs build
|
|
206
206
|
也可以通过以下链接导入:
|
207
207
|
https://polars-ta.readthedocs.io/en/latest/llms-full.txt
|
208
208
|
|
209
|
+
## 提示词
|
210
|
+
由于`llms-full.txt`信息不适合做提示词,所以`tools/prompt.py`提供了生成更简洁算子清单的功能。
|
211
|
+
|
212
|
+
用户也可以直接使用`prompt.txt`(欢迎提示词工程专家帮忙改进,做的更准确)
|
213
|
+
|
209
214
|
## 参考
|
210
215
|
|
211
216
|
- https://github.com/pola-rs/polars
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "0.5.4"
|
@@ -0,0 +1 @@
|
|
1
|
+
from polars_ta.labels.future import * # noqa
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import numpy as np
|
2
|
+
from numba import jit
|
3
|
+
from numpy import full
|
4
|
+
|
5
|
+
|
6
|
+
@jit(nopython=True, nogil=True, cache=True)
|
7
|
+
def _triple_barrier(close: np.ndarray, high: np.ndarray, low: np.ndarray, window: int, take_profit: float, stop_loss: float) -> np.ndarray:
|
8
|
+
"""三重障碍打标法"""
|
9
|
+
out = full(close.shape[0], np.nan, dtype=np.float64)
|
10
|
+
for i in range(close.shape[0] - window + 1):
|
11
|
+
entry_price = close[i]
|
12
|
+
if np.isnan(entry_price):
|
13
|
+
# out[i] = 0
|
14
|
+
continue
|
15
|
+
upper_barrier = entry_price * (1 + take_profit)
|
16
|
+
lower_barrier = entry_price * (1 - stop_loss)
|
17
|
+
for j in range(i + 1, i + window):
|
18
|
+
hit_upper = high[j] >= upper_barrier
|
19
|
+
hit_lower = low[j] <= lower_barrier
|
20
|
+
if hit_upper and hit_lower:
|
21
|
+
# TODO 同一天无法知道是先触发止损还是先触发止盈
|
22
|
+
# 1. 假定离收盘价远的先触发
|
23
|
+
if high[j] - close[j] > close[j] - low[j]:
|
24
|
+
out[i] = 1 # 最高价更远,触发止盈
|
25
|
+
else:
|
26
|
+
out[i] = -1 # 最低价更远,触发止损
|
27
|
+
|
28
|
+
# out[i] = -1 # 2. 简化处理认为先触发止损
|
29
|
+
break
|
30
|
+
if hit_upper:
|
31
|
+
out[i] = 1 # 止盈
|
32
|
+
break
|
33
|
+
if hit_lower:
|
34
|
+
out[i] = -1 # 止损
|
35
|
+
break
|
36
|
+
else:
|
37
|
+
# out[i] = 0 # 1. 时间到了触发平仓
|
38
|
+
out[i] = np.sign(close[j] / entry_price - 1) # 2. 时间到了触发平仓
|
39
|
+
|
40
|
+
return out
|
@@ -0,0 +1,165 @@
|
|
1
|
+
"""
|
2
|
+
|
3
|
+
由于标签的定义比较灵活,所以以下代码主要用于参考
|
4
|
+
|
5
|
+
Notes
|
6
|
+
-----
|
7
|
+
标签都是未来数据,在机器学习中,只能用于`y`,不能用于`X`。
|
8
|
+
|
9
|
+
References
|
10
|
+
----------
|
11
|
+
https://mp.weixin.qq.com/s/XtgYezFsslOfW-QyIMr0VA
|
12
|
+
https://github.com/Rachnog/Advanced-Deep-Trading/blob/master/bars-labels-diff/Labeling.ipynb
|
13
|
+
|
14
|
+
"""
|
15
|
+
from polars import Expr, struct
|
16
|
+
|
17
|
+
from polars_ta.labels._nb import _triple_barrier
|
18
|
+
from polars_ta.utils.numba_ import batches_i2_o1, struct_to_numpy
|
19
|
+
from polars_ta.wq import cut, ts_delay, ts_log_diff, log
|
20
|
+
|
21
|
+
|
22
|
+
def ts_log_return(close: Expr, n: int = 5) -> Expr:
|
23
|
+
"""将未来数据当成卖出价后移到买入价位置,计算对数收益率
|
24
|
+
|
25
|
+
Examples
|
26
|
+
--------
|
27
|
+
```python
|
28
|
+
df = pl.DataFrame({
|
29
|
+
'a': [None, 10, 11, 12, 9, 12, 13],
|
30
|
+
}).with_columns(
|
31
|
+
out1=ts_log_return(pl.col('a'), 3),
|
32
|
+
out2=_ts_log_return(pl.col('a'), 3),
|
33
|
+
)
|
34
|
+
|
35
|
+
shape: (7, 3)
|
36
|
+
┌──────┬───────────┬───────────┐
|
37
|
+
│ a ┆ out1 ┆ out2 │
|
38
|
+
│ --- ┆ --- ┆ --- │
|
39
|
+
│ i64 ┆ f64 ┆ f64 │
|
40
|
+
╞══════╪═══════════╪═══════════╡
|
41
|
+
│ null ┆ null ┆ null │
|
42
|
+
│ 10 ┆ -0.105361 ┆ -0.105361 │
|
43
|
+
│ 11 ┆ 0.087011 ┆ 0.087011 │
|
44
|
+
│ 12 ┆ 0.080043 ┆ 0.080043 │
|
45
|
+
│ 9 ┆ null ┆ null │
|
46
|
+
│ 12 ┆ null ┆ null │
|
47
|
+
│ 13 ┆ null ┆ null │
|
48
|
+
└──────┴───────────┴───────────┘
|
49
|
+
```
|
50
|
+
|
51
|
+
"""
|
52
|
+
# return (close.shift(-n) / close).log()
|
53
|
+
return log(ts_delay(close, -n) / close)
|
54
|
+
|
55
|
+
|
56
|
+
def _ts_log_return(close: Expr, n: int = 5) -> Expr:
|
57
|
+
"""计算对数收益率,但将结果后移
|
58
|
+
|
59
|
+
如果打标签方式复杂,这种最终结果后移的方法更方便
|
60
|
+
"""
|
61
|
+
# return (close / close.shift(n)).log().shift(-n)
|
62
|
+
return ts_delay(ts_log_diff(close, n), -n)
|
63
|
+
|
64
|
+
|
65
|
+
def ts_simple_return(close: Expr, n: int = 5, threshold: float = 0.0, *more_threshold) -> Expr:
|
66
|
+
"""简单收益率标签。支持二分类、三分类等。对收益率使用`cut`进行分类
|
67
|
+
|
68
|
+
Parameters
|
69
|
+
----------
|
70
|
+
close
|
71
|
+
n:int
|
72
|
+
未来n天
|
73
|
+
threshold:float
|
74
|
+
收益率阈值,小于该值为0,大于等于该值为1
|
75
|
+
more_threshold:float
|
76
|
+
更多的阈值,用于三分类等。小于该值为1,大于等于该值为2,以此类推
|
77
|
+
|
78
|
+
Returns
|
79
|
+
-------
|
80
|
+
Expr
|
81
|
+
标签列, 类型为UInt32, 取值为0, 1, 2, ...
|
82
|
+
|
83
|
+
Examples
|
84
|
+
--------
|
85
|
+
```python
|
86
|
+
df = pl.DataFrame({
|
87
|
+
'a': [None, 10., 9.99, 9., 10., 11., 11.],
|
88
|
+
}).with_columns(
|
89
|
+
out1=label_simple_return(pl.col('a'), 1, 0),
|
90
|
+
out2=label_simple_return(pl.col('a'), 1, -0.001, 0.001),
|
91
|
+
)
|
92
|
+
|
93
|
+
shape: (7, 3)
|
94
|
+
┌──────┬──────┬──────┐
|
95
|
+
│ a ┆ out1 ┆ out2 │
|
96
|
+
│ --- ┆ --- ┆ --- │
|
97
|
+
│ f64 ┆ u32 ┆ u32 │
|
98
|
+
╞══════╪══════╪══════╡
|
99
|
+
│ null ┆ null ┆ null │
|
100
|
+
│ 10.0 ┆ 0 ┆ 0 │
|
101
|
+
│ 9.99 ┆ 0 ┆ 0 │
|
102
|
+
│ 9.0 ┆ 1 ┆ 2 │
|
103
|
+
│ 10.0 ┆ 1 ┆ 2 │
|
104
|
+
│ 11.0 ┆ 0 ┆ 1 │
|
105
|
+
│ 11.0 ┆ null ┆ null │
|
106
|
+
└──────┴──────┴──────┘
|
107
|
+
|
108
|
+
"""
|
109
|
+
return cut(close.pct_change(n).shift(-n), threshold, *more_threshold)
|
110
|
+
|
111
|
+
|
112
|
+
def ts_triple_barrier(close: Expr, high: Expr, low: Expr, d: int = 5, take_profit: float = 0.1, stop_loss: float = 0.05) -> Expr:
|
113
|
+
"""三重障碍打标法
|
114
|
+
|
115
|
+
Parameters
|
116
|
+
----------
|
117
|
+
close:Expr
|
118
|
+
收盘价
|
119
|
+
high:Expr
|
120
|
+
最高价
|
121
|
+
low:Expr
|
122
|
+
最低价
|
123
|
+
d:int
|
124
|
+
时间窗口
|
125
|
+
take_profit:float
|
126
|
+
止盈比例
|
127
|
+
stop_loss:float
|
128
|
+
止损比例
|
129
|
+
|
130
|
+
Returns
|
131
|
+
-------
|
132
|
+
Expr
|
133
|
+
标签列。取值为-1止损, 1止盈,0时间到期
|
134
|
+
|
135
|
+
Notes
|
136
|
+
-----
|
137
|
+
1. `high`, `low`在粗略情况下可用`close`代替
|
138
|
+
2. 时间到期时,根据盈亏返回不同的标签
|
139
|
+
|
140
|
+
Examples
|
141
|
+
--------
|
142
|
+
```python
|
143
|
+
df = pl.DataFrame({
|
144
|
+
"close": [np.nan, 1, 1, 1.0],
|
145
|
+
"high": [np.nan, 1, 1.1, 1],
|
146
|
+
"low": [np.nan, 1, 1, 0.95],
|
147
|
+
}).with_columns(
|
148
|
+
out=ts_triple_barrier(pl.col("close"), pl.col("high"), pl.col("low"), 2, 0.1, 0.05)
|
149
|
+
)
|
150
|
+
|
151
|
+
shape: (4, 4)
|
152
|
+
┌───────┬──────┬──────┬──────┐
|
153
|
+
│ close ┆ high ┆ low ┆ out │
|
154
|
+
│ --- ┆ --- ┆ --- ┆ --- │
|
155
|
+
│ f64 ┆ f64 ┆ f64 ┆ f64 │
|
156
|
+
╞═══════╪══════╪══════╪══════╡
|
157
|
+
│ NaN ┆ NaN ┆ NaN ┆ null │
|
158
|
+
│ 1.0 ┆ 1.0 ┆ 1.0 ┆ 1.0 │
|
159
|
+
│ 1.0 ┆ 1.1 ┆ 1.0 ┆ -1.0 │
|
160
|
+
│ 1.0 ┆ 1.0 ┆ 0.95 ┆ null │
|
161
|
+
└───────┴──────┴──────┴──────┘
|
162
|
+
```
|
163
|
+
|
164
|
+
"""
|
165
|
+
return struct([close, high, low]).map_batches(lambda xx: batches_i2_o1(struct_to_numpy(xx, 3), _triple_barrier, d, take_profit, stop_loss))
|
@@ -1,12 +1,6 @@
|
|
1
1
|
from polars import Expr
|
2
2
|
|
3
|
-
from polars_ta.wq.arithmetic import log1p, expm1
|
4
|
-
# log return
|
5
|
-
# 对数收益
|
6
|
-
from polars_ta.wq.time_series import ts_log_diff as ts_log_return # noqa
|
7
|
-
# simple percentage return
|
8
|
-
# 简单收益
|
9
|
-
from polars_ta.wq.time_series import ts_returns as ts_percent_return # noqa
|
3
|
+
from polars_ta.wq.arithmetic import log1p, expm1
|
10
4
|
|
11
5
|
|
12
6
|
def ts_cum_return(close: Expr) -> Expr:
|
@@ -0,0 +1 @@
|
|
1
|
+
from polars_ta.labels import * # noqa
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# polars_ta.ta
|
2
|
+
|
3
|
+
1. Files in this folder mimic `talib`, and implement `polars` versions for the same functions
|
4
|
+
2. Since we reduce the functino calls between `Python` and `C` code, it should be faster than `talib`.
|
5
|
+
3. We first try to import from `ta`, then from `wq`, and only implement the function if it is not available.
|
6
|
+
4. When there is a circular dependency, we use `polars` instead.
|
7
|
+
|
8
|
+
|
9
|
+
1. 本文件夹中模仿`talib`,实现同名函数的`polars`版
|
10
|
+
2. 由于减少了python与c来回调用,理论上比直接调用`talib`快
|
11
|
+
3. 优先从`ta`中导入,然后从`wq`中导入,没有的才实现
|
12
|
+
4. 出现循环依赖时,使用`polars`
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# polars_ta.talib
|
2
|
+
|
3
|
+
Inside this package, files are generated by `tools.codegen_talib2`.
|
4
|
+
It is a wrapper of `talib` functions, with the following features:
|
5
|
+
|
6
|
+
1. Input and output are `Expr` instead of `Series`
|
7
|
+
2. ~~Add skipna feature (not efficient, will update when `polars` support backward fill)~~
|
8
|
+
|
9
|
+
本包由`tools.codegen_talib2`自动生成,是对`talib`代码的封装。实现了以下功能
|
10
|
+
1. 输入输出由`Series`改`Expr`
|
11
|
+
2. ~~添加跳过空值功能(效率不高,等`polars`支持反向填充,此部分将更新)~~
|
12
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# polars_ta.tdx
|
2
|
+
|
3
|
+
1. Follows the `tdx` naming convention
|
4
|
+
2. Except for some element-wise functions, all functions are time-series functions. Pay special attention to `MAX` and similar functions.
|
5
|
+
3. First import from `tdx`, then from `wq`, and finally from `ta`. Only implement the function if it is not available.
|
6
|
+
|
7
|
+
|
8
|
+
1. 函数名称按照通达信来
|
9
|
+
2. 除了部分按元素计算的函数,其它都为时序函数,特别注意`MAX`等一类不要混淆
|
10
|
+
3. 优先从`tdx`中导入,然后从`wq`中导入,最后从`ta`,没有的才实现
|
@@ -27,6 +27,7 @@ def isnan(x):
|
|
27
27
|
|
28
28
|
@jit(nopython=True, nogil=True, cache=True)
|
29
29
|
def full_with_window_size(arr, fill_value, dtype=None, window_size: int = 1):
|
30
|
+
"""创建一个更大的数组,填充后一截数据"""
|
30
31
|
out = full(arr.shape[0] + window_size - 1, fill_value, dtype=dtype)
|
31
32
|
out[window_size - 1:] = arr
|
32
33
|
return out
|
@@ -34,6 +35,7 @@ def full_with_window_size(arr, fill_value, dtype=None, window_size: int = 1):
|
|
34
35
|
|
35
36
|
@jit(nopython=True, nogil=True, cache=True)
|
36
37
|
def sliding_window_with_min_periods(arr, window_size: int, min_periods: int):
|
38
|
+
"""为rolling准备的数据,当数据长度不足时,用nan填充"""
|
37
39
|
windows = sliding_window_view(arr, window_size)
|
38
40
|
valid_counts = np.sum(~np.isnan(windows), axis=1)
|
39
41
|
# 修改这一行,使用布尔索引而不是np.where
|