浅谈比特币期货做市策略(3)

来源:互联网 发布:java excel 模板填充 编辑:程序博客网 时间:2024/04/27 17:23

在之前的两次分享浅谈比特币期货做市策略(1)和浅谈比特币期货做市策略(2)中,和大家分享了做市策略的概念和期货做市策略源码,这一期和大家分享期货移仓程序源码,以及做市策略实盘运行结果的展示。


期货移仓程序源码:

#!/usr/bin/env python# -*- coding: utf-8 -*-from signalGenerator.futureSpotArb import *from signalGenerator.strategyConfig import changeFutureContractConfig as rollCfgimport timeclass ChangeFutureContract(FutureSpotArb):    def __init__(self, startRunningTime, orderRatio, timeInterval, orderWaitingTime,                 coinMarketType, open_diff, close_diff, heart_beat_time, depth_data, account_info, transaction_info, maximum_qty_multiplier=None,                 dailyExitTime=None):        super(ChangeFutureContract, self).__init__(startRunningTime, orderRatio, timeInterval, orderWaitingTime,                 coinMarketType, open_diff, close_diff, heart_beat_time, depth_data, account_info, transaction_info, maximum_qty_multiplier=maximum_qty_multiplier,                 dailyExitTime=dailyExitTime)        self.strat_name = "合约滚动-%s" % startRunningTime.strftime("%Y%m%d_%H%M%S")        self.change_contract_diff = rollCfg.CHANGE_CONTRACT_DIFF_1        self.initial_acct_info = None        self.coin_type = rollCfg.COIN_TYPE        self.is_short_contract = None    # 计算当前的换合约需要满足的价差比例    def current_change_contract_diff(self, current_time):        if self.in_time_period(current_time, rollCfg.CHANGE_CONTRACT_START_WEEK_DAY_STAGE_1,                               rollCfg.CHANGE_CONTRACT_END_WEEK_DAY_STAGE_1, rollCfg.CHANGE_CONTRACT_START_TIME_STAGE_1,                               rollCfg.CHANGE_CONTRACT_END_TIME_STAGE_1):            return rollCfg.CHANGE_CONTRACT_DIFF_1        elif self.in_time_period(current_time, rollCfg.CHANGE_CONTRACT_START_WEEK_DAY_STAGE_2,                               rollCfg.CHANGE_CONTRACT_END_WEEK_DAY_STAGE_2, rollCfg.CHANGE_CONTRACT_START_TIME_STAGE_2,                               rollCfg.CHANGE_CONTRACT_END_TIME_STAGE_2):            return rollCfg.CHANGE_CONTRACT_DIFF_2        elif self.in_time_period(current_time, rollCfg.CHANGE_CONTRACT_START_WEEK_DAY_STAGE_3,                               rollCfg.CHANGE_CONTRACT_END_WEEK_DAY_STAGE_3, rollCfg.CHANGE_CONTRACT_START_TIME_STAGE_3,                               rollCfg.CHANGE_CONTRACT_END_TIME_STAGE_3):            return rollCfg.CHANGE_CONTRACT_DIFF_3        elif self.in_time_period(current_time, rollCfg.CHANGE_CONTRACT_START_WEEK_DAY_STAGE_4,                               rollCfg.CHANGE_CONTRACT_END_WEEK_DAY_STAGE_4, rollCfg.CHANGE_CONTRACT_START_TIME_STAGE_4,                               rollCfg.CHANGE_CONTRACT_END_TIME_STAGE_4):            return rollCfg.CHANGE_CONTRACT_DIFF_4        else:            return None    # 计算盘口满足价差的深度数量    def qty_and_price(self, buy_side_data, sell_side_data, price_diff):        max_qty = 0        buy_current_depth = 0        sell_current_depth = 0        buy_limit_price = None        sell_limit_price = None        buy_price = float(buy_side_data[buy_current_depth][0])        sell_price = float(sell_side_data[sell_current_depth][0])        buy_qty = float(buy_side_data[buy_current_depth][2])        sell_qty = float(sell_side_data[sell_current_depth][3])        while sell_price - buy_price >= price_diff:            buy_limit_price = buy_price            sell_limit_price = sell_price            # 数量少的一方,深度+1            if buy_qty > sell_qty:                max_qty = sell_qty                sell_current_depth += 1                sell_qty += float(sell_side_data[sell_current_depth][4])            else:                max_qty = buy_qty                buy_current_depth += 1                buy_qty += float(buy_side_data[buy_current_depth][5])            if buy_current_depth >= len(buy_side_data) or sell_current_depth >= len(sell_side_data):                break            buy_price = float(buy_side_data[buy_current_depth][0])            sell_price = float(sell_side_data[sell_current_depth][0])        self.timeLog("盘口数量为:%s, buy:%s, sell:%s" % (max_qty, buy_limit_price, sell_limit_price))        return max_qty, buy_limit_price, sell_limit_price    # cancel all pending orders    def cancel_pending_orders(self, contract_type):        orders = self.BitVCService.order_list(self.coin_type, contract_type)        while orders is not None and len(componentExtract(orders, contract_type, [])) > 0:            orders = componentExtract(orders, contract_type, [])            for order in orders:                if componentExtract(order, u"id", "") != "":                    order_id = order[u"id"]                    self.BitVCService.order_cancel(self.coin_type, contract_type, order_id)            orders = self.BitVCService.order_list(self.coin_type, contract_type)    def cancel_all_pending_orders(self):        self.cancel_pending_orders(helper.CONTRACT_TYPE_WEEK)        self.cancel_pending_orders(helper.CONTRACT_TYPE_NEXT_WEEK)        self.latest_trade_time = time.time()    def go(self):        self.timeLog("日志启动于 %s" % self.getStartRunningTime().strftime(self.TimeFormatForLog))        self.timeLog("开始cancel pending orders")        self.cancel_all_pending_orders()        self.timeLog("完成cancel pending orders")        while True:            # 非换期货时间,程序一直sleep            if not self.in_time_period(datetime.datetime.now(), rollCfg.CHANGE_CONTRACT_START_WEEK_DAY,                                      rollCfg.CHANGE_CONTRACT_END_WEEK_DAY, rollCfg.CHANGE_CONTRACT_START_TIME,                                      rollCfg.CHANGE_CONTRACT_END_TIME):                self.timeLog("当前处于非移仓时间,程序进入睡眠状态……")                time.sleep(60)                continue            if self.timeInterval > 0:                self.timeLog("等待 %d 秒进入下一个循环..." % self.timeInterval)                time.sleep(self.timeInterval)            # 重置部分self级别变量            self.order_info_list = []            self.change_contract_diff = self.current_change_contract_diff(datetime.datetime.now())            # 查询bitvc深度数据            try:                bitvc_week_depth = copy.deepcopy(self.depth_data)["bitvc"]                bitvc_next_week_depth = copy.deepcopy(self.depth_data)["bitvc_next_week"]            except Exception:                self.timeLog("尚未取得bitvc深度数据")                continue            # 查看行情信息时间戳是否合理            timestamp_list = [bitvc_week_depth["time"], bitvc_next_week_depth["time"]]            if not self.check_time(timestamp_list):                self.timeLog("获取的行情信息时间延迟过大,被舍弃,进入下一循环")                continue            bitvc_week_depth["asks"].reverse()            bitvc_week_sell = bitvc_week_depth["asks"]            bitvc_next_week_buy = bitvc_next_week_depth["bids"]            bitvc_week_buy = bitvc_week_depth["bids"]            bitvc_next_week_depth["asks"].reverse()            bitvc_next_week_sell = bitvc_next_week_depth["asks"]            # 本周合约:买入平仓(看卖1), 下周合约:卖出开仓(看买1)            bitvc_week_sell_1 = float(bitvc_week_sell[0][0])            bitvc_next_week_buy_1 = float(bitvc_next_week_buy[0][0])            bitvc_week_buy_1 = float(bitvc_week_buy[0][0])            bitvc_next_week_sell_1 = float(bitvc_next_week_sell[0][0])            market_price = np.mean([bitvc_week_sell_1, bitvc_next_week_buy_1, bitvc_week_buy_1, bitvc_next_week_sell_1])            price_diff = self.change_contract_diff * market_price            try:                account = copy.deepcopy(self.account_info)                accountInfo = account["account_info"]                account_update_time = account["time"]            except Exception:                self.timeLog("尚未取得账户信息")                continue            # 检查账户获取时间            if account_update_time < self.latest_trade_time:                self.timeLog("当前账户信息时间晚于最近交易时间,需要重新获取")                continue            accountInfo = self.update_bitvc_account_info(accountInfo, market_price)            self.timeLog("记录心跳信息...")            self.heart_beat_time.value = time.time()            self.timeLog("换空头合约价差:%.2f, 换多头合约价差:%.2f。 当前信号价差:%.2f" % (bitvc_next_week_buy_1-bitvc_week_sell_1, bitvc_week_buy_1-bitvc_next_week_sell_1, price_diff))            # setup initial account info            if self.initial_acct_info is None:                self.initial_acct_info = accountInfo            print(self.initial_acct_info["bitvc_btc_hold_quantity_week_short"])            # 判断合约的方向            if self.is_short_contract is None:                if self.initial_acct_info["bitvc_btc_hold_quantity_week_short"] > 0:                    self.is_short_contract = True                elif self.initial_acct_info["bitvc_btc_hold_quantity_week_long"] > 0:                    self.is_short_contract = False            # 空头合约,本周买入平仓,下周开空仓            if self.is_short_contract:                print("short")                buy_side = bitvc_week_sell                sell_side = bitvc_next_week_buy                week_decreased = self.initial_acct_info["bitvc_btc_hold_quantity_week_short"] - \                                 accountInfo["bitvc_btc_hold_quantity_week_short"]                next_week_increased = accountInfo["bitvc_btc_hold_quantity_next_week_short"] - \                                      self.initial_acct_info["bitvc_btc_hold_quantity_next_week_short"]                # 本周合约剩余的money,按市场价折算成可成交数量                week_remaining_qty = accountInfo["bitvc_btc_hold_money_week_short"] / market_price                week_trade_type = helper.CONTRACT_TRADE_TYPE_BUY                next_week_trade_type = helper.CONTRACT_TRADE_TYPE_SELL                week_contract_avg_price = accountInfo["bitvc_btc_hold_price_week_short"]            else:                buy_side = bitvc_next_week_sell                sell_side = bitvc_week_buy                week_decreased = self.initial_acct_info["bitvc_btc_hold_quantity_week_long"] - \                                 accountInfo["bitvc_btc_hold_quantity_week_long"]                next_week_increased = accountInfo["bitvc_btc_hold_quantity_next_week_long"] - \                                      self.initial_acct_info["bitvc_btc_hold_quantity_next_week_long"]                # 本周合约剩余的money,按市场价折算成可成交数量                week_remaining_qty = accountInfo["bitvc_btc_hold_money_week_long"] / market_price                week_trade_type = helper.CONTRACT_TRADE_TYPE_SELL                next_week_trade_type = helper.CONTRACT_TRADE_TYPE_BUY                week_contract_avg_price = accountInfo["bitvc_btc_hold_price_week_long"]            week_order_type = helper.CONTRACT_ORDER_TYPE_CLOSE            next_week_order_type = helper.CONTRACT_ORDER_TYPE_OPEN            max_qty, buy_limit_price, sell_limit_price = self.qty_and_price(buy_side, sell_side, price_diff)            if max_qty is None:                continue            if self.is_short_contract:                week_order_price = buy_limit_price                next_week_order_price = sell_limit_price            else:                week_order_price = sell_limit_price                next_week_order_price = buy_limit_price            # qty_delta > 0, 说明本周合约买入的比下周合约成交的多,下一次挂单,下周合约多成交一些            qty_delta = week_decreased - next_week_increased            if week_remaining_qty == 0 and abs(qty_delta) * next_week_order_price < self.bitvc_min_cash_amount:                continue            # 最多平掉本周合约的全部            qty = min(max_qty, week_remaining_qty)            qty_week = qty            cash_amount_week = qty_week * week_order_price            order_id_week = self.bitvc_order(self.coin_type, helper.CONTRACT_TYPE_WEEK,                                                 week_order_type, week_trade_type, week_order_price,                                                 cash_amount_week, leverage=self.lever)            executed_qty_week = self.bitvc_order_wait_and_cancel(self.coin_type, CONTRACT_TYPE_WEEK,                                                                     order_id_week)            if executed_qty_week is None:                executed_qty_week = 0            if week_contract_avg_price != 0:                executed_qty_week = executed_qty_week * week_order_price / week_contract_avg_price            else:                executed_qty_week = 0            qty_next_week = min(executed_qty_week + qty_delta,                                     accountInfo["bitvc_btc_available_margin"] * self.lever)            cash_amount_next_week = qty_next_week * next_week_order_price            order_id_next_week = self.bitvc_order(self.coin_type, helper.CONTRACT_TYPE_NEXT_WEEK,                                                       next_week_order_type, next_week_trade_type,                                                  next_week_order_price, cash_amount_next_week,                                                       leverage=self.lever)            self.bitvc_order_wait_and_cancel(self.coin_type, helper.CONTRACT_TYPE_NEXT_WEEK,                                             order_id_next_week)            self.cancel_all_pending_orders()

策略实盘运行结果展示

策略在运行了半个小时之后,成功地抓住了两次做市机会,胜率100%!在比特币基准收益为-0.03%的情况下,本策略30分钟收益达到0.12%。

这里写图片描述

总结

关于期货做市策略,我们用了三个帖子来给大家介绍了相关概念和两个源码以及运行结果。

我们最后回顾一下:做市策略是一种风险中立盘口价差套利的策略,是一种增加交易所流动性的策略。基本原理是:在盘口的卖一和买一价之间,插入委买单和委卖单,如果插入的两个单子都成交的话,做市商就吃到了买卖单之间的价差,而整个过程结束后,做市商所持有的头寸并没有变化。如果买卖单之间的价差扣除各种交易手续费之后还有盈余,那么该做市商就获得了相应的盈利。

关于做市策略就暂时分享到这里,欢迎大家给我留言讨论~

阅读全文
0 0
原创粉丝点击