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

[复制链接]
查看8557 | 回复0 | 2023-8-7 09:07:15 | 显示全部楼层 |阅读模式
一、引言
; L! K# ]" D+ t% U" u2 G. G2 r9 n4 [  i5 t' q+ u
(1)、希望对其他同学有帮助,顺便希望能有个小葫芦,集齐7个娃6 p' p0 Z; @; K5 N. z, o+ G& R' ~
(2)、担心自己程序有考虑不周到的地方。比如爆仓风险啥的,毕竟个人的经验认知有限。也希望同学有好的想法能交流者发帖共享出来一起改进 (这是主要的,嘻嘻,有同学优化,改进,或者马力强的能分析历史找出比较优的方案)。一起致富,此贴抛砖引玉。3 F% n% u! P! t/ Q
(3)、下图是我大概半个月的收益( 做空usdt,做多busd,利用杠杠,赚两个品种的费率差 ),因为我资金没全开满,也是每天观察,一点点加的,中间也调仓开开平平,持了好几个币,所以平均持仓大概用了一万二,三左右金额。策略比较粗糙,只是一个大概的开单跟查询框架。
* F' r% m4 P/ p效果图
5 D; e) _, K' |
+ |' ~! ]0 A; |: N usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-1.jpg 2 \' ~. a8 F  C5 U
二、程序设置
; `+ H$ k; o4 Q4 L& ~1 Q9 k0 V1 s& b  T" o. |' K" \
账户先设置成单边模式,和联合保证金模式 ( 联合保证金可以参考上一篇帖子设置 )
" ^3 J. H$ z; L. f% w  O(1)、在【utils】文件夹下的【Config.py】里设置账号和钉钉账号,这里钉钉账号我程序里是有两个,大家也可以都填一样的,因为我有专门个钉钉监控所有策略的异常
% Q+ `) ?+ L/ [6 O) w: |" C; v
/ @# c# t8 @: {0 V5 C, {
% ]' _8 f8 d* {  O* _(2)、在【实盘下单】文件夹里的【config.py】配置策略相关参数,【实盘下单】里的所有py程序参数都在这一个文件里配置,参数 "set_lever"是要自己查询两个本位的允许最大杠杠,比如BTCUSDT最大刚刚是50倍,BTCBUSD杠杆是20倍,那就填20,后面程序运行会自动设置
! c% Z- h7 a! N% ]
! C8 e6 A. _5 a1 s( I9 C usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-3.jpg ) i  o% A1 C5 B0 w% p: }
(3) 、【1_实盘下单.py】这里一开始会显示相关的数据,觉得ok了,在最下方输入yes,才会开始开单,程序有一个地方要注意,右上角有显示这个品种最大的持仓价值,我这里没做处理,目前是假设跑BTCUSDT,BTCBUSD,假设BTCUSDT开单了,接着开BTCUSD超过了允许值开不出来,然后程序会结束,这时候需要手动在把BTCUSDT多开的部分平掉。
  y3 e4 ~5 v4 w  _% |+ k! |! j
: o+ W$ |  m) A
6 w! H3 G" K# l* i(4)、【3_实盘监控.py】开单后主要就是开着这个程序,循环监控,这里功能,每到 00:00、8:00、16:00 会显示相关信息,并且如果ADL到达你设置的报警级别,或者仓位不平衡会隔10秒提示,并且仓位不平衡的时候,也会把多出来的一边多出来的部分给平了,目前是这样处理的。okex船队的方法是平掉百分20再开,我担心行情极端的时候会出现平开,又ADL又平开的情况,干脆直接平掉多出来的部分,这里我是一次性平掉的,等到行情稳定了再手动执行程序补。而且具我观察币安的这些合约ALD满级了也很少触发平仓,如果主动平仓再开,多几次成本就高了,个人想法。9 |4 K6 `' f1 T3 f9 |8 R5 Q
+ A- T" Y  E0 i7 J0 ?) z  y6 D2 V
usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-5.jpg 8 g2 S5 _5 I8 O  v1 I& q' O

( [1 \, L6 W/ f5 q usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-6.jpg
% y! h7 x; b2 _3 f" t( s. |4 U) z/ U0 q# P# J2 g
" A  t# t% K6 |" X( }
(5)还有两个小程序【5_保证金查询.py】,【6_收益查询.py】查看账户情况,用于策略的参考
+ k1 ^, N, n/ L& N, e9 t2 M8 A7 p三、主要代码
9 G% B! s5 m1 j: Z+ f! w/ n1 l9 @# L
5 k0 y4 C  O0 e) B' b2 k下单代码
7 H$ j! v' h# _3 s  D' Bimport utils.Config as Cf
% i' c' |( u1 m: ?) Wimport utils.gateway.binance_http as ins/ n  P0 w" U# z# p- [
import time
# w3 J) s7 f" E, U) m# O2 kimport program.usd_busd永续套利.实盘下单.config as cf# Q% r2 I7 o, \/ v( V2 L9 V; D: C
import math
1 @, Z7 r* N& f, `) q# ===== 初始化2 b! ]/ c2 D- h% N5 B
# 创建币安api
. [" j6 p* T! }! a1 Z2 S& P* uaccount = Cf.account[cf.username]+ R) h+ I( P) i+ G
ins = ins.BinanceHttp(key = account['key_0'] ,secret=account['secret_0'] )& D8 j5 y# y0 M  R- }

, Y* m4 H# v0 l6 `, d1 \# 参数设置  N) D/ |0 ?, ~
coin = cf.coin. a* z1 V5 A  e9 K9 N
money = cf.money # usdt. O  V+ ^4 X+ ?3 s* Y
set_lever = cf.set_lever # 设置杠杆0 I6 [2 u4 D8 ?4 O$ k: {& q& q
symbol_1 = cf.symbol_1 # 做空. f! D# i1 ]  C
symbol_2 = cf.symbol_2 # 做多
& Y9 w. [; d3 y" G- pexecute_amount = cf.execute_amount # 每次建仓usdt的数量。如果是btc的话,得是100的整数倍。其他币种得是10的整数倍。每次数量不要太多,太多会造成价格波动。建议数量在1000-3000之
# [7 I* U8 s/ c& l6 mmax_execute_num = math.floor(money*set_lever/execute_amount/2)  # 最大建仓次数,需要向下取整这里要改。建仓这些次数之后程序就会停止。7 }+ k0 F5 t! {7 j  h

* L, \0 @* z" Z9 {1 ?* jprint("开仓次数 : {}".format(max_execute_num))
* R' w, _/ M3 V2 V9 i. g, @print("设置最大杠杆 : ")
% x; X5 G, b: q1 Cprint(ins.u_set_leverage(symbol_1,set_lever))
8 z+ ^& |3 {6 c+ B$ i$ v3 Tprint(ins.u_set_leverage(symbol_2,set_lever))
; s& z, Q9 h- {, nprint()* m' X* y! \; `0 Z8 ?
, Q: H% v) [  y; ^/ O/ Q
print("最新资金费率 : ")* x, M8 s# y  `# y  W2 Y( O$ q5 j% `
print(symbol_1 + ": "+ins.u_premiumIndex(symbol_1)["lastFundingRate"])
; C8 u* j  g  \- e9 yprint(symbol_2 + ": "+ins.u_premiumIndex(symbol_2)["lastFundingRate"])
2 j4 r& D8 C2 m( n0 bprint()
' P5 `; J1 c2 [/ I/ t+ P! @  y$ \) A% a: f: g
print("合约信息 : 品种 ,价格精度,下单量精度,最小下单u")
& ~5 E/ o; B& d0 J% ksymbol_exchange_info = [[i['symbol'],
: B7 q$ ~4 x  x/ t( i* T                         int(i['filters'][0]['tickSize'][::-1].split("1")[1].find('.')) + 1,
& c* \* \$ H" D* }                         int(i["filters"][2]["minQty"][::-1].split("1")[1].find('.')) + 1,, ]4 ]* e+ D, k: b
                         i["filters"][5]["notional"]]
- p& Y8 n, }5 E" I' _( _3 M+ J( b                        for i in ins.u_exchange_info()["symbols"] if i['symbol'] in [symbol_1,symbol_2]]
$ b3 C( j) D+ n/ C) u# H  _: y& @5 Iprint(symbol_exchange_info,'\n')# 价格下单精度,价格最小下单量精度,最小下单金额
  N" v) j$ f% t& q+ Vprint()! n1 T  T7 b& U7 I
7 P, M" N+ c5 ?6 ~, `. C
swap_buy_price_1 = float(ins.u_depth(symbol_1, limit=5)['bids'][0][0]) # 做空$ Z, T/ X  E) u5 v9 l- z5 B
swap_sell_price_1 = float(ins.u_depth(symbol_2, limit=5)['asks'][0][0]) # 做多% Z- }8 n- I5 k2 B7 p' ]
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)))% x2 f9 N, V- T+ H
( O: I  V5 M4 _7 B; V( L7 I
print()2 f2 `. O( G6 m: W4 D. q& e
run = input("注意控制风险,是否继续 y/x :")
( ~, e) J$ u! k  J
; p" S  A1 ~+ m: \& Tif run.lower() == "x":
' W9 \) e( R( D2 O9 Q" j+ W0 d, l; [    print('*' * 20, '程序退出', '*' * 20, '\n')8 ~; z1 w3 p8 w% w* p7 {
    exit()" u' ~" y$ n& u1 k: l  w5 I1 q9 Q
0 @, J0 D) p; ^1 q+ t- e/ [
elif run.lower() == "y":; @1 u) a5 B8 L( o: b8 s9 y1 M, G
    print('*' * 20, '【开始运行】', '*' * 20, '\n')
+ C' G, d/ i: Z0 \7 e, L3 S% O
2 Y. M: J$ Z2 P, p3 c& G    execute_num = 0
3 e7 d& R" I; |" f4 `4 H! n( Q- S4 J    while True:: b) f2 |! U3 q

' D6 C" u& k: b8 ^( U
" n3 w. C& n/ v& \8 P( D. Y        execute_num+=1
/ P- h& W. u4 j, y        print("*"*50,"【执行{}次】".format(execute_num),"*"*50)+ h. D7 b* I8 b% |
: m, P- X" A% B4 W& l# H6 r
        swap_buy_price_1 = float(ins.u_depth(symbol_1, limit=5)['bids'][0][0])$ O& V# d; @! x% i0 j; J
        swap_sell_price_1 = float(ins.u_depth(symbol_2, limit=5)['asks'][0][0])2 \) \3 B7 _0 e! u8 n
        buy_price_1 = round(swap_buy_price_1*0.98,symbol_exchange_info[0][1])5 r7 m$ Y! D7 R5 \
        sell_price_1 = round(swap_sell_price_1*1.02,symbol_exchange_info[1][1])6 i; o; B% c$ X1 u1 \3 y1 p

2 g" b/ L5 \: J* a        if buy_price_1 > sell_price_1:
/ g3 Q6 {& H" Z  ?* ^- F            lot = round(execute_amount/buy_price_1,symbol_exchange_info[0][2])' I; P! o# W) v9 c' i- {: ?
        else:
$ o2 w- i# ?; y9 [& w            lot = round(execute_amount/sell_price_1,symbol_exchange_info[1][2])8 Y/ x" c! ?/ g: N1 e3 j" K3 }/ n4 a
+ r2 f* g4 i& J4 A! v
        r = swap_buy_price_1 / swap_sell_price_1 - 1
7 i' o, D; A0 \5 s& [        print( "{} 买一价 {} ,做空 {} , 下单量 {}".format(symbol_1,swap_buy_price_1,buy_price_1,lot))
0 I; _' p6 D5 y/ C8 B1 Y        print( "{} 卖一价 {} ,做多 {} , 下单量 {}".format(symbol_2,swap_sell_price_1,sell_price_1,lot))+ k3 @% ]- k9 y
, c3 J) v9 V% D) i) p" ~
        print("开始下单 : ")
* K& M% G' H5 \$ ]- c        symbol_1_order_info = ins.u_order_send(symbol_1,"SELL","LIMIT",quantity = lot ,price = buy_price_1,timeIn_force="GTC")2 k7 w' ]5 O; E8 X# ~* y" F0 W
        symbol_2_order_info = ins.u_order_send(symbol_2, "BUY", "LIMIT", quantity=lot, price=sell_price_1,timeIn_force="GTC")
5 u9 ~% B' K8 w+ Z        print(symbol_1_order_info)
& k& _' m& R. a: F1 U7 E: K        print(symbol_2_order_info)
. J; v# m6 k9 V, |# E2 S& {
! z7 [1 o1 c! k- b! M' k+ D8 c        if ("code" in symbol_1_order_info) | ("code" in symbol_2_order_info):9 A2 |7 }$ ^4 w6 y, b2 S2 M1 p
            print("下单出错停止"); |( U' Y% x7 F4 X( T" t, {& T
            break
+ b  @2 D/ a  `) w7 c0 D
& W% ?7 X# O4 q' c# h; K        time.sleep(5)& q% D) S$ \7 w; O5 w
        print()
. Z' O3 [2 [8 ^# j/ Q
! T2 @$ Z' Y; D- _# Q5 u: Z        if execute_num >= max_execute_num:8 U% T  ~* i7 O- ~/ O
            print('达到最大下单次数,完成建仓计划,退出程序')
6 g9 N0 h3 ~; E" }# \* r5 s( h            Break监控代码  M/ {9 t# L: J3 V0 |
print("\n"+text)- X' o7 e" J; e9 B3 r
        text = " 警报! adl风险 : " + "\n" + str(adl) + "\n"( o. `& T. o1 w  C5 C$ o
        dingtalk_alert.send_dingding_msg(alert_text + text)/ |5 m! S" F7 b  N
0 }7 h3 B2 ?$ h; ]
    # 2.检测手数是否平衡,异常报警,平掉多余手数, B( y: l, y! J/ X. A' w
    check_pos = check.pos()
1 I% }. n. M/ V6 z# ?    df_pos = check_pos[0]   # 原始仓位- G& B. F# I; b3 B
    coin_pos = check_pos[1] # 多空抵消后的币的仓位
( T8 X0 X& }! p; h6 a- [) S
2 q6 i3 {. X8 r# `4 m# k6 k9 h    coin_pos = coin_pos[coin_pos['open_pos'] != 0]1 x. J8 m0 H' b
    if len(coin_pos) > 0:
* g7 X/ l$ L% C! Y) E5 V; F
- [  e3 ?9 w- @/ K8 E        symbol_order_info = check.close_pos(coin_pos)! h; q9 v3 D; Y* h$ L; i
% m5 ?6 O  q% t3 V% K, \# m! x
        text = " 警报!仓位异常 : "+"\n"+str(coin_pos.to_markdown())+"\n"+"平仓信息 : " +"\n"+str(symbol_order_info)6 C6 e1 a8 z5 T3 w0 x0 S
        print(text)
0 w: R' ?9 J( Y4 c) [        text = " 警报!仓位异常 : "+"\n"+str(coin_pos)+"\n"+"平仓信息 : " +"\n\n"+str(symbol_order_info)7 k: J: f8 G+ C. W1 \
        dingtalk_alert.send_dingding_msg(alert_text + text + str(symbol_order_info))
$ t: K! T8 e/ _1 ]" M( y0 M$ E4 H: U/ x- D! X+ A
    # 3.账户风险,检测资金流水,本期到期资金费率
; z/ N1 m. U; U, `, I    now_time = pd.to_datetime(now_time)
- e; D1 \" S( g- P    account_risk = check.account_risk()
% Q2 O( Q1 `) Y: d8 L7 [" I! p    maint_margin = account_risk[0]
4 W; F- p7 z" c7 E2 a1 b- d    margin_balance = account_risk[1]. }. a) {' J2 Q4 \. f1 M
    risk_rate = round(float(account_risk[2] * 100),2)
( y2 F0 c3 Q2 r8 c# y" a$ Z7 Y! m3 Q+ J  v% c% ~. j! b
    if risk_rate > set_risk_rate:
8 Z- Z3 J# N7 Q" X        text = " 警报!账户风险率 : {}%".format(risk_rate)- J2 ~1 \& [: I/ E8 ~1 b( B4 A0 ^
        print(text)
- i0 x. t" H/ D        dingtalk_alert.send_dingding_msg(alert_text +text)
4 {( {0 M& A8 m5 K( P& `3 s# C
7 T/ J5 r$ G( r& _3 W$ d; g, F    # 资金费率发生后一分钟显示数据
8 }) f4 F+ Q) }* L1 y6 ^+ b    if now_time.hour % 8 == 0 and now_time.minute == 1:) V$ v# C9 G% V! J, r" l4 f8 b$ f
& u) V( B5 r$ _& P
        text = "\n"+"【账户风险】 :"+"\n"+\
) _, `- q# S* \4 |6 E2 D               "维持保证金 : {}USD".format(round(maint_margin,2))+"\n"+\' Y% R% P0 R+ Z3 `4 N+ I0 _* i
               "账户权益 : {}USD".format(round(margin_balance,2))+"\n"+\$ t4 w4 @9 h4 |' Q( ^' t7 E
               "账户风险率 : {}%".format(risk_rate)+"\n"+" "+"\n"+\
8 T! ^0 O7 S. ~6 b( D" V( d& z               "【资金费率差】 :" +"\n"+str(check.last_funding_rate())+"\n"+" "+"\n"+\
; o3 i5 ^. b* e5 F5 Y& i7 x( L4 A; H               "【币种收益】 : "+"\n"+str(check.income()) + '\n'+" "
0 _1 @9 C& |6 K1 l' j% y* H* G  u; ?1 ?/ ^& L, P( H" t. x
        dingtalk.send_dingding_msg(text)% t% A7 I' e& w1 B5 e0 G# d
        print(text)
& D2 l7 g1 X! A/ G0 ]7 M' f8 T; l- T; b5 _6 M3 J
        # 休眠60秒这样就只会报警一次了4 f& l" C+ C# A( Q" X$ F+ Q' n
        time.sleep(60)
- E# ]0 }$ D: e3 n8 X0 x. }) x( {7 |$ N( j! g3 E
    print()1 Q6 `, e) k0 p6 \& j: S
    time.sleep(sleeptime)# A2 ]: J6 z5 s  V
/ u  `/ F0 |$ m& h6 U

- N  R5 F# g+ v8 kif __name__ == '__main__':
$ d1 I+ Z- E3 K4 {4 A
1 T3 e8 S9 U3 R, F: e9 U% o7 P8 U6 B. c
    while True:% u3 {! K" e- \( p! W# d0 g) E
/ q3 V: H9 i1 ~6 ~% A* I
        try:
- f4 ~  M' U0 B3 m            main(ins,dingtalk_alert,dingtalk,alert_text)# S: |6 g, p; _, Z' \- `$ T9 q! f" ~
        except Exception as e:2 M: T* i: q0 Y) s' S, y- y
            print("程序报错")
# T7 e7 V" e" g            dingtalk_alert.send_dingding_msg(alert_text + "程序报错 :" + str(e))* y3 V+ P! Q& P5 I. q- f
            time.sleep(10)1 R' U3 g- \/ x& d) E4 B  E
三、其他5 f( G" Q; g3 d- |* C; q

6 E* U  ^: o; X' a5 I# t我这里没写平仓,大家开单反过来写下就行了,另外跑的时间很短,这几天大部分币资金费率差开始变成负的了( 策略是否要加入自动平仓功能,比如平均多少天的资金费率转负了平仓,转正了再开?),亏了两天,具体策略的情况还需要长期观察。另外usdt之前暴雷过,如果再次发生暴雷,或者busd/usdt价格偏离很大,会发生爆仓。
4 {& J9 y$ H9 ^6 s3 ?先这样吧,觉得有帮助的话多多点赞
8 T1 c$ U& |' S1 J5 j, C: S代码附件:4 k5 f) a& Z3 R0 a+ N
: {( \6 I& u3 s* x8 q  O! d8 p
3 X, F; B. ?3 J
usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-8.jpg
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

264

金钱

0

收听

0

听众
性别
保密

新手上路

金钱
264 元