九神,何许人也,自己百度。. \- |( I" o9 o. _+ t. i- V
9 C' C* s0 N: [7 S. H
9 r* E; }5 r, B$ C0 ~' A. A! z3 x5 J$ i& v
j% E6 Q0 V; `$ M H* t' S
6月8日修改,李冰大佬推荐调和平均数; e- T9 ^5 q) ] z* j
策略主体内容' F1 N' X$ w1 k0 ~$ ]
import pandas as pd% e4 ]9 R& O# }, m+ o9 V* ^
import numpy as np" K4 m* K3 J+ ^" n( M% s
def jiushen(df, now_pos, para=[]):
, ]3 ~) [) j7 j6 C6 K """
/ V; G# N W' q4 |7 Y* X """, Z7 t& q. }* r1 x; [+ i& G
: u5 ]( j; s, B) a
n = int(para[0])
9 H! F% H# U9 r
4 @0 g9 a3 V$ t, m2 @# U # 比特币至今诞生天数,比特币第一个区块,北京时间2009-1-4
9 E( ]) X' \. j6 T: ?. a' G6 l df['days'] = (pd.to_datetime(df['candle_begin_time_GMT8'].apply(lambda x: x.strftime('%Y-%m-%d'))) - pd.to_datetime($ N/ u/ b- D# t
'2009-1-4')).astype('timedelta64[D]').astype(int)
. d$ a( m4 J+ v# v
; p( R$ ]8 u* L# {" K+ k p # 九神拟合曲线币价数值; Y. Z& x# J8 z+ y* m' o
df['future_price'] = np.power(10, (5.84 * np.log10(df['days']) - 17.01)) # 5.2% p3 x8 m6 q* ]$ T
U1 ~) ?- g! ]3 [1 g& U # 常规n天定投成本数值" i: u: @# B* q
# df['close_mean'] = df['close'].rolling(window=n, min_periods=1).mean()
5 ~! S2 t/ Z5 \ a8 f6 \ # n天定投成本,使用调和平均数
, {! K5 |! f2 P* e: L df['close_1'] = df['close'] ** (-1)
4 C" a) M/ L; ]) v. L- }9 U df['mean'] = (df['close_1'].rolling(window=n, min_periods=1).mean()) ** (-1)
, Z4 H/ x8 G7 J! p: O' z2 a* ?5 s0 ?: z; I% {+ U4 F7 M
# 九神指数的重点,第一个数值:当天比特币价格/n天定投成本数值;第二个数值,当天比特币价格/拟合曲线币价数值。
% w# l+ N; y3 G6 D# U1 d9 J # 这个数值越小,自然就意味着当天的比特币价格越低估。
' a3 k5 a: E3 _ df['jiushen'] = (df['close'] / df['close_mean']) * (df['close'] / df['future_price'])
+ _9 l+ Y& n! s! U
; e" a' k! z" ~0 H+ j: B
I N5 k" ?2 I- g2 M8 c # 九神指数的布林部分,可以另外魔改+ M: p; v! X6 C3 w( r* J
df['mean'] = df['jiushen'].rolling(window=n, min_periods=1).mean()% _6 i0 S1 [0 M$ C! r. h+ N
df['std'] = df['jiushen'].rolling(window=n, min_periods=1).std(ddof=0) # ddof代表标准差自由度/ B, h6 ^6 ]% L* \" Y2 p9 a
df['up'] = df['mean'] + df['std']' G( f6 c9 Q3 f5 w! ?6 z- r
df['dn'] = df['mean'] - df['std']8 C% m7 g& r$ \
$ S- J5 X: r) S, j1 f- e$ H: L/ O jiushen = df.iloc[-1]['jiushen']
" \9 K) `5 Z8 C z0 Y f( v$ u$ D8 R mean = df.iloc[-1]['mean']
" M# T1 k9 G, i% K' \/ x up = df.iloc[-1]['up']
- G3 g8 d& Q$ Y* S dn = df.iloc[-1]['dn']
0 m6 k+ A) @$ G+ x8 M' q8 Z
# a, x! H! T# O p8 Z4 S, W3 B target_pos = None3 f* d' |. h/ d& D
4 |4 s- I8 q5 l' X
# 现在是多头仓位$ v7 n Q* w2 d. M
if now_pos == 1:
/ E0 x6 U# V4 }# g4 @/ q! f if jiushen < dn:0 q6 \+ S$ k1 a F2 {+ n1 w$ i& {
target_pos = -1 e" J2 m- n5 m7 N6 s3 l
elif jiushen < mean:, O8 w; k1 `; t2 c. d
target_pos = 0
% H1 u; t. _/ a9 z2 ? else: V T" g. z9 H% i5 W1 q" X) `
target_pos = 1
! s. r2 m3 L% h # 现在是空头仓位
1 a5 e- A" a2 p2 } elif now_pos == -1:: ~5 ?9 p$ [ X
if jiushen > up:1 Z8 y4 y8 k; t1 ~2 e* x" T1 Q' ]
target_pos = 17 B& ]7 m5 Q4 |/ _' B# `3 O4 |' _
elif jiushen > mean:' J- _! h) b+ T# l6 [
target_pos = 0, R) i* ]7 x7 z% R! K
else:% u- u! E1 N$ u
target_pos = -1
; N# t- S6 L9 v8 g # 现在无仓位
3 c! i! i3 E& \- N5 [- f elif now_pos == 0:
, d1 j! J: S) [0 e- A # 计算是否要开多仓还是开空仓
# {+ S% T* o6 H% N if jiushen > up:
6 G! M* v6 s2 F7 ^; o target_pos = 1
+ n# h7 a P' Q elif jiushen < dn:
, ^1 ~% M6 @0 l. C" _* \$ z& g- [5 M8 Q target_pos = -1
) z8 o; e# b) z7 j! Q else:, v3 A3 V/ k& z4 m( F4 y$ s
target_pos = 0
) @- H! i) a. ]+ x4 u9 f- _9 k # 其他情况报错
' Y' R) X" D, w8 K Z, l else:
. K9 q, u6 G6 v raise ValueError('当前仓位变量now_pos数值只能是1,-1,0,但目前是', now_pos)
( k3 G# A9 R# B, N( z
7 ?6 b2 Y! M. t5 }; k& v! ] return target_pos |