Skip to content

Commit

Permalink
test mkdocs 5
Browse files Browse the repository at this point in the history
  • Loading branch information
wukan1986 committed Dec 3, 2024
1 parent 2b000a5 commit 8c22a3f
Show file tree
Hide file tree
Showing 9 changed files with 310 additions and 33 deletions.
15 changes: 13 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
# polars_ta

尽量接近`WorldQuant Alpha101`风格,但部分又做了一定的调整
尽量接近`WorldQuant Alpha101`风格函数,但部分又做了一定的调整

例如:

1. x.abs().log()
- 可利用`IDE`的自动补全,输入方便
- 默认是一个输入,多输入要通过参数列表。输入不统一
2. log(abs_(x))
- 都是通过参数列表,输入统一
- 一层套一层,正好对应表达式树,直接可用于遗传规划
- `abs``python`内置函数冲突,使用`abs_`代替,同样还有`and_``int_``max_`

## References

https://platform.worldquantbrain.com/learn/operators/operators
- https://platform.worldquantbrain.com/learn/operators/operators
- https://github.com/TA-Lib/ta-lib
41 changes: 41 additions & 0 deletions polars_ta/ta/momentum.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
"""
```python
```
"""
from polars import Expr

from polars_ta import TA_EPSILON
Expand Down Expand Up @@ -77,6 +83,13 @@ def MACD_macdsignal(close: Expr, fastperiod: int = 12, slowperiod: int = 26, sig


def MOM(close: Expr, timeperiod: int = 10) -> Expr:
"""MOM = (price - prevPrice) [Momentum]
References
----------
https://github.com/TA-Lib/ta-lib/blob/main/src/ta_func/ta_MOM.c#L200
"""
return ts_delta(close, timeperiod)


Expand All @@ -88,18 +101,46 @@ def PPO(close: Expr, fastperiod: int = 12, slowperiod: int = 26, matype: int = 0


def ROC(close: Expr, timeperiod: int = 10) -> Expr:
"""ROC = ((price/prevPrice)-1)*100 [Rate of change]
References
----------
https://github.com/TA-Lib/ta-lib/blob/main/src/ta_func/ta_ROC.c#L200
"""
return ROCP(close, timeperiod) * 100


def ROCP(close: Expr, timeperiod: int = 10) -> Expr:
"""ROCP = (price-prevPrice)/prevPrice [Rate of change Percentage]
References
----------
https://github.com/TA-Lib/ta-lib/blob/main/src/ta_func/ta_ROCP.c#L202
"""
return ts_returns(close, timeperiod)


def ROCR(close: Expr, timeperiod: int = 10) -> Expr:
"""ROCR = (price/prevPrice) [Rate of change ratio]
References
----------
https://github.com/TA-Lib/ta-lib/blob/main/src/ta_func/ta_ROCR.c#L203
"""
return close / close.shift(timeperiod)


def ROCR100(close: Expr, timeperiod: int = 10) -> Expr:
"""ROCR100 = (price/prevPrice)*100 [Rate of change ratio 100 Scale]
References
----------
https://github.com/TA-Lib/ta-lib/blob/main/src/ta_func/ta_ROCR100.c#L203
"""
return ROCR(close, timeperiod) * 100


Expand Down
4 changes: 4 additions & 0 deletions polars_ta/ta/price.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@


def AVGPRICE(open: Expr, high: Expr, low: Expr, close: Expr) -> Expr:
"""(open + high + low + close) / 4"""
return (open + high + low + close) / 4


def MEDPRICE(high: Expr, low: Expr) -> Expr:
"""(high + low) / 2"""
return (high + low) / 2


def TYPPRICE(high: Expr, low: Expr, close: Expr) -> Expr:
"""(high + low + close) / 3"""
return (high + low + close) / 3


def WCLPRICE(high: Expr, low: Expr, close: Expr) -> Expr:
"""(high + low + close * 2) / 4"""
return (high + low + close * 2) / 4
8 changes: 4 additions & 4 deletions polars_ta/wq/arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,8 @@ def s_log_1p(x: Expr) -> Expr:
-----
从`wq`示例可以看出,log的底数是10,而不是e
Reference
---------
References
----------
https://platform.worldquantbrain.com/learn/operators/detailed-operator-descriptions#s_log_1px
"""
Expand All @@ -357,8 +357,8 @@ def signed_power(x: Expr, y: Expr) -> Expr:
"""x raised to the power of y such that final result preserves sign of x.
Reference
---------
References
----------
https://platform.worldquantbrain.com/learn/operators/detailed-operator-descriptions#signed_powerx-y
"""
Expand Down
143 changes: 125 additions & 18 deletions polars_ta/wq/cross_sectional.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
"""
与`WorldQuant Alpha101`的区别是添加了`cs_`前缀
由于截面与时序的使用方式不同,在自动化工具中如果不在名字上做区分就得手工注册,反而要麻烦些
"""

import polars_ols as pls
from polars import Expr, when
from polars_ols import OLSKwargs
Expand All @@ -12,11 +19,39 @@

def cs_one_side(x: Expr, is_long: bool = True) -> Expr:
"""Shifts all instruments up or down so that the Alpha becomes long-only or short-only
(if side = short), respectively."""
# TODO: 这里不确定,需再研究
# [-1, 0, 1]+1=[0, 1, 2]
# max([-1, 0, 1], 0)=[0,0,1]
raise
(if side = short), respectively.
Examples
--------
```python
df = pl.DataFrame({
'a': [None, -15, -7, 0, 20],
'b': [None, 15, 7, 0, 20],
}).with_columns(
out1=cs_one_side(pl.col('a'), True),
out2=cs_one_side(pl.col('a'), False),
out3=cs_one_side(pl.col('b'), True),
out4=cs_one_side(pl.col('b'), False),
)
shape: (5, 6)
┌──────┬──────┬──────┬──────┬──────┬──────┐
│ a ┆ b ┆ out1 ┆ out2 ┆ out3 ┆ out4 │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 ┆ i64 ┆ i64 │
╞══════╪══════╪══════╪══════╪══════╪══════╡
│ null ┆ null ┆ null ┆ null ┆ null ┆ null │
│ -15 ┆ 15 ┆ 0 ┆ -35 ┆ 15 ┆ -5 │
│ -7 ┆ 7 ┆ 8 ┆ -27 ┆ 7 ┆ -13 │
│ 0 ┆ 0 ┆ 15 ┆ -20 ┆ 0 ┆ -20 │
│ 20 ┆ 20 ┆ 35 ┆ 0 ┆ 20 ┆ 0 │
└──────┴──────┴──────┴──────┴──────┴──────┘
```
"""
if is_long:
return when(x.min() < 0).then(x - x.min()).otherwise(x)
else:
return when(x.max() > 0).then(x - x.max()).otherwise(x)


def cs_rank(x: Expr, pct: bool = True) -> Expr:
Expand All @@ -26,7 +61,7 @@ def cs_rank(x: Expr, pct: bool = True) -> Expr:
----------
x
pct
* True: 排名百分比。范围:(0,1]
* True: 排名百分比。范围:[0,1]
* False: 排名。范围:[1,+inf)
Examples
Expand All @@ -47,33 +82,105 @@ def cs_rank(x: Expr, pct: bool = True) -> Expr:
│ i64 ┆ f64 ┆ u32 │
╞══════╪══════════╪══════╡
│ null ┆ null ┆ null │
│ 1 ┆ 0.142857 ┆ 1 │
│ 1 ┆ 0.142857 ┆ 1 │
│ 1 ┆ 0.142857 ┆ 1 │
│ 2 ┆ 0.571429 ┆ 4 │
│ 2 ┆ 0.571429 ┆ 4 │
│ 3 ┆ 0.857143 ┆ 6 │
│ 1 ┆ 0.0 ┆ 1 │
│ 1 ┆ 0.0 ┆ 1 │
│ 1 ┆ 0.0 ┆ 1 │
│ 2 ┆ 0.5 ┆ 4 │
│ 2 ┆ 0.5 ┆ 4 │
│ 3 ┆ 0.833333 ┆ 6 │
│ 10 ┆ 1.0 ┆ 7 │
└──────┴──────────┴──────┘
```
References
----------
https://platform.worldquantbrain.com/learn/operators/detailed-operator-descriptions#rankx-rate2
"""
if pct:
return x.rank(method='min') / x.count()
# (x-x.min)/(x.max-x.min)
r = x.rank(method='min') - 1
return r / r.max()
else:
return x.rank(method='min')


def cs_scale(x: Expr, scale_: float = 1, long_scale: float = 1, short_scale: float = 1) -> Expr:
"""Scales input to booksize. We can also scale the long positions and short positions to separate scales by mentioning additional parameters to the operator."""
"""Scales input to booksize. We can also scale the long positions and short positions to separate scales by mentioning additional parameters to the operator.
Examples
--------
```python
df = pl.DataFrame({
'a': [None, -15, -7, 0, 20],
}).with_columns(
out1=cs_scale(pl.col('a'), 1),
out2=cs_scale(pl.col('a'), 1, 2, 3),
)
shape: (5, 3)
┌──────┬───────────┬───────────┐
│ a ┆ out1 ┆ out2 │
│ --- ┆ --- ┆ --- │
│ i64 ┆ f64 ┆ f64 │
╞══════╪═══════════╪═══════════╡
│ null ┆ null ┆ null │
│ -15 ┆ -0.357143 ┆ -2.045455 │
│ -7 ┆ -0.166667 ┆ -0.954545 │
│ 0 ┆ 0.0 ┆ 0.0 │
│ 20 ┆ 0.47619 ┆ 2.0 │
└──────┴───────────┴───────────┘
```
References
----------
https://platform.worldquantbrain.com/learn/operators/detailed-operator-descriptions#scale-x-scale1-longscale1-shortscale1
"""
if long_scale != 1 or short_scale != 1:
L = x.clip(lower_bound=0) # 全正数
S = x.clip(upper_bound=0) # 全负数,和还是负数
return L / L.sum() * long_scale - S / S.sum() * short_scale
S = x.clip(upper_bound=0) # 全负数
L = when(L.sum() == 0).then(0).otherwise(L / L.sum())
S = when(S.sum() == 0).then(0).otherwise(S / S.sum()) # 负数/负数=正数
return L * long_scale - S * short_scale
else:
return x / x.abs().sum() * scale_


def cs_scale_down(x: Expr, constant: int = 0) -> Expr:
"""Scales all values in each day proportionately between 0 and 1 such that minimum value maps to 0 and maximum value maps to 1.
constant is the offset by which final result is subtracted
Examples
--------
```python
df = pl.DataFrame({
'a': [None, 15, 7, 0, 20],
}).with_columns(
out1=cs_scale_down(pl.col('a'), 0),
out2=cs_scale_down(pl.col('a'), 1),
)
shape: (5, 3)
┌──────┬──────┬───────┐
│ a ┆ out1 ┆ out2 │
│ --- ┆ --- ┆ --- │
│ i64 ┆ f64 ┆ f64 │
╞══════╪══════╪═══════╡
│ null ┆ null ┆ null │
│ 15 ┆ 0.75 ┆ -0.25 │
│ 7 ┆ 0.35 ┆ -0.65 │
│ 0 ┆ 0.0 ┆ -1.0 │
│ 20 ┆ 1.0 ┆ 0.0 │
└──────┴──────┴───────┘
```
References
----------
https://platform.worldquantbrain.com/learn/operators/detailed-operator-descriptions#scale_downxconstant0
"""
return (x - x.min()) / (x.max() - x.min()) - constant


def cs_truncate(x: Expr, max_percent: float = 0.01) -> Expr:
"""Operator truncates all values of x to maxPercent. Here, maxPercent is in decimal notation
Expand All @@ -98,8 +205,8 @@ def cs_truncate(x: Expr, max_percent: float = 0.01) -> Expr:
└─────┴─────┘
```
Reference
---------
References
----------
https://platform.worldquantbrain.com/learn/operators/detailed-operator-descriptions#truncatexmaxpercent001
"""
Expand Down
5 changes: 5 additions & 0 deletions polars_ta/wq/logical.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ def negate(input1: Expr) -> Expr:
return ~input1


def not_(input1: Expr) -> Expr:
"""The result is true if the converted operand is false; the result is false if the converted operand is true"""
return ~input1


def or_(a: Expr, b: Expr, *args) -> Expr:
"""Logical OR operator returns true if either or both inputs are true and returns false otherwise"""
return any_horizontal(a, b, *args)
Expand Down
1 change: 1 addition & 0 deletions polars_ta/wq/preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def cs_demean(x: Expr) -> Expr:
-----
速度没有多元回归快,因为这里需要按日期行业groupby,
而多元回归只要添加行业哑变量,然后按日期groupby即可
"""
return x - x.mean()

Expand Down
Loading

0 comments on commit 8c22a3f

Please sign in to comment.