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

来源:互联网 发布:寻侠天书突破数据 编辑:程序博客网 时间:2024/04/30 19:41

上一期(链接:http://blog.csdn.net/wequarter/article/details/74182279我们讲到做市策略的概念。做市策略是一种风险中立盘口价差套利策略,在策略中要注意时机的选择,净头寸的处理以及期货合约(移仓)的处理。这一期给大家带来做市的策略源码中的期货做市源码,关于源码的解析大家可以留言和我讨论。

一个典型的比特币期货做市策略源码分享

注意,以下的策略需要其他WeQuant基础类库的支持才能运行,这里仅给出策略核心源码,是为了让读者对做市策略本身有一个具体的认识,而不用去太纠结底层下单、统计收益、收发邮件、进程监控等技术细节。

期货做市策略源码:

#!/usr/bin/env python# -*- coding: utf-8 -*-from signalGenerator.futureSpotArb import *from signalGenerator.strategyConfig import changeFutureContractConfig as rollCfgimport time, threadingclass FutureMarketMaker(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(FutureMarketMaker, 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.trade_threshold = 0.0003 * 1.01        self.sell_cut = 0.6        self.buy_cut = 0.6        self.leverage = 5        self.remaining_delta_cash = 0         # 策略下单参数        self.coin_type = helper.HUOBI_COIN_TYPE_BTC        self.contract_type = helper.CONTRACT_TYPE_WEEK        self.initial_acct_info = None     # cancel all pending orders     def cancel_pending_orders(self):        orders = self.BitVCService.order_list(self.coin_type,self.contract_type)        while orders is not None and len(componentExtract(orders, "week", [])) > 0:            orders = componentExtract(orders, "week", [])            for order in orders:                if componentExtract(order, u"id", "") != "":                    order_id = order[u"id"]                    self.BitVCService.order_cancel(self.coin_type,self.contract_type, order_id)            orders = self.BitVCService.order_list(self.coin_type,self.contract_type)     def go(self):        self.timeLog("日志启动于 %s" % self.getStartRunningTime().strftime(self.TimeFormatForLog))        self.timeLog("开始cancel pending orders")        self.cancel_pending_orders()        self.timeLog("完成cancel pending orders")        while True:            # 期货移仓期间,程序一直sleep            if self.in_time_period(datetime.datetime.now(), rollCfg.CHANGE_CONTRACT_START_WEEK_DAY_FOR_NORMAL,                                      rollCfg.CHANGE_CONTRACT_END_WEEK_DAY_FOR_NORMAL, rollCfg.CHANGE_CONTRACT_START_TIME_FOR_NORMAL,                                      rollCfg.CHANGE_CONTRACT_END_TIME_FOR_NORMAL):                self.timeLog("当前处于移仓时间,程序进入睡眠状态……")                time.sleep(60)                continue            if self.timeInterval > 0:                self.timeLog("等待 %d 秒进入下一个循环..." % self.timeInterval)                time.sleep(self.timeInterval)            self.order_info_list = []            # 获取账户持仓信息            try:                account = copy.deepcopy(self.account_info)                acct_info = account["account_info"]                account_update_time = account["time"]            except Exception:                self.timeLog("尚未取得账户信息")                continue            # 检查账户获取时间            if account_update_time < self.latest_trade_time:                self.timeLog("当前账户信息时间晚于最近交易时间,需要重新获取")                continue            # setup initial account info            if self.initial_acct_info is None:                self.initial_acct_info = acct_info            short_pos_money_delta = acct_info["bitvc_btc_hold_money_week_short"] - self.initial_acct_info["bitvc_btc_hold_money_week_short"]            long_pos_money_delta = acct_info["bitvc_btc_hold_money_week_long"] - self.initial_acct_info["bitvc_btc_hold_money_week_long"]            self.remaining_delta_cash = long_pos_money_delta - short_pos_money_delta  # 代表着增加了多少开多的money,需要减去(sell)            if self.remaining_delta_cash != 0:                self.timeLog("剩余 %.4f 数量还没有平" % self.remaining_delta_cash)            # 查询bitvc深度数据            try:                bitvcDepth = copy.deepcopy(self.depth_data)["bitvc"]            except Exception:                self.timeLog("尚未取得bitvc深度数据")                continue            # 查看行情信息时间戳是否合理            timestamp_list = [bitvcDepth["time"]]            if not self.check_time(timestamp_list):                self.timeLog("获取的行情信息时间延迟过大,被舍弃,进入下一循环")                continue            self.timeLog("记录心跳信息...")            self.heart_beat_time.value = time.time()            asks = bitvcDepth["asks"]            bids = bitvcDepth["bids"]            bitvc_sell_1_price = float(asks[len(asks) - 1][0])            bitvc_buy_1_price = float(bids[0][0])            margin = bitvc_sell_1_price - bitvc_buy_1_price            future_order_sell_price = bitvc_sell_1_price - 0.5*margin*self.sell_cut            future_order_buy_price = bitvc_buy_1_price + 0.5*margin*self.buy_cut            future_order_sell_money = 100            future_order_buy_money = 100            if self.remaining_delta_cash > 0: #bought too much                future_order_sell_money += self.remaining_delta_cash                future_order_sell_price -= 0.2*margin*self.sell_cut                future_order_buy_price -= 0.1*margin*self.buy_cut            else:                future_order_buy_money += abs(self.remaining_delta_cash)                future_order_buy_price += 0.2*margin*self.buy_cut                future_order_sell_price += 0.1*margin*self.sell_cut            diff_percentage = (future_order_sell_price - future_order_buy_price)/future_order_sell_price            if diff_percentage < self.trade_threshold:                self.timeLog("future_order_sell_price: %.2f, future_order_buy_price: %.2f, diff percentage: %.6f%% smaller than trade threshold: %.6f%%, so ignore and continue" % ( future_order_sell_price, future_order_buy_price, diff_percentage*100, self.trade_threshold*100))                continue            bitvc_btc_hold_money_week_long = acct_info["bitvc_btc_hold_money_week_long"]            bitvc_btc_hold_money_week_short = acct_info["bitvc_btc_hold_money_week_short"]            global sold_money            sold_money = 0            global bought_money            bought_money = 0            # 策略下单参数            coin_type = self.coin_type            contract_type = self.contract_type            def loop1():                # place sell order                order_id_list_sell = []                if bitvc_btc_hold_money_week_long > future_order_sell_money:                    order_id_list_sell.append(self.bitvc_order(coin_type, contract_type, helper.CONTRACT_ORDER_TYPE_CLOSE, helper.CONTRACT_TRADE_TYPE_SELL, future_order_sell_price, future_order_sell_money, leverage=self.leverage))                else:                    if bitvc_btc_hold_money_week_long > 0:                        order_id_list_sell.append(self.bitvc_order(coin_type, contract_type, helper.CONTRACT_ORDER_TYPE_CLOSE, helper.CONTRACT_TRADE_TYPE_SELL, future_order_sell_price, bitvc_btc_hold_money_week_long, leverage=self.leverage))                    if future_order_sell_money-bitvc_btc_hold_money_week_long > 0:                        order_id_list_sell.append(self.bitvc_order(coin_type, contract_type, helper.CONTRACT_ORDER_TYPE_OPEN, helper.CONTRACT_TRADE_TYPE_SELL, future_order_sell_price, future_order_sell_money-bitvc_btc_hold_money_week_long, leverage=self.leverage))                if self.remaining_delta_cash > 0:                    bitvc_order_query_retry_maximum_times = 100                    bitvc_order_cancel_query_retry_maximum_times = 10                else:                    bitvc_order_query_retry_maximum_times = 100                    bitvc_order_cancel_query_retry_maximum_times = 10                global sold_money                for order_id in order_id_list_sell:                    if order_id is not None:                        tmp = self.bitvc_order_wait_and_cancel(coin_type, contract_type, order_id, returnProcessedMoney=True, bitvc_order_query_retry_maximum_times=bitvc_order_query_retry_maximum_times, bitvc_order_cancel_query_retry_maximum_times=bitvc_order_cancel_query_retry_maximum_times)                        if tmp is not None:                            sold_money += tmp                order_id_list_sell = []                if sold_money < future_order_sell_money and bought_money > 0: # buy side is partially filled or filled                    adjusted_future_order_sell_price = future_order_buy_price * (1 + 0.0003)                    adjusted_future_order_sell_money = future_order_sell_money - sold_money                    if bitvc_btc_hold_money_week_long - sold_money > adjusted_future_order_sell_money:                        order_id_list_sell.append(self.bitvc_order(coin_type, contract_type, helper.CONTRACT_ORDER_TYPE_CLOSE, helper.CONTRACT_TRADE_TYPE_SELL, adjusted_future_order_sell_price, adjusted_future_order_sell_money, leverage=self.leverage))                    else:                        if bitvc_btc_hold_money_week_long - sold_money > 0:                            order_id_list_sell.append(self.bitvc_order(coin_type, contract_type, helper.CONTRACT_ORDER_TYPE_CLOSE, helper.CONTRACT_TRADE_TYPE_SELL, adjusted_future_order_sell_price, bitvc_btc_hold_money_week_long - sold_money, leverage=self.leverage))                        if bitvc_btc_hold_money_week_long - sold_money < 0:                            #already opened short                            remaining_short = adjusted_future_order_sell_money                        else:                            remaining_short = adjusted_future_order_sell_money - (bitvc_btc_hold_money_week_long - sold_money)                        if remaining_short > 0:                            order_id_list_sell.append(self.bitvc_order(coin_type, contract_type, helper.CONTRACT_ORDER_TYPE_OPEN, helper.CONTRACT_TRADE_TYPE_SELL, adjusted_future_order_sell_price, remaining_short, leverage=self.leverage))                for order_id in order_id_list_sell:                    if order_id is not None:                        tmp = self.bitvc_order_wait_and_cancel(coin_type, contract_type, order_id, returnProcessedMoney=True, bitvc_order_query_retry_maximum_times=bitvc_order_query_retry_maximum_times, bitvc_order_cancel_query_retry_maximum_times=bitvc_order_cancel_query_retry_maximum_times)                        if tmp is not None:                            sold_money += tmp            def loop2():                # place buy order                order_id_list_buy = []                if bitvc_btc_hold_money_week_short > future_order_buy_money:                    order_id_list_buy.append(self.bitvc_order(coin_type, contract_type, helper.CONTRACT_ORDER_TYPE_CLOSE, helper.CONTRACT_TRADE_TYPE_BUY, future_order_buy_price, future_order_buy_money, leverage=self.leverage))                else:                    if bitvc_btc_hold_money_week_short > 0:                        order_id_list_buy.append(self.bitvc_order(coin_type, contract_type, helper.CONTRACT_ORDER_TYPE_CLOSE, helper.CONTRACT_TRADE_TYPE_BUY, future_order_buy_price, bitvc_btc_hold_money_week_short, leverage=self.leverage))                    if future_order_buy_money-bitvc_btc_hold_money_week_short > 0:                        order_id_list_buy.append(self.bitvc_order(coin_type, contract_type, helper.CONTRACT_ORDER_TYPE_OPEN, helper.CONTRACT_TRADE_TYPE_BUY, future_order_buy_price, future_order_buy_money-bitvc_btc_hold_money_week_short, leverage=self.leverage))                if self.remaining_delta_cash < 0:                    bitvc_order_query_retry_maximum_times = 100                    bitvc_order_cancel_query_retry_maximum_times = 10                else:                    bitvc_order_query_retry_maximum_times = 100                    bitvc_order_cancel_query_retry_maximum_times = 10                global bought_money                for order_id in order_id_list_buy:                    if order_id is not None:                        tmp = self.bitvc_order_wait_and_cancel(coin_type, contract_type, order_id, returnProcessedMoney=True, bitvc_order_query_retry_maximum_times=bitvc_order_query_retry_maximum_times, bitvc_order_cancel_query_retry_maximum_times=bitvc_order_cancel_query_retry_maximum_times)                        if tmp is not None:                            bought_money += tmp                order_id_list_buy = []                if bought_money < future_order_buy_money and sold_money > 0: # sell side is partially filled or filled                    adjusted_future_order_buy_price = future_order_sell_price * (1 - 0.0003)                    adjusted_future_order_buy_money = future_order_buy_money - bought_money                    if bitvc_btc_hold_money_week_short - bought_money > adjusted_future_order_buy_money:                        order_id_list_buy.append(self.bitvc_order(coin_type, contract_type, helper.CONTRACT_ORDER_TYPE_CLOSE, helper.CONTRACT_TRADE_TYPE_BUY, adjusted_future_order_buy_price, adjusted_future_order_buy_money, leverage=self.leverage))                    else:                        if bitvc_btc_hold_money_week_short - bought_money > 0:                            order_id_list_buy.append(self.bitvc_order(coin_type, contract_type, helper.CONTRACT_ORDER_TYPE_CLOSE, helper.CONTRACT_TRADE_TYPE_BUY, adjusted_future_order_buy_price, bitvc_btc_hold_money_week_short - bought_money, leverage=self.leverage))                        if bitvc_btc_hold_money_week_short - bought_money < 0:                            # already opened long                            remaining_long = adjusted_future_order_buy_money                        else:                            remaining_long = adjusted_future_order_buy_money - (bitvc_btc_hold_money_week_short - bought_money)                        if remaining_long > 0:                            order_id_list_buy.append(self.bitvc_order(coin_type, contract_type, helper.CONTRACT_ORDER_TYPE_OPEN, helper.CONTRACT_TRADE_TYPE_BUY, adjusted_future_order_buy_price, remaining_long, leverage=self.leverage))                for order_id in order_id_list_buy:                    if order_id is not None:                        tmp = self.bitvc_order_wait_and_cancel(coin_type, contract_type, order_id, returnProcessedMoney=True, bitvc_order_query_retry_maximum_times=bitvc_order_query_retry_maximum_times, bitvc_order_cancel_query_retry_maximum_times=bitvc_order_cancel_query_retry_maximum_times)                        if tmp is not None:                            bought_money += tmp            t1 = threading.Thread(target=loop1, name='LoopThread1')            t2 = threading.Thread(target=loop2, name='LoopThread2')            t1.start()            t2.start()            t1.join()            t2.join()            if len(self.order_info_list) > 0:                transaction_id = helper.getUUID()                for order_info in self.order_info_list:                    coinType = self.coinMarketType                    marketType = order_info["marketType"]                    order_id = order_info["order_id"]                    self.put_order_info_in_queue(coinType, marketType, order_id, transaction_id)            self.cancel_pending_orders()            self.latest_trade_time = time.time()


由于篇幅所限,本次只能给大家分享期货做市策略源码,下一期将继续给大家分享期货移仓程序源码,欢迎大家留言以及评论!

原创粉丝点击