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

[复制链接]
查看8544 | 回复0 | 2023-8-7 09:07:15 | 显示全部楼层 |阅读模式
一、引言$ }, j2 f% y, j

4 w, m1 `8 W8 v4 o; S9 a4 g(1)、希望对其他同学有帮助,顺便希望能有个小葫芦,集齐7个娃6 N8 ]; f, b  V1 S
(2)、担心自己程序有考虑不周到的地方。比如爆仓风险啥的,毕竟个人的经验认知有限。也希望同学有好的想法能交流者发帖共享出来一起改进 (这是主要的,嘻嘻,有同学优化,改进,或者马力强的能分析历史找出比较优的方案)。一起致富,此贴抛砖引玉。" r7 L3 b, Y+ H
(3)、下图是我大概半个月的收益( 做空usdt,做多busd,利用杠杠,赚两个品种的费率差 ),因为我资金没全开满,也是每天观察,一点点加的,中间也调仓开开平平,持了好几个币,所以平均持仓大概用了一万二,三左右金额。策略比较粗糙,只是一个大概的开单跟查询框架。
  p/ b, O% N" z2 d2 s* ]效果图! B& Z, B9 u0 j* a+ D& w

% z: o1 `% x+ j usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-1.jpg / ^- J5 d  |. V! U  r  `6 x
二、程序设置
5 ^7 w7 z+ v& D& Q( g
3 K. @% d( Y$ V" g' ^账户先设置成单边模式,和联合保证金模式 ( 联合保证金可以参考上一篇帖子设置 )
$ o3 V4 t  @5 R4 e3 y. a(1)、在【utils】文件夹下的【Config.py】里设置账号和钉钉账号,这里钉钉账号我程序里是有两个,大家也可以都填一样的,因为我有专门个钉钉监控所有策略的异常& m6 M& |" a( T0 i( m" \& O
# [& p- V6 A: {, S4 o# p

3 q. J% M+ P9 u9 t$ N(2)、在【实盘下单】文件夹里的【config.py】配置策略相关参数,【实盘下单】里的所有py程序参数都在这一个文件里配置,参数 "set_lever"是要自己查询两个本位的允许最大杠杠,比如BTCUSDT最大刚刚是50倍,BTCBUSD杠杆是20倍,那就填20,后面程序运行会自动设置3 p0 ]# X5 a3 C2 @

- B9 s$ A- W; I( G2 @ usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-3.jpg
  ^( ?* q! x7 z& Z( e(3) 、【1_实盘下单.py】这里一开始会显示相关的数据,觉得ok了,在最下方输入yes,才会开始开单,程序有一个地方要注意,右上角有显示这个品种最大的持仓价值,我这里没做处理,目前是假设跑BTCUSDT,BTCBUSD,假设BTCUSDT开单了,接着开BTCUSD超过了允许值开不出来,然后程序会结束,这时候需要手动在把BTCUSDT多开的部分平掉。: ~3 q* ~7 t9 V0 |  c- G
( y/ z7 z) D! T

/ |! Q6 L* S- r% ?( H(4)、【3_实盘监控.py】开单后主要就是开着这个程序,循环监控,这里功能,每到 00:00、8:00、16:00 会显示相关信息,并且如果ADL到达你设置的报警级别,或者仓位不平衡会隔10秒提示,并且仓位不平衡的时候,也会把多出来的一边多出来的部分给平了,目前是这样处理的。okex船队的方法是平掉百分20再开,我担心行情极端的时候会出现平开,又ADL又平开的情况,干脆直接平掉多出来的部分,这里我是一次性平掉的,等到行情稳定了再手动执行程序补。而且具我观察币安的这些合约ALD满级了也很少触发平仓,如果主动平仓再开,多几次成本就高了,个人想法。
9 J7 K8 J, t+ X* G
1 `- {. V  @1 j8 ` usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-5.jpg
0 d4 @0 q3 T' `. v9 k  S$ {* D& I% i+ L% n+ B: o5 \$ Z7 X9 N& m
usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-6.jpg
0 b& ^, G/ v1 b# q7 |$ D! D9 i# I# k0 x! s( i; ]

& x1 _2 h; e. K2 k/ C# n: o$ K(5)还有两个小程序【5_保证金查询.py】,【6_收益查询.py】查看账户情况,用于策略的参考& ]" ?% t, Q; |7 ]% N! c
三、主要代码
$ T4 h' Y) O' H% P8 Z9 c$ e3 v0 v7 Q$ n. n* J2 N0 v
下单代码- f8 ~0 m, |+ {. F/ s) U4 x! g( b! W
import utils.Config as Cf
* \8 C( y3 b$ Bimport utils.gateway.binance_http as ins8 F2 x1 Y9 a( l' t7 e, \* t+ E
import time3 f9 F" U- ], y
import program.usd_busd永续套利.实盘下单.config as cf
. c7 D5 r1 }# I: yimport math" X9 e: J: T9 |' Q( f
# ===== 初始化
" E  u& t; E+ m& s# y# 创建币安api
. x  i' H. |4 f" G, haccount = Cf.account[cf.username]
+ G/ `' O2 ^, `7 o! yins = ins.BinanceHttp(key = account['key_0'] ,secret=account['secret_0'] )
* H/ N  ~0 Y8 ]' r3 Q! O) K* e8 ~8 [' u6 a( ?+ [% L: w, Y
# 参数设置
5 u7 S0 F3 t5 bcoin = cf.coin; J4 O* `0 _; R9 l
money = cf.money # usdt
1 a, L' S  E6 D, p) aset_lever = cf.set_lever # 设置杠杆
: ~- i, |9 w) c' Psymbol_1 = cf.symbol_1 # 做空
1 J, Y( V% B4 y3 u% w; d+ r0 f0 Bsymbol_2 = cf.symbol_2 # 做多
8 b9 A6 Z2 u- m2 O4 t3 N  nexecute_amount = cf.execute_amount # 每次建仓usdt的数量。如果是btc的话,得是100的整数倍。其他币种得是10的整数倍。每次数量不要太多,太多会造成价格波动。建议数量在1000-3000之- b9 x" |- [* i0 z7 ]/ S2 i
max_execute_num = math.floor(money*set_lever/execute_amount/2)  # 最大建仓次数,需要向下取整这里要改。建仓这些次数之后程序就会停止。  n- e" ^7 D6 {  R' I: x# ]

2 S/ W. [1 j0 F0 j$ y% Nprint("开仓次数 : {}".format(max_execute_num))
1 ?$ Q$ m1 O, c' t( cprint("设置最大杠杆 : ")# h& ]0 d) w0 |, d* ]  y
print(ins.u_set_leverage(symbol_1,set_lever))1 j( S, y% ?1 t: t
print(ins.u_set_leverage(symbol_2,set_lever))
% W! I0 o5 v9 Y# i& O' q$ ~  ^$ Mprint()
7 r+ s& k9 V) G! K5 G9 V" y5 x/ a, ]' f. E2 y4 m/ x) q$ E
print("最新资金费率 : ")
0 T4 z6 C, t6 W( zprint(symbol_1 + ": "+ins.u_premiumIndex(symbol_1)["lastFundingRate"])
8 B3 u" c2 w3 oprint(symbol_2 + ": "+ins.u_premiumIndex(symbol_2)["lastFundingRate"])1 C" V0 Y% O9 [: _
print()7 T) V; ^' B8 J$ Y& {6 w2 r

# a8 J1 \3 F0 j0 @% s1 Pprint("合约信息 : 品种 ,价格精度,下单量精度,最小下单u")
. H: H4 Q7 q  ~! \8 a* dsymbol_exchange_info = [[i['symbol'],
# l( h+ e4 I. _/ F. M, P                         int(i['filters'][0]['tickSize'][::-1].split("1")[1].find('.')) + 1,
7 A3 V2 A& a$ r" F                         int(i["filters"][2]["minQty"][::-1].split("1")[1].find('.')) + 1,
0 D. _( L4 G+ S% y* |                         i["filters"][5]["notional"]]+ H) _! G+ V7 y) b9 \
                        for i in ins.u_exchange_info()["symbols"] if i['symbol'] in [symbol_1,symbol_2]]
4 ?0 y& Y' ]/ S1 h, ^  Jprint(symbol_exchange_info,'\n')# 价格下单精度,价格最小下单量精度,最小下单金额2 d: X7 `. Q, V
print()/ S8 p$ S2 {& K) W; i% [8 `& t
3 n( X+ |; c' u& {7 H( b
swap_buy_price_1 = float(ins.u_depth(symbol_1, limit=5)['bids'][0][0]) # 做空8 A2 ]7 \$ T" ~8 u0 [  t5 x
swap_sell_price_1 = float(ins.u_depth(symbol_2, limit=5)['asks'][0][0]) # 做多; W1 Q- d$ O) d  W* _0 u
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)))
( D, Y% `3 F8 D2 p5 j; v" v& D# \1 a. S, h0 B' L/ y; d4 |
print()4 _+ u; v  ^) V6 _# o0 U9 U
run = input("注意控制风险,是否继续 y/x :")  ?0 V, b" H! r; R* H6 i
9 `, P% d5 A  ]6 J# l5 H
if run.lower() == "x":6 `9 e( x4 c) q2 @5 r' M& H1 r
    print('*' * 20, '程序退出', '*' * 20, '\n')
: c+ O. f7 i, B/ P    exit()- u1 M- C! z. ?2 f4 r4 s* ~3 ~
  d) ~% `5 M& t! D' p- |# t
elif run.lower() == "y":8 T4 B% r, ~/ Z. V; l& v2 ]
    print('*' * 20, '【开始运行】', '*' * 20, '\n')  I3 E2 {, J: K9 X
0 B: n8 y' j7 B4 S+ U$ E; ^3 Q
    execute_num = 0
% i/ S5 [4 y3 Y; R9 D9 W" T6 H3 H3 }  |    while True:$ k" s& w& i# ~: t5 Q: `7 l" r9 |. |9 o

/ t5 @8 D3 u$ \8 n' C3 Y; V$ x- N5 O$ n
        execute_num+=1
" U$ S1 a% t( @; x7 S        print("*"*50,"【执行{}次】".format(execute_num),"*"*50)
( i4 _% Q, N4 A$ J6 T, T" r8 c- J# Y1 ^9 U8 s  G) @* f
        swap_buy_price_1 = float(ins.u_depth(symbol_1, limit=5)['bids'][0][0])
# T$ Y) {$ z$ f        swap_sell_price_1 = float(ins.u_depth(symbol_2, limit=5)['asks'][0][0])8 u3 E% P2 g5 H6 T8 _" m, R& i
        buy_price_1 = round(swap_buy_price_1*0.98,symbol_exchange_info[0][1])' E  j  P# y! u9 [, {
        sell_price_1 = round(swap_sell_price_1*1.02,symbol_exchange_info[1][1])
! g6 p/ `! _4 d+ d% f& k" s# R: ]& C( |
        if buy_price_1 > sell_price_1:
3 E7 r" E0 q" u' i) s            lot = round(execute_amount/buy_price_1,symbol_exchange_info[0][2])
  m  Q+ a8 u: _0 p& S: E; U        else:/ G5 ]2 v" R0 a. {: V$ _: m
            lot = round(execute_amount/sell_price_1,symbol_exchange_info[1][2])
+ T4 t% j. ?5 }9 V) n. f; y
) n0 l: X8 e3 g, [1 K7 ^& B        r = swap_buy_price_1 / swap_sell_price_1 - 12 x) j4 v2 o4 t9 }" L+ z9 p: z6 r# y
        print( "{} 买一价 {} ,做空 {} , 下单量 {}".format(symbol_1,swap_buy_price_1,buy_price_1,lot))
" o# I: V  y( s5 j3 R        print( "{} 卖一价 {} ,做多 {} , 下单量 {}".format(symbol_2,swap_sell_price_1,sell_price_1,lot))
/ a. u3 h: \4 M7 M: G5 T! ^
. [& I: K. D1 Y" [3 X        print("开始下单 : ")
3 U/ N( P+ F$ w4 H( T        symbol_1_order_info = ins.u_order_send(symbol_1,"SELL","LIMIT",quantity = lot ,price = buy_price_1,timeIn_force="GTC")3 p0 o9 Y8 M% y" U" O" Y! \, r
        symbol_2_order_info = ins.u_order_send(symbol_2, "BUY", "LIMIT", quantity=lot, price=sell_price_1,timeIn_force="GTC")
: j( t. w5 }8 q9 i4 j        print(symbol_1_order_info)# T) j) i: Z% e9 f) E! l. S8 v$ k
        print(symbol_2_order_info)" U7 H2 K+ Z& {

3 I' s1 E" Z: g$ Z1 [( ]2 p; q. ^        if ("code" in symbol_1_order_info) | ("code" in symbol_2_order_info):  g* k  b  V0 w7 G
            print("下单出错停止")) Q# K# W8 Q4 H  s0 Y# ]" @
            break
2 i# s  X8 z( M5 T* m7 a/ k6 P4 q4 U* G: R
        time.sleep(5)2 H$ X$ t: ~; a- v
        print()
) c& s" m$ l7 N. d5 H6 u
% ?- E* \* F, {5 g- h2 `5 m        if execute_num >= max_execute_num:. u# n* p  T2 ]5 o6 i$ I
            print('达到最大下单次数,完成建仓计划,退出程序')
) S' w; f1 }: S" y  ~# h            Break监控代码
0 a- x! u' K! s$ Z1 Tprint("\n"+text)
7 ^; U! f5 G6 q- `% _% {1 {        text = " 警报! adl风险 : " + "\n" + str(adl) + "\n"6 h2 e* s- B6 e
        dingtalk_alert.send_dingding_msg(alert_text + text)
+ J  J3 `/ W  t( y6 V7 R5 V: ~( ]% k) q3 k- H# |/ W
    # 2.检测手数是否平衡,异常报警,平掉多余手数
: U2 L1 L4 i) |  V    check_pos = check.pos()
' l# U. o- f2 [, j9 H" n    df_pos = check_pos[0]   # 原始仓位# e8 h8 R6 n! b/ M9 g
    coin_pos = check_pos[1] # 多空抵消后的币的仓位$ m& H8 ~1 l! T% Y: \

, J  q! S, T7 v) ~" i    coin_pos = coin_pos[coin_pos['open_pos'] != 0]! n: c5 P, u  @8 x
    if len(coin_pos) > 0:3 ^8 y( o6 q. `- X

( Q9 H+ y+ Z+ C. ?- q4 C        symbol_order_info = check.close_pos(coin_pos)
9 k( C" l* g4 Q4 V  x
- s; v. I8 ?( ?1 u3 [* U' D3 |4 o        text = " 警报!仓位异常 : "+"\n"+str(coin_pos.to_markdown())+"\n"+"平仓信息 : " +"\n"+str(symbol_order_info)4 t* g! B6 d+ w, o6 c
        print(text)- J6 c" O0 h) O8 }( S
        text = " 警报!仓位异常 : "+"\n"+str(coin_pos)+"\n"+"平仓信息 : " +"\n\n"+str(symbol_order_info)
, z  f8 V) v: A, m        dingtalk_alert.send_dingding_msg(alert_text + text + str(symbol_order_info))
9 y+ X6 a& e; G. ~+ T
- l& N5 t1 h6 W+ w- p    # 3.账户风险,检测资金流水,本期到期资金费率; M( y* O) @9 V+ Q* ^9 o
    now_time = pd.to_datetime(now_time)$ ~0 O. c3 }- {6 x9 s5 Y
    account_risk = check.account_risk()8 X( k! D8 y& ^' h; ^$ m6 K
    maint_margin = account_risk[0]" Y+ z  @. y% f: F: }
    margin_balance = account_risk[1]
- [  B: |# Y+ h    risk_rate = round(float(account_risk[2] * 100),2)  A' c1 m( P. W+ {; J/ o: m' O

3 N8 v) z$ K7 n, ~2 G. d1 P/ ?    if risk_rate > set_risk_rate:
% y# \- L! f5 J3 B: |: B( K" K! U        text = " 警报!账户风险率 : {}%".format(risk_rate)
3 S6 W: v+ @2 p- x# H$ q1 }& w' `3 p        print(text)
( H' a7 b1 ]. D        dingtalk_alert.send_dingding_msg(alert_text +text)9 S0 ?" M3 X" Q& D8 j1 z

: K# t% x6 q1 C9 h; Z9 ^7 n; ?    # 资金费率发生后一分钟显示数据3 G6 H, z/ w# ]8 d! K+ w1 Y
    if now_time.hour % 8 == 0 and now_time.minute == 1:) V3 f( i# x' v
* t, B4 B+ A4 x! R( j: C. [
        text = "\n"+"【账户风险】 :"+"\n"+\
. N/ r9 P, o) u7 m- V               "维持保证金 : {}USD".format(round(maint_margin,2))+"\n"+\% W7 `* ~8 S8 U. a4 \: k
               "账户权益 : {}USD".format(round(margin_balance,2))+"\n"+\
, u1 k  u* l" D8 M* Q               "账户风险率 : {}%".format(risk_rate)+"\n"+" "+"\n"+\! h9 z" Z" h9 W& T! Q# g9 r
               "【资金费率差】 :" +"\n"+str(check.last_funding_rate())+"\n"+" "+"\n"+\; j4 \0 `% a( U1 Z! z/ b1 o0 u
               "【币种收益】 : "+"\n"+str(check.income()) + '\n'+" "
3 ~- ?$ y5 H2 o3 e. o2 \4 T/ ]! c- w/ M, y. h1 Y) ]
        dingtalk.send_dingding_msg(text)- y+ G  U( G" |0 F
        print(text)
( }' l" z+ z1 ^: t. d
0 I/ K1 H' o1 m0 O7 q        # 休眠60秒这样就只会报警一次了
1 A, {: o; M7 s" g        time.sleep(60)5 h9 x. i) t: i; i

& V8 r' }+ t& `' Q' w& Z$ e    print(). y$ v8 ~$ G% u
    time.sleep(sleeptime)
2 B0 X# J1 b/ g- h* o4 Y# m! w! H2 y1 d1 P, W* o" {

$ M3 l) k5 c6 K: Tif __name__ == '__main__':
" U/ K& n6 r' {( B: k. X) Y
9 W  u! {) o/ {- a7 \8 p' k" J1 w  S
    while True:5 ]$ Y2 E" S5 U* z
, N, x+ X. v/ e, A  m, z
        try:
, b; u. r( `5 o3 c* Y$ o) W4 P7 E            main(ins,dingtalk_alert,dingtalk,alert_text)& j4 ]- u. q0 v$ v  e0 B* ~4 k
        except Exception as e:
6 g9 o5 ]# ?3 j& G1 a            print("程序报错")
2 M, q8 o) m* O+ @4 S$ E# n            dingtalk_alert.send_dingding_msg(alert_text + "程序报错 :" + str(e))
) ^0 s# b4 i" M/ J0 Q' ]4 |            time.sleep(10)
9 v0 t* O8 a* Y( S) ^/ Y4 A- U0 H三、其他
) f6 i- X0 [0 E. ?( v- ?4 ?$ i4 R1 c# M' n% m$ {( z
我这里没写平仓,大家开单反过来写下就行了,另外跑的时间很短,这几天大部分币资金费率差开始变成负的了( 策略是否要加入自动平仓功能,比如平均多少天的资金费率转负了平仓,转正了再开?),亏了两天,具体策略的情况还需要长期观察。另外usdt之前暴雷过,如果再次发生暴雷,或者busd/usdt价格偏离很大,会发生爆仓。& r- W( H0 P6 p8 l4 S6 f
先这样吧,觉得有帮助的话多多点赞6 R. a" j% h6 l
代码附件:  D7 l- g3 R% A

- u2 g) p& H' o5 v4 W" Q! D4 l4 g5 {& Y3 j" {9 E) I( m
usdt本位busd本位资金费率套利研究二 :实盘代码【python数字货币量化_策略第38篇_21精华帖】-8.jpg
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

264

金钱

0

收听

0

听众
性别
保密

新手上路

金钱
264 元