第2篇超买超卖策略教程,下一篇布林带策略
写一些币安api脚本范例吧,如果要帮写可以私信,今天写一个经典超买超卖指标策略,好像平时没注意过其实这些经典策略还不错。
简单介绍下超买超卖策略,属于趋势反转策略,能有效抓住一段趋势的反转。指标的逻辑就是极限行情不可能持续,行情在这种情况随时会发送反转。
当市场卖出情绪太高时RSI指标低于20属于超卖区域,行情随时可能发生反转(当然也可能继续强势下跌,这里一般需要结合其他指标)。当市场买入情绪高涨时RSI超过80就属于超买区间,这时候行情可能随时反转下跌。
策略一般分两种:趋势策略(等风来,亏吧,来一波行情我就赚了,总在等大行情)。RSI属于小趋势策略,不如双均线那样宏伟一抓就是个大娃娃。
震荡策略(波动吧,我看都不看行情不管涨跌我都赚钱,卧槽怎么超出我的震荡区间了,两个结局,一把亏完。或者等待行情回归震荡区间)
没有第三种策略了。策略只分这两种。
废话不多说直接上代码,代码直接复制粘贴可用。
策略逻辑提炼:
开多平空:RSI<20
开空平多:RSI>80
import logging
#合约模块
from binance_f import RequestClient
from binance_f import SubscriptionClient
from binance_f.constant.test import *
from binance_f.model import *
from binance_f.exception.binanceapiexception import BinanceApiException
from binance_f.base.printobject import *
##现货杠杆和所有REST请求模块
from binance.spot import Spot as Client
import pandas as pd
import threading
import numpy as np
import datetime
import time
import requests
import websocket
import json
#################################################### 客户端启动区
g_api_key = '贴入自己key'
g_secret_key = '贴入自己secret'
#日志
request_client = RequestClient(api_key=g_api_key, secret_key=g_secret_key)
symbol='1000pepeusdt'#你要交易的交易对
interval='1d'#k线周期
rsi_fz=20# #rsi的过滤阈值20
#交易配置
class dx: # 变量属性
symbol = symbol # 交易对
benji=0.
price_jd = 4 # 价格精度
sl_jd = -1 # 数量精度
b=0#杠杆倍数
xs=1.2
def jindu(x,n):#精度处理
if n > 0:
return round(x, n)
else:
return int(x)
def k_get(url):#获取k线条
try:
k_json=requests.get(url).json()
#print(k_json)
return k_json
except Exception as e:print(e)
def get_history(symbol,interval,limit):#读取k线数据
x=k_get('https://fapi.binance.com/fapi/v1/klines?symbol='+
symbol+'&interval='+interval+'&limit='+str(limit))
#print(x[0])
return x
def get_ye():#查询余额
bj=request_client.get_balance_v2()#查询账户余额
for i in bj:
#print(i.__dict__)
if 'USDT' == i.asset:
#print(i.__dict__)
tlbenjin1=i.balance#初始本金赋值
return tlbenjin1
def jindu_get(): # 程序初始化数据 获取交易对精度
symboljd = request_client.get_exchange_information()#更新交易对信息
for i in symboljd.symbols:
if i.symbol.lower()==tl.symbol.lower():
jg2=i.filters[0]['tickSize']
sl2=i.filters[1]['stepSize']
print(jg2,sl2)
if '.' in jg2:
jg=len(jg2.split('.')[1].split('1')[0]+'1')
else:jg=0
if '.' in sl2:
sl=len(sl2.split('.')[1])
else:sl=0
print('精度',i.symbol,jg,sl)
return jg,sl
def cw_gx():#仓位读取
x = request_client.get_position_v2()
cijg=[0,0]
cisl=[0,0]
for i in x:
if i.symbol.lower()==tl.symbol.lower():
if i.positionAmt>0:
cisl[0]= i.positionAmt
cijg[0]=i.entryPrice
if i.positionAmt<0:
cisl[1]= abs(i.positionAmt)
cijg[1]=i.entryPrice
return cisl,cijg
def MARKET(dz,cc,sl):#市价交易 交易动作10,持仓方向10,数量
print(dz,cc,sl)
sl=str(sl)
side=['SELL', 'BUY']
positionSide=[ 'SHORT','LONG']
print(side[dz],positionSide[cc],sl)
x = request_client.post_order(symbol=tl.symbol, # 交易对
side=side[dz], # 买卖方向 SELL, BUY
ordertype='MARKET', # 交易类型
positionSide=positionSide[cc], # 在双向持仓模式下必填,且仅可选择 LONG 或 SHORT
#timeInForce='GTC',
quantity=sl, # 下单数量,使用closePosition不支持此参数
# newClientOrderId: 'str' = None#// 用户自定义的订单号
)
return x
def LIMIT(dz,cc,jg,sl):#挂单交易 交易动作10,持仓方向10,价格,数量
print(dz,cc,jg,sl)
jg=str(jg)
sl=str(sl)
side=['SELL', 'BUY']
positionSide=[ 'SHORT','LONG']
##print(dz,cc,jg,sl)
x = request_client.post_order(symbol=tl.symbol, # 交易对
side=side[dz], # 买卖方向 SELL, BUY
ordertype='STOP_MARKET', # 交易类型
positionSide=positionSide[cc], # 在双向持仓模式下必填,且仅可选择 LONG 或 SHORT
timeInForce='GTC',
quantity=sl, # 下单数量,使用closePosition不支持此参数
#price=jg,
stopPrice=jg
)
return x
xintiao=0#心跳记录
def fun_timer():
global xintiao
t=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
#print('心跳记录',t,xintiao)
if xintiao!=1:
ws2.on_open = on_open
ws2.run_forever()
xintiao=0
timer = threading.Timer(60, fun_timer)#1分钟检查一次是否掉线
timer.start()
timer = threading.Timer(60, fun_timer)
timer.start()
def jyxh(k_data):
global fsl,fjg
# 将原始数据转换为DataFrame
df = pd.DataFrame(k_data, columns=['open_time','open','high','low', 'close'])
# 将价格转换为float类型
df['open'] = df['open'].astype(float)
df['high'] = df['high'].astype(float)
df['low'] = df['low'].astype(float)
df['close'] = df['close'].astype(float)
# 计算rsi
rsi=6
delta = df['close'].diff()
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
avg_gain = gain.ewm(alpha=1/rsi, adjust=False).mean()
avg_loss = loss.ewm(alpha=1/rsi, adjust=False).mean()
rs = avg_gain / avg_loss
df['rsi'] = 100 - (100 / (1 + rs))
#信号生成
jg=df['close'].iloc[-1]
#开多
if df['rsi'].iloc[-1]<100-rsi_fz:#开多
if fsl[0]==0:#当前无多单开多
sl=jindu(6/jg,tl.sl_jd )
MARKET(1,1,sl)
if fsl[1]>0:#平空
MARKET(1,0,fsl[1])
if df['rsi'].iloc[-2]>rsi_fz:#开空
if fsl[1]==0:#当前无空单开多
sl=jindu(6/jg,tl.sl_jd )
MARKET(0,0,sl)
if fsl[0]>0:#平多
MARKET(0,1,fsl[0])
def call_symbol(data_type, event): # 服务器有数据更新时,主动推送过来的数据
global klist,fsl,fjg,xintiao
xintiao=1
m=json.loads(event)
if 'k' not in m:print(m)
if m['k']['x']==True:#数据更新
if len(klist)>20:klist=klist[-20:]
fsl,fjg=cw_gx()
klist.append([m['k']['t'],m['k']['o'],m['k']['h'],m['k']['l'],m['k']['c']])#添加数据到k线
jyxh(klist)#交易信号生成
tl.benjin=get_ye()#余额更新
def on_error(ws, error): #
print('连接出错',error)
def sj_yuchuli(k):#数据处理
c=[]
for i in k:
c.append([i[0],i[1],i[2],i[3],i[4]])
return c
tl = dx() # 实例化
klist=[]#k线缓存
fsl,fjg=[0.,0.],[0.,0.]#仓位数量,仓位价格
klist1 = get_history(tl.symbol.upper(), interval, 100) # 获取数据集用于堆积启动数据#先获取k线数据集用于计算各种指标
klist=sj_yuchuli(klist1[:-1])#数据预处理
tl.price_jd,tl.sl_jd=jindu_get()#获取交易精度
tl.benjin=6#get_ye()#余额读取
fsl,fjg=cw_gx()#程序开跑前仓位检查
request_client.cancel_all_orders(tl.symbol) # 取消所有订单
sub_client.subscribe_aggregate_trade_event(tl.symbol, call_symbol, error)#行情监听