usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】

[复制链接]
查看8609 | 回复0 | 2023-8-7 09:07:15 | 显示全部楼层 |阅读模式
一、引言
$ o. `8 n0 b6 W  V$ o" y( G
# H$ Q/ j- g$ M4 S3 u(1)、希望对其他同学有帮助,顺便希望能有个小葫芦,集齐7个娃2 c& p5 K" H. D' `
(2)、担心自己程序有考虑不周到的地方。比如爆仓风险啥的,毕竟个人的经验认知有限。也希望同学有好的想法能交流者发帖共享出来一起改进 (这是主要的,嘻嘻,有同学优化,改进,或者马力强的能分析历史找出比较优的方案)。一起致富,此贴抛砖引玉。
1 G: z" A* x8 {. P' _% n(3)、下图是我大概半个月的收益( 做空usdt,做多busd,利用杠杠,赚两个品种的费率差 ),因为我资金没全开满,也是每天观察,一点点加的,中间也调仓开开平平,持了好几个币,所以平均持仓大概用了一万二,三左右金额。策略比较粗糙,只是一个大概的开单跟查询框架。
9 {+ y5 g. _/ O5 W效果图7 I' b* z" U! K
8 o: J7 d" ^+ r" e1 h
usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-1.jpg
1 |9 M9 H8 A& L二、程序设置
' n2 e9 X* [! N" Y" G8 d- D8 l1 F- F  D7 l, X
账户先设置成单边模式,和联合保证金模式 ( 联合保证金可以参考上一篇帖子设置 )7 S1 [% D/ [4 B! L) I
(1)、在【utils】文件夹下的【Config.py】里设置账号和钉钉账号,这里钉钉账号我程序里是有两个,大家也可以都填一样的,因为我有专门个钉钉监控所有策略的异常
% u/ Z4 ^/ }* z* U9 u' e  t" x/ S  k- h( D/ B2 z
. Z0 ~' e7 Z% B' s% I9 K
(2)、在【实盘下单】文件夹里的【config.py】配置策略相关参数,【实盘下单】里的所有py程序参数都在这一个文件里配置,参数 "set_lever"是要自己查询两个本位的允许最大杠杠,比如BTCUSDT最大刚刚是50倍,BTCBUSD杠杆是20倍,那就填20,后面程序运行会自动设置' a7 u% A# B& O' V! u8 T" ~$ Q
3 b  o; T  _& r, E# L* N6 g. `
usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-3.jpg , w' x4 Y: |: R
(3) 、【1_实盘下单.py】这里一开始会显示相关的数据,觉得ok了,在最下方输入yes,才会开始开单,程序有一个地方要注意,右上角有显示这个品种最大的持仓价值,我这里没做处理,目前是假设跑BTCUSDT,BTCBUSD,假设BTCUSDT开单了,接着开BTCUSD超过了允许值开不出来,然后程序会结束,这时候需要手动在把BTCUSDT多开的部分平掉。
  f' @- e4 p4 R, f9 o8 N& Q, q

& u, A) k! z( p9 t(4)、【3_实盘监控.py】开单后主要就是开着这个程序,循环监控,这里功能,每到 00:00、8:00、16:00 会显示相关信息,并且如果ADL到达你设置的报警级别,或者仓位不平衡会隔10秒提示,并且仓位不平衡的时候,也会把多出来的一边多出来的部分给平了,目前是这样处理的。okex船队的方法是平掉百分20再开,我担心行情极端的时候会出现平开,又ADL又平开的情况,干脆直接平掉多出来的部分,这里我是一次性平掉的,等到行情稳定了再手动执行程序补。而且具我观察币安的这些合约ALD满级了也很少触发平仓,如果主动平仓再开,多几次成本就高了,个人想法。. e7 t' s/ j8 V9 s5 m

+ J, X) v+ y- n3 Y" q usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-5.jpg
  d8 S2 @9 n. @/ H* g& v& F/ {' j) A
usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-6.jpg 6 m  T& |7 P  e7 ^1 P
0 b2 ~9 Q' o+ S, g4 s: }6 K; p

7 }: {2 B3 E$ \! k# Q(5)还有两个小程序【5_保证金查询.py】,【6_收益查询.py】查看账户情况,用于策略的参考
, X8 H" f# f7 D; G7 W/ x$ I三、主要代码( m4 a" \2 W1 R' i& h8 t
$ s! E/ m* F6 k$ B7 |) m. ~
下单代码6 d. u, w; R) k' X
import utils.Config as Cf
* W( C# B0 l2 B3 A" Wimport utils.gateway.binance_http as ins
$ Y# ?. g# E8 V) z, [! Kimport time
; \( h: U$ v7 F! m, R4 q* Cimport program.usd_busd永续套利.实盘下单.config as cf
2 n& }& k! x# eimport math1 {0 L6 x( ]& q3 v, o
# ===== 初始化
. V$ r: {6 `& z4 c# 创建币安api
& p7 v1 p- Z! [account = Cf.account[cf.username]
' ~! S5 A4 L3 \% o: @  kins = ins.BinanceHttp(key = account['key_0'] ,secret=account['secret_0'] )
3 s, b$ k+ v+ \; H$ {4 e1 y! S% l0 L
# 参数设置
2 N5 y! V& f8 o' W2 Ccoin = cf.coin
0 E4 G: N  S% @" lmoney = cf.money # usdt
! z+ r6 s' t# m6 Nset_lever = cf.set_lever # 设置杠杆
9 v0 d9 i( }4 m: Zsymbol_1 = cf.symbol_1 # 做空
' Y* G4 k$ }2 R" Zsymbol_2 = cf.symbol_2 # 做多$ G/ v# ^2 x0 }, [( ^/ }
execute_amount = cf.execute_amount # 每次建仓usdt的数量。如果是btc的话,得是100的整数倍。其他币种得是10的整数倍。每次数量不要太多,太多会造成价格波动。建议数量在1000-3000之
: K9 {% v& f( S! J3 C3 f5 [5 qmax_execute_num = math.floor(money*set_lever/execute_amount/2)  # 最大建仓次数,需要向下取整这里要改。建仓这些次数之后程序就会停止。
2 n* {) E, s$ O/ I3 Z: {4 [7 S4 |
, T& L) P6 D+ Lprint("开仓次数 : {}".format(max_execute_num))1 F; Q, E+ V( x
print("设置最大杠杆 : ")
" i8 F7 ?6 L1 o# ^( l3 bprint(ins.u_set_leverage(symbol_1,set_lever))
' J3 [- B# U6 {9 Xprint(ins.u_set_leverage(symbol_2,set_lever))* [3 e/ @6 @8 q" N; e
print(). x- d- H3 T: k( \8 e

/ j: }( T5 L: z# k2 c; Fprint("最新资金费率 : ")
7 _, u# L6 m& Xprint(symbol_1 + ": "+ins.u_premiumIndex(symbol_1)["lastFundingRate"])9 f- Y4 Q! y; l
print(symbol_2 + ": "+ins.u_premiumIndex(symbol_2)["lastFundingRate"])# {$ W9 ~3 a: X; ]
print()/ c$ ?" n7 t( M( h
$ Q$ h. {, _8 I
print("合约信息 : 品种 ,价格精度,下单量精度,最小下单u")
) [/ F' C" [( nsymbol_exchange_info = [[i['symbol'],
# F" Q8 X* ?& w3 U                         int(i['filters'][0]['tickSize'][::-1].split("1")[1].find('.')) + 1,
: q- W/ p4 G% k+ I: }+ k; j( }                         int(i["filters"][2]["minQty"][::-1].split("1")[1].find('.')) + 1,% _4 p" d- s. J
                         i["filters"][5]["notional"]]! L6 {' ?, D* K) V2 `+ o( A
                        for i in ins.u_exchange_info()["symbols"] if i['symbol'] in [symbol_1,symbol_2]]8 |. g9 O: r/ U/ q  T
print(symbol_exchange_info,'\n')# 价格下单精度,价格最小下单量精度,最小下单金额4 u/ i1 z/ G/ n& b
print()
& }% a2 B, j& X% ?& z; A
2 {) Q* i/ k+ M% Yswap_buy_price_1 = float(ins.u_depth(symbol_1, limit=5)['bids'][0][0]) # 做空) x9 h* O- q' h  i, @
swap_sell_price_1 = float(ins.u_depth(symbol_2, limit=5)['asks'][0][0]) # 做多
6 e  D% q, l: c7 l- g. _print("{} bids {} , {} asks {} , 价差 {}".format(symbol_1,swap_buy_price_1,symbol_2,swap_sell_price_1,round(swap_buy_price_1/swap_sell_price_1-1,5))); o( ~# U$ n! w2 @9 p; j
* M- D8 p8 y! J$ a, t) |% d
print()
# z( {& O  j0 V4 g5 h* }8 B" qrun = input("注意控制风险,是否继续 y/x :")
/ t$ _3 w% D6 H4 U8 b0 e
9 ?$ {& r5 `5 V2 a4 H) P" L* iif run.lower() == "x":) g1 d4 E# E0 m% d
    print('*' * 20, '程序退出', '*' * 20, '\n')
; I5 l& \, F4 A# e% x2 d7 M9 B* X/ H    exit()
: n: O# \: V$ n$ w+ m5 n' I; F6 v1 S/ c9 \5 [
elif run.lower() == "y":
) i1 k) g! {  S* b# H$ [    print('*' * 20, '【开始运行】', '*' * 20, '\n')
1 q7 z; J5 o( G6 X& t& K% f) V5 }5 H  `0 e6 y8 E
    execute_num = 0
0 V2 ?# U: o2 y4 J1 {! J& a( I4 ?    while True:
# N9 \: ?6 G9 T+ Y( u$ d$ c' d, ?$ n& l; L! e% o% `  ]# b% d" F7 g

! i" z1 @, q# z: l  o5 H4 W        execute_num+=1
7 ~4 R1 ]' U( z8 G. q& h& N        print("*"*50,"【执行{}次】".format(execute_num),"*"*50)4 A" D& E9 Y% y! u% R$ t

5 M. ~7 q. K0 h& Y* W        swap_buy_price_1 = float(ins.u_depth(symbol_1, limit=5)['bids'][0][0])$ G  u( G& L3 N+ e/ n
        swap_sell_price_1 = float(ins.u_depth(symbol_2, limit=5)['asks'][0][0])2 e( H* B9 a2 j8 J7 l9 q
        buy_price_1 = round(swap_buy_price_1*0.98,symbol_exchange_info[0][1])7 o/ J( E3 W, _5 P: D1 e' ?
        sell_price_1 = round(swap_sell_price_1*1.02,symbol_exchange_info[1][1])
& k$ J9 C1 O* P: ?+ u+ H5 i
7 b8 S' G- q8 `3 V$ f9 Z* H        if buy_price_1 > sell_price_1:' r! Z8 j. J  _( h9 b8 o; b
            lot = round(execute_amount/buy_price_1,symbol_exchange_info[0][2])# ?; C& s, Z- l1 k5 ~
        else:' N7 x+ L# V$ Z6 T
            lot = round(execute_amount/sell_price_1,symbol_exchange_info[1][2])
: M4 Z: N, o6 Q4 o- U8 C5 K& |5 g- h' c; U( [
        r = swap_buy_price_1 / swap_sell_price_1 - 1  R9 m, S, O1 Q( m0 |. V0 ^4 J, M
        print( "{} 买一价 {} ,做空 {} , 下单量 {}".format(symbol_1,swap_buy_price_1,buy_price_1,lot))* a( k) K$ E3 V7 s0 g# y$ y3 Q
        print( "{} 卖一价 {} ,做多 {} , 下单量 {}".format(symbol_2,swap_sell_price_1,sell_price_1,lot))2 s7 y& Y5 h1 k2 B. y- c7 b

" Q& K" U% m. n' g        print("开始下单 : ")2 ]$ Z7 B0 C3 ?& [+ b5 [5 k
        symbol_1_order_info = ins.u_order_send(symbol_1,"SELL","LIMIT",quantity = lot ,price = buy_price_1,timeIn_force="GTC")
: |9 K  @: |- g: _2 M) [, q  K        symbol_2_order_info = ins.u_order_send(symbol_2, "BUY", "LIMIT", quantity=lot, price=sell_price_1,timeIn_force="GTC")
1 @6 X$ M8 t  T* p        print(symbol_1_order_info), [" x/ ~! r; ]# s
        print(symbol_2_order_info)
6 A# T: U/ E3 ?$ Y* n, H. S% H1 C3 _5 a* H. W( Q
        if ("code" in symbol_1_order_info) | ("code" in symbol_2_order_info):# t" p) p" Y9 Z9 B- @% `% a
            print("下单出错停止")
& U: k1 ?# E0 Q+ i: z' G            break
; D: {( T' h( X9 ~0 A' @/ ]8 `8 h% q  S+ ~0 j
        time.sleep(5)3 ~7 k6 d6 Q( X9 j
        print()
% p6 m/ M+ G) ?4 V& ^( T* D( V7 M' ?: p% j% \6 B2 _
        if execute_num >= max_execute_num:
, `0 v$ G* A# Y9 B# M8 d2 o7 r            print('达到最大下单次数,完成建仓计划,退出程序')
" A: ~) N# C6 _' V" T# O            Break监控代码& n' g2 j6 Z- V/ |2 X! L0 Z( X
print("\n"+text)
% X; ^4 f5 s* x6 U* `6 ^        text = " 警报! adl风险 : " + "\n" + str(adl) + "\n"3 |: R+ o+ f& t/ [! V' u
        dingtalk_alert.send_dingding_msg(alert_text + text)
- R- t% U7 H) m  M* z/ x: f. C. V# x9 H# X8 ]; d& r/ z7 @
    # 2.检测手数是否平衡,异常报警,平掉多余手数+ x% I2 z+ A2 ]+ P! V
    check_pos = check.pos()
, G1 }: M" g" Z3 J    df_pos = check_pos[0]   # 原始仓位: M& ]/ T- O1 g  q" y9 D: I: a6 r" K
    coin_pos = check_pos[1] # 多空抵消后的币的仓位! i  K# l7 q! |+ B

  `8 E8 Q/ F" h2 X5 i    coin_pos = coin_pos[coin_pos['open_pos'] != 0], d2 c2 P: Z1 C. m( B7 `5 C8 L
    if len(coin_pos) > 0:
2 w2 ~( w3 r. P3 E0 U  p5 Q% H: W# a9 S) [  z
        symbol_order_info = check.close_pos(coin_pos)
& M2 Y3 h  L5 Z% [, P# L% B. n- A  {. X1 z8 ~  R9 k
        text = " 警报!仓位异常 : "+"\n"+str(coin_pos.to_markdown())+"\n"+"平仓信息 : " +"\n"+str(symbol_order_info)
% ~. f( u2 Y  i        print(text)
+ B! W! y# ~$ g/ t        text = " 警报!仓位异常 : "+"\n"+str(coin_pos)+"\n"+"平仓信息 : " +"\n\n"+str(symbol_order_info)
0 f* z: \' b1 p7 Z# i* l        dingtalk_alert.send_dingding_msg(alert_text + text + str(symbol_order_info))
4 S6 K( t$ j8 E" B& _/ Q% {; b/ N
    # 3.账户风险,检测资金流水,本期到期资金费率' G% B9 L5 [1 h% d  ^5 T2 V# ]6 _% T4 Z
    now_time = pd.to_datetime(now_time)
: H9 E- E& v7 [, a    account_risk = check.account_risk()* U& `9 Z6 \$ E6 A- ]* y2 n
    maint_margin = account_risk[0]. [# s% P. |1 }9 N, \) X; g
    margin_balance = account_risk[1]
3 @( {6 q# F+ v! k/ ~& o    risk_rate = round(float(account_risk[2] * 100),2)
+ h0 k; o+ @5 G" ^
: b/ V- j& O  N! a% W2 i    if risk_rate > set_risk_rate:
: t2 M0 x$ X. `- h1 {: j        text = " 警报!账户风险率 : {}%".format(risk_rate), F. d& a7 d# t+ f% `  P3 X
        print(text)
, K' j  _% I( O        dingtalk_alert.send_dingding_msg(alert_text +text)
- e7 {& i; c% K! _. _% E) H4 i+ S9 u( ^% b
    # 资金费率发生后一分钟显示数据3 A& L- l  g) Y2 F
    if now_time.hour % 8 == 0 and now_time.minute == 1:
: @8 B1 ~* ]4 b: R4 R' A4 p8 d. d9 C
        text = "\n"+"【账户风险】 :"+"\n"+\
' u1 x2 ]! _& n, o/ O. A. i               "维持保证金 : {}USD".format(round(maint_margin,2))+"\n"+\, ~+ v6 b* @' S' k+ O8 N( {6 U
               "账户权益 : {}USD".format(round(margin_balance,2))+"\n"+\! B3 k% u0 T- w2 \3 [) y+ u' |
               "账户风险率 : {}%".format(risk_rate)+"\n"+" "+"\n"+\- E- |; m+ n& A. U# o: v- a
               "【资金费率差】 :" +"\n"+str(check.last_funding_rate())+"\n"+" "+"\n"+\5 T* [- _3 B# X5 t2 M3 n$ y* M7 z3 z
               "【币种收益】 : "+"\n"+str(check.income()) + '\n'+" "
  l7 R& p) G3 b' t$ V  f0 `- L- H# [0 x  e/ f6 a+ W
        dingtalk.send_dingding_msg(text)+ \  e1 P+ x' l
        print(text)
* R3 ]2 R, Z$ A0 t: f! U: H9 n- B
" `* L/ X( b2 w0 \1 t! M        # 休眠60秒这样就只会报警一次了, k3 e- t( @- y: g2 D5 u$ _. g
        time.sleep(60). m5 r. I' d7 B, e9 t

3 i2 l) S4 `& c: J& n- E    print()% p- A7 W1 w# g8 f: W
    time.sleep(sleeptime)$ f0 \9 `/ H% g
  O8 i$ `4 j" R2 l

2 ?7 ?  V. c& M! ~if __name__ == '__main__':
9 W4 |& Y: k! B: s) b* K; o/ y% i2 X. e) y/ [

5 ^* p2 Y) _( M- q1 U* F" }    while True:
( I. ~1 J( k5 q8 r9 }% v. l4 b$ [$ \3 Y0 ]' a
        try:
: ]# L4 O$ Y% K            main(ins,dingtalk_alert,dingtalk,alert_text)
) b: F/ m8 ^) t5 Y        except Exception as e:
% H+ P# y* X8 s) v) V            print("程序报错")
6 Z8 z' u' O6 B6 z2 a9 ]5 l' U1 X            dingtalk_alert.send_dingding_msg(alert_text + "程序报错 :" + str(e))5 n+ x( `# B+ |: y- C
            time.sleep(10)' O( S& ^1 Q) a$ E
三、其他
' H5 c3 V; ?  o  I3 X, h+ A5 B0 c, j) g; O# u- M
我这里没写平仓,大家开单反过来写下就行了,另外跑的时间很短,这几天大部分币资金费率差开始变成负的了( 策略是否要加入自动平仓功能,比如平均多少天的资金费率转负了平仓,转正了再开?),亏了两天,具体策略的情况还需要长期观察。另外usdt之前暴雷过,如果再次发生暴雷,或者busd/usdt价格偏离很大,会发生爆仓。- V8 J6 ~. e. q6 }' h! @$ i& Z+ p
先这样吧,觉得有帮助的话多多点赞
+ N$ x, U* V5 V+ N9 w5 p7 J代码附件:% Z* N: D) h( Z

1 |/ P2 Q/ l! M& G# N$ z$ s( k7 M
usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-8.jpg
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

265

金钱

0

收听

0

听众
性别
保密

新手上路

金钱
265 元