- 警告 1:本文仅涉及技术分享。请勿将本文内容运用于实盘交易,以免出现巨额亏损。数字资产交易涉及重大风险,本文不应作为投资决策依据,亦不应被解释为从事投资交易的建议。请确保充分了解所涉及的风险并谨慎投资。
- 警告 2:十部门:比特币、以太币等虚拟货币业务属于非法金融活动 (来源:人民网 | 日期:2021-09-24)
- 警告 3:关于进一步防范和处置虚拟货币交易炒作风险的通知 (来源:中国人民银行 | 日期:2021-09-24)
获取 API KEY 和可用的 SDK 包
本文的案例使用了 Okex V5 API,参考前请阅读文章开头的警告。Okex 官网的 API 文档(目前只有 V5):https://www.okex.com/docs-v5/zh/ 。
由于官网没有为 V5 API 提供 SDK 包,所以本文用到了以下的第三方 SDK 包: https://github.com/jane-cloud/Open-API-SDK-V5 。
import okex.account_api as Account
import okex.Public_api as Public
import okex.Trade_api as Trade
获取账户信息
一些初始化的信息,注意一定要保存好 APIKey 和 SecretKey 和 passphrase ,不要在公开场合(公开的文章、代码仓库等)出现。
# 账户信息
api_key = snickers.my_trading_info['api_key']
secret_key = snickers.my_trading_info['secret_key']
passphrase = snickers.my_trading_info['passphrase']
flag = '0' # 实盘 real trading ,v5 专有
# 一些参数的初始化
result_total = {} # 放置各种数据的读取结果,字典
mail_content = {} # 放置邮件内容,字典
一些常用的信息,如“持仓数量”、“未实现收益”、“持仓方向”、“可用保证金”等。
accountAPI = Account.AccountAPI(api_key, secret_key, passphrase, False, flag) # 获取账户信息
result_total['position-info'] = accountAPI.get_positions('SWAP', instrument) # 获取账户中的仓位信息
holding_info = result_total['position-info']['data'][0]['pos'] # 持仓数量
upl_info = result_total['position-info']['data'][0]['upl'] # 未实现收益
side_info = result_total['position-info']['data'][0]['posSide'] # 持仓方向
uplRatio_info = result_total['position-info']['data'][0]['uplRatio'] # 可用保证金
获取基本行情数据
这里获取单个标的的行情数据,下方代码中获取的是1分钟的 k 线信息,并根据实际需要提取相应的数据。
marketAPI = Market.MarketAPI(api_key, secret_key, passphrase, False, flag) # 获取市场数据
result_total['kline-'+instrument] = marketAPI.get_candlesticks(instrument, bar='1m') # 获取指定时间的k线
kline_close_result = [] # 收盘价
kline_high_result = [] # 最高价
kline_low_result = [] # 最低价
kline_hlc3 = [] # 上述三者的平均值
list = result_total['kline-'+instrument]['data'] # 指定时间的k线100根,顺序“最新-最旧”
i = 1
while i < 15: # 限制,每次最多获取100根k线,所以要获取10次,才能获取1000根以上
## 最旧的那个时间戳
dataunix = list[-1][0]
print(dataunix)
get_data_2nd_times = marketAPI.get_candlesticks(instrument,after=dataunix,bar='1m')
#print(get_data_2nd_times)
list = list + get_data_2nd_times['data']
i = i+1
#print(list)
for i in range(len(list)):
kline_close_result.append(float(list[i][4]))
kline_high_result.append(float(list[i][2]))
kline_low_result.append(float(list[i][3]))
kline_hlc3.append((float(list[i][2])+float(list[i][3])+float(list[i][4]))/3)
calcul_atr(kline_close_result,kline_high_result,kline_low_result,instrument)
使用 TA-Lib 计算指标
在 Ubuntu 中安装 TA-Lib 请参考这篇文章: UBUNTU 服务器安装 TALIB 并定时执行 PYTHON 量化小脚本。
在 Windows 中安装 TA-Lib ,请访问 https://github.com/cgohlke/talib-build/releases/tag/v0.4.32 ,并根据自己的 Python 版本选择下载。
例如,在上述网站下载了 TA_Lib‑0.4.21‑cp38‑cp38‑win_amd64.whl 这个文件,将此文件放入到 C:\Windows\System32
路径下。
进入 CMD 命令行窗口(或 Anaconda Prompt 亦可),进入 C:\Windows\System32
,输入安装命令 pip install TA_Lib‑0.4.21‑cp38‑cp38‑win_amd64.whl
在脚本中导入该库:
import talib
MACD
df = {}
# diff, dea, macd
df['DIFF'],df['DEA'],df['MACD'] = talib.MACD(np.array(kline_close_result),
fastperiod=12, slowperiod=26, signalperiod=9)
diff = df['DIFF'][~np.isnan(df['DIFF'])] # 去除nan
dea = df['DEA'][~np.isnan(df['DEA'])] # 去除nan
macd = df['MACD'][~np.isnan(df['MACD'])] # 去除nan
EMA
df = {}
## 计算EMA
df['MA_long'] = talib.EMA(np.array(kline_close_result),timeperiod=100)
df['MA_short'] = talib.EMA(np.array(kline_close_result),timeperiod=50)
ema_value_diff.append(df['MA_short'][-2] - df['MA_long'][-2])
ema_value_diff.append(df['MA_short'][-1] - df['MA_long'][-1])
print(ema_value_diff)
开仓和平仓
开仓和平仓用一个函数即可,需要填写以下信息即可执行开仓和平仓:
- 开多:买入开多(buyornot 填写 buy;direction_type 填写 long )
- 开空:卖出开空(buyornot 填写 sell;direction_type 填写 short )
- 平多:卖出平多(buyornot 填写 sell;direction_type 填写 long )
- 平空:买入平空(buyornot 填写 buy;direction_type 填写 short )
#%% 开多 开空
def trading_swap(buyornot,direction_type,instrument):
tradeAPI = Trade.TradeAPI(api_key, secret_key, passphrase, False, flag)
accountAPI = Account.AccountAPI(api_key, secret_key, passphrase, False, flag)
result = accountAPI.set_leverage(instId=instrument, lever='20', mgnMode='isolated',posSide='long') # 设定杠杆
result = accountAPI.set_leverage(instId=instrument, lever='20', mgnMode='isolated',posSide='short')
result2 = accountAPI.get_maximum_trade_size(instrument, 'isolated') # 逐仓最大可开仓张数
max_sz = str(int(int(result2['data'][0]['maxBuy'])/10)) # 只开最大数量的一半,但张数要为整数
# 开多:买入开多(side 填写 buy; posSide 填写 long )
# 开空:卖出开空(side 填写 sell; posSide 填写 short )
try: # 尝试做以下事情
result = tradeAPI.place_order(instId=instrument, tdMode='isolated', side=buyornot, posSide=direction_type,ordType='market', sz=max_sz)
print(result)
except: # 如果因为各种原因报错
print('可能没有相应的单子!或保证金不够!')
mail_content["order_info"] = instrument+"!!!开仓失败!开仓数量大于可开数量,保证金不够!"
mail_trade.send_mail_img(mail_content) # 发邮件
else: # 如果没有报错
mail_content["order_info"] = instrument+"开仓成功"
# 邮件内容正文
mail_content['holding_info'] = '开仓成功'
# 邮件主题
mail_content['holding_info_subject'] = '开仓成功'
mail_trade.send_mail_img(mail_content) # 发邮件
市价全平
## 市价全平
def trading_swap_close_all(direction_type,instrument):
try: # 尝试做以下事情
tradeAPI = Trade.TradeAPI(api_key, secret_key, passphrase, False, flag)
result = tradeAPI.close_positions(instrument, 'isolated', direction_type , '')
print(result)
except: # 如果因为各种原因报错
print('可能没有相应的单子!或保证金不够!')
else: # 如果没有报错
mail_content["order_info"] = "平仓成功"
mail_trade.send_mail_img(mail_content) # 发邮件
达到条件开仓平仓
if mail_content['holding_info'] != "当前无持仓" and side_info == 'long' and pos[-1] == -1:
print("平多和开空")
trading_swap_close_all("long",instrument) # 市价全平
time.sleep(15)
trading_swap("sell","short",instrument)
elif mail_content['holding_info'] != "当前无持仓" and side_info == 'short' and pos[-1] == 1:
trading_swap_close_all("short",instrument) # 市价全平
time.sleep(15)
print("平空和开多")
trading_swap("buy","long",instrument)
在 Ubuntu 服务器中自动执行
请参考下下列文章: