FLASH策略的实盘实现(基于框架少量改动)
5 _& r1 y8 N9 n& I9 b先贴signal代码:
+ K, ], B5 e4 m8 F4 sdef signal_adapt_bolling_with_flash(df_base, now_pos, avg_price,symbol_config,symbol ):
1 p2 A0 D* f) x$ I$ f holding_times_min=10( d) ^2 c& h# u. f; b
#本地文件名,初始化本地文件" J& d0 s2 U; m7 ^( }0 X2 @( V
para=symbol_config[symbol]['para']
% G% V9 r" v! m# u id=para['id']) O% [8 o6 G+ _ z, z
8 e' S- m3 q; M5 Y7 s file_name=os.path.join(father_path,'data',id+'.csv')
; A, @ w0 C! d, ?" s; v6 E& t ini_data(file_name,dic = {'pre_signal': 0, 'stop_lose_price': None,'holding_times':0,'stop_win_times':0,'stop_win_price':0}): ~! ]- @" X; v$ M1 V
0 U! {$ L ~; Q, t& ^ # ===计算指标# B& ?' d. L1 g$ Y/ D
# w! J1 u9 v: B) Z O2 E n = para['n']
$ F$ K! J2 Z- |9 T
5 u6 C! `+ a! i* q #固定止损参数
6 P- x. {# m" u2 F. S# i3 q df=df_base.copy()
8 Z$ ^6 D8 t/ _ stop_loss_pct=para['stop_loss_pct']3 U& f% R. |( V6 j( o
( Q6 g* s+ m$ K9 L: \$ T# B df['median'] = df['close'].rolling(n).mean(); f$ Y. I2 R1 d8 g2 `' T8 ]7 w+ p# ^6 M
# 计算上轨、下轨道
. v0 }4 x5 f! f% [ K. p df['std'] = df['close'].rolling(n).std(ddof=0) # ddof代表标准差自由度
( T& [: \; W# I& ` df['zscore'] = abs(df['close'] - df['median']) / df['std']4 s4 L: Q/ N8 ?' e7 X) S4 e
df['zsocre_abs'] = df['zscore'].rolling(n).max().shift()3 `/ m# V+ Q+ p! {
6 r' O+ o- r# D3 p. H df['upper'] = df['median'] + df['zsocre_abs'] * df['std']" Z) g5 p3 Y9 G9 p/ Y8 B; V: J" M# n
df['lower'] = df['median'] - df['zsocre_abs'] * df['std']1 _' T$ y# a' @. e8 X- x& R2 I
% v' |) b2 m6 |- ]( {- V& }5 L
& N9 R/ y0 c9 m8 G- Y' W e& ]7 Z/ z# \- ~+ i/ H+ P
, N6 |. ^: y# [, a$ l. A #初始化信号2 v7 |, ]: ], @! X
signal=None
- S2 e% A+ E( f! |3 j; g$ [' H) C
5 r. w) f1 N* o6 j # 做空条件* M% W8 l1 R0 `
condition1=df.iloc[-1]['close']<df.iloc[-1]['lower']
" E- K0 {* T: r4 U* N; O condition2=df.iloc[-2]['close']>df.iloc[-2]['lower']9 P0 ~0 }3 X: m0 F( i6 p
short_condition =condition1 & condition2+ b- M. Y- X$ L0 t" M, U: p& N2 Z$ z$ g4 O
( J! b4 Z# a. S # 做多条件 B. c5 [! ^1 e, F1 s% t
condition1=df.iloc[-1]['close']>df.iloc[-1]['upper']% ?+ s/ ^, Q: l4 [$ l- l- r4 u
condition2=df.iloc[-2]['close']<df.iloc[-2]['upper']
; A' |6 n) g; R long_condition =condition1 & condition2
* q! k3 {* R; Z
/ J: {& E9 ?: i% o1 A# | #平空条件! H, M+ s. ^/ P! v4 V' k) Q- g% V& `
condition1 = df.iloc[-1]['close'] > df.iloc[-1]['median']
: C# L n" ?0 h& x6 c4 N condition2 = df.iloc[-2]['close'] < df.iloc[-2]['median']! ~" i" p$ F% j$ M3 G, F/ ^
close_short_condition = condition1 & condition2) f N: j& I' _0 l' ]' j& S& W
9 Q8 X, w% I( G" e( Q7 | #平多条件( N: V# c0 L. d4 |
condition1 = df.iloc[-1]['close'] < df.iloc[-1]['median']
1 M5 C: {6 V+ P1 T0 A condition2 = df.iloc[-2]['close'] > df.iloc[-2]['median']
' @ h( C$ H: P" S: H close_long_condition = condition1 & condition2, h8 Y; G' P+ g7 U# m+ Q0 V
7 v9 b' w8 Q8 Y' P j5 e
#检查本地文件与实际仓位是否有出入: s" X+ T; J3 p O! ^
# 从本地文件读取当前参数
( l" ~0 @0 \: t \ info_dict = read_data(file_name)7 p1 F3 Q6 R7 m1 Q( C8 p
1 C7 e8 Z- f: _
if now_pos != info_dict['pre_signal']:
' Y' G: a# P8 d2 T- q #如果实际仓位为07 F/ K7 a# ~ y1 r2 K
if now_pos==0:( w5 ?6 f' p* z$ X' s' ] ~: }
info_dict={'pre_signal': 0, 'stop_lose_price': None,'holding_times':0,'stop_win_times':0,'stop_win_price':0}2 J# Z, L- e2 t2 I7 b( T8 K8 S
; y$ |. }6 K! v+ \8 w1 u elif now_pos==1:* [( f" i2 J% |5 I7 W
info_dict={'pre_signal': 1,
" U2 Z; z6 H: Z: a& E% S9 W( [ 'stop_lose_price': (avg_price * (1 - stop_loss_pct / 100)),
; j' _& Q# u! E l 'holding_times':0,'stop_win_times':0,'stop_win_price':0}
; v$ u9 w7 Y- U) h; g# T: [& f; Y9 G9 X% e/ c
elif now_pos==-1:
8 I6 g" u, @2 z4 h w7 w) F2 G info_dict = {'pre_signal': -1,% b% B% D8 K! C$ R
'stop_lose_price': (avg_price * (1 + stop_loss_pct / 100))," V; \' [" G- ~* R: V0 E# Y
'holding_times': 0,
: ^" v! s) H N 'stop_win_times': 0, 'stop_win_price': 0}
9 h$ W- J/ @# S, T# J5 d save_data(info_dict,file_name)
9 m) f2 f& q. u
. L2 I: r4 o# ^' i5 T# ?! V2 k #开始下单逻辑
+ s% j; o( d P, K #做空' z9 h+ E8 B0 y, X4 ]- o$ L* B
if short_condition & (now_pos!=-1): {3 z& H4 m, e
signal = -16 _% d$ U. J0 Y! r3 t: P, G
stop_lose_price=df.iloc[-1]['close'] * (1 + stop_loss_pct / 100)
( U" D$ M8 D& U+ m info_dict = {'pre_signal': -1,
1 m- O. t/ ^9 O3 B 'stop_lose_price': stop_lose_price,6 r# t& \$ z0 I3 g9 U/ }# ]7 H
'holding_times': 0, 'stop_win_times': 0, 'stop_win_price': 0}
) D4 H% ~* d" G- x save_data(info_dict,file_name); {" \1 A! H5 n$ q* Q4 L3 J* H6 b
#做多; @& l. p+ |, [* Z3 k
elif long_condition & (now_pos!=1):
: [- ^+ R0 ^5 Z3 j+ X signal = 1
@* I, B9 Z* H3 m( T" Z0 @/ m stop_lose_price = df.iloc[-1]['close'] * (1 - stop_loss_pct / 100)
9 M* ~0 e9 W/ G( B C info_dict = {'pre_signal': 1,
9 b( D K1 J$ ~; ?! ^3 } 'stop_lose_price': stop_lose_price,
# \# Z2 m/ X/ E4 d7 \( a- v, Z 'holding_times': 0,
& K$ Y7 k! f) x; @9 s _ 'stop_win_times': 0, 'stop_win_price': 0}% j/ v$ I3 D5 n$ r+ d5 R4 U; V
save_data(info_dict,file_name)
0 Q1 b; l1 }7 F! v2 Z4 r5 X( B( T$ V # ===考察是否需要止盈止损; R1 L* N S" ] b" o% c# e4 o
#当前持仓多头时5 b0 s8 { L: C' D3 K% a, m
elif now_pos == 1:7 @1 a7 L. b3 @1 M
# 由持仓次数,决定flash加速均线用哪个ma
( h+ x5 G0 i6 M9 L7 `4 S" t- \8 A holding_times = info_dict['holding_times']
- V: j, s! v2 _' _! z+ p9 e. Z ma_temp = max(n - holding_times, holding_times_min)( Y5 |4 L5 _: u
#更新info_dict的holding_times- G, O5 j9 x% n, D U
info_dict['holding_times'] = holding_times + 19 A" \" g. u0 B4 f+ @8 ]; m- ^
#计算止盈均线
+ |2 v4 W, q$ z% g df_temp=df['close'].rolling(ma_temp,min_periods=1).mean()
: j3 A+ O' C: V2 d6 @) A6 t #提取均线最新值
- k9 a. K, h7 k- O% r2 Q% N+ z flash_stop_win=df_temp.iloc[-1]; ?2 m' l7 P' V* x) s: I6 S
#中线平多- y) t; o* t4 C. g r, X( I1 _7 {
if close_long_condition:# K ]- F+ N5 N5 M, j8 d; O
signal = 0
5 t, P8 O, f5 I5 ?6 i info_dict = {'pre_signal': 0, 'stop_lose_price': None, 'holding_times': 0, 'stop_win_times': 0,' c5 f Y- g% U- e! }2 W3 t$ M
'stop_win_price': 0}" X- p- u: p; ~3 I$ `+ L
& z2 M- i5 B- D* O, k
#固定止损
! c/ K& F' s7 S elif df.iloc[-1]['close'] < (avg_price*(1-stop_loss_pct/100)): #固定止损$ p) J/ K; s* a0 J
signal = 0
- T# l' B# l0 s2 X9 D info_dict = {'pre_signal': 0, 'stop_lose_price': None, 'holding_times': 0, 'stop_win_times': 0,) w' p9 b4 ?2 S
'stop_win_price': 0}
4 D8 ?& D* `5 e Y. V. D0 {2 ^$ s- R! h) X- _/ s5 C+ a
#flash!!6 W: K% k0 D, W r6 n( X/ f
#如果价格到达止盈点
6 T- ]! V' ?5 H$ u0 Y elif df.iloc[-1]['close'] < flash_stop_win:
5 G2 j( h1 C# `$ g. I. r1 i) @& } # 如果价格超过了上一次止盈点价格,说明上方可能还有空间,则重新开始flash加速,
1 o4 n5 T( `+ R7 B7 R! V- O if df.iloc[-1]['close'] > info_dict['stop_win_price'] or info_dict['stop_win_times'] == 0:
/ b! y9 z! N3 [7 G: K9 @3 ?$ L2 } info_dict['stop_win_price'] = df.iloc[-1]['close']
! _, K& {: ~, b' l1 l6 U # 产生的止盈点次数+1# X2 R, G* g) b% o6 F, ~3 n1 L6 U
info_dict['stop_win_times'] = info_dict['stop_win_times'] + 1; h2 r" Y2 ~8 x& q _' A
# flash加速均线的持仓次数清零
- g% o& q) B9 U info_dict['holding_times'] = 0 `0 B- p6 {5 L9 A- v0 J x. l
, y0 v8 `: Z( w5 T3 Y( Z
else:) B6 ], S, m7 |( e7 I: Y
#止盈出场
- Y( \8 |7 m2 q2 W u/ s signal=00 C: r& c$ B/ b5 b9 k' P
info_dict = {'pre_signal': 0, 'stop_lose_price': None, 'holding_times': 0, 'stop_win_times': 0,
" B+ j8 Y5 R+ f$ J& F7 {; [ 'stop_win_price': 0}1 o* N3 q$ k$ K/ F2 ]
# 更新本地文件7 H6 f0 R% ]* P5 _7 `
save_data(info_dict,file_name)7 B1 D' s( e* {* |4 A/ N! ]6 N5 |
# 当前持仓空头时' P4 e( n' \3 I% Y" ]& n/ h, r- [
elif now_pos == -1:" {* U. y: G0 @2 |) j+ j
# 由持仓次数,决定flash加速均线用哪个ma' X% k; J6 ~& H9 A3 M* o6 s
holding_times = info_dict['holding_times']3 Q) U9 b0 ~! c
ma_temp = max(n - holding_times, holding_times_min)4 [ J: V1 G' S ?; P, j
info_dict['holding_times'] = holding_times + 1
6 D, Q6 P5 {# U$ |+ i& _" |" N+ Q1 G2 O1 k. }, a- z
: h7 L9 y0 v6 G6 C
df_temp = df['close'].rolling(ma_temp, min_periods=1).mean()% M7 i4 V1 V3 t2 t. U! @! j% B6 V; ^" K
flash_stop_win = df_temp.iloc[-1]' F( j$ o+ C8 A8 ^6 Z! U& A
if close_short_condition:
; D' l, v R5 ?; I signal = 0# O5 Q& e4 r; L z Q6 l5 J0 p$ E
info_dict = {'pre_signal': 0, 'stop_lose_price': None, 'holding_times': 0, 'stop_win_times': 0,- @ `# K1 \4 E& v' _
'stop_win_price': 0}2 V, }2 r+ ^- T6 w( G& G0 W6 k% F
' m% X! d, ?! `1 p; m# e
elif df.iloc[-1]['close'] > (avg_price*(1+stop_loss_pct/100)):4 F# h$ F$ Y0 [% g5 Q* t
signal = 0 r! I, R- f: F$ ^1 O. {4 J
info_dict = {'pre_signal': 0, 'stop_lose_price': None, 'holding_times': 0, 'stop_win_times': 0,
5 B# r3 ~8 @2 z8 r- f! C; b* Z 'stop_win_price': 0}- b6 L3 N6 z& G2 I+ p' X
#flash!!9 b. [; s* M& Z4 _# c+ r1 w) l
# 如果价格达到止盈点. ^) E9 b) N' W6 d; T
elif df.iloc[-1]['close'] > flash_stop_win:! j0 k4 y, U& m6 s
# 如果价格跌破了上一次止盈点价格,说明下方可能还有空间,则重新开始flash加速,& K% u9 L* _# a- a5 i
if df.iloc[-1]['close'] < info_dict['stop_win_price'] or info_dict['stop_win_times'] == 0:& |, L' \( q6 S( U+ \0 ~$ L
info_dict['stop_win_price'] = df.iloc[-1]['close']9 C% H5 r: G6 z4 u& ^" T6 b8 v
# 产生的止盈点次数+1
; H# a* t& m, p5 _ info_dict['stop_win_times'] = info_dict['stop_win_times'] + 1
9 ^8 Y# _& I% }3 ]4 Y" T # flash加速均线的持仓次数清零
" C8 Q/ [+ v5 p$ }8 A info_dict['holding_times'] = 0& l2 D# y, _1 }% V8 q9 ?
) r" d9 S( T( o
else:
1 u5 Y0 f3 e" ?- d. B+ I1 z signal = 07 a# m% [- [$ @
info_dict = {'pre_signal': 0, 'stop_lose_price': None, 'holding_times': 0, 'stop_win_times': 0,4 ]5 E8 A# W, H# w
'stop_win_price': 0}
: w' H) _! G9 ~ o #更新本地文件
5 Z- p5 w/ r' m$ B3 L5 ` save_data(info_dict,file_name)$ g! _$ f4 x! o7 Q$ ^9 i( D
" d& A0 S4 s& [+ k2 V6 z( ]3 v3 I return signal这是一个自适应布林加上flash的实盘代码。我和刑大的一个不同在于我讲para改成了dict,symbol_config变成了:
- e$ q/ t7 C: |" B'eth-usdt': {'instrument_type': 'SWAP_USDT',
# j) a% d; K, O# F3 J" P 'size': 1,$ Q5 Z D; C9 X1 S' Q% S' d4 Z
'leverage': '1.2',
* }7 \5 k1 p0 y8 V4 K' f/ | 'strategy_name': 'signal_adapt_bolling_with_flash',
0 [" D- u0 V$ N' N) P "para": {'n': 515,'stop_loss_pct': 7}这个样子,然后我在主程序给symbol_config的para里加了个id号,各位可以将7 b& b V0 `9 X) b: j
id=para['id']
* e: I9 g8 o6 e. u/ C" d, o/ E* A& n3 \$ ?3 i C+ h( h1 j$ c) e
file_name=os.path.join(father_path,'data',id+'.csv')这段代码改成自己喜欢的样子。。。随意就好。father_path是一个自动读取当前文件夹上一文件夹的路径,来自于:
! t: W. x/ M% g. I, xtrue_path=os.path.abspath(__file__)#绝对路径& d) m. S9 N) F0 j+ N
9 X1 J# l. J4 ~! Sfather_path=os.path.dirname(os.path.dirname(true_path)) #当前工作目录
: [: L( {8 H) `# H& J6 Nroot_path=os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(true_path)))) #OKEX项目根目录这段代码
3 P* v* [ h, E+ Z! ^7 j最后,这个signal中的书写本地文件和读取来自于以下代码:
4 C: \2 ]3 U0 M% e gimport os
5 c# a9 S3 l6 Mimport pandas as pd, v8 k- x+ @% R" b/ k* }
from datetime import datetime }) z7 d) @& X
/ y* Q3 w6 q5 j' V% V# Y
4 P0 }( e% u. F M X2 t+ O9 ]
def ini_data(file_name,dic = {'stop_open_time': None, 'stop_price': None,'AF':None,'now_pos':0,'highest_after_entry':None,'lowest_after_entry':None}):
: ~. }+ J$ j, g; |* H3 U if os.path.exists(file_name) != True:
6 [+ }0 ]# M' n8 O6 q3 T- z0 I7 b4 n8 C df=pd.DataFrame()
' e! ?' H7 L* H7 u; ]1 ?1 ^3 I
8 q2 i3 D4 ~" `; h5 d8 t& B/ g4 ^% y* q3 A
df=df.append(dic,ignore_index=True)1 n; u+ w# W/ r9 Y- d; e
0 ]1 M8 ~6 }6 v$ w0 W) X
df.to_csv(file_name,index=False)
. y" P0 D, \% Z/ v1 q0 z" }" n( |2 n
0 h1 j3 J! n, Y7 ~* M
def save_data(dic,file_name):* X; o6 F% a2 K2 d
# save to local+ U" q; O- e* V1 P
max_line=20 #CSV文件最大行数$ L7 \( ]- J3 a& k
df=pd.read_csv(file_name): v4 W$ L9 S& T* ^% G" j
if df.shape[0]>max_line:9 o7 L# ]% \" q; {/ [* \
df=df[-max_line:]0 G) U4 W6 a. p+ V
df=df.append(dic,ignore_index=True)/ N" M% j/ M8 l$ f/ S
df.reset_index(drop=True,inplace=True): j- Q* F' ^6 c) c4 t3 f9 | Z
df.to_csv(file_name,index=False)
: ]) V. u, H/ V0 U/ q2 E print("save dict successfully.")
3 j$ ~( y( A4 E! V- L
& s' R) J; ]9 y& I" X! u. W. \def read_data(file_name): l4 A, ]6 ~0 V& G: |5 u
# read from local
( D0 ]+ j$ l' ^; R% l. S, o; m* P% f global dict$ _% P/ c) a- L, q$ g% Y8 x
df=pd.read_csv(file_name)2 {4 Q/ G L; m4 i/ R) b
; M! X4 g) h. ^% ^
df_new=df.iloc[-1]
- Y+ z* @3 X& ^! v. N dict_=dict(df_new)( T. c4 P" E) M, |4 P: n+ L `
7 n+ A" w" @. `2 s% u1 t- R! |, f1 R) E
return dict_" n h: a" \' r1 P" ?* C
就是如此了。。分享这个牛逼策略。 |