精华内容
下载资源
问答
  • 算法交易中的智能做市策略
  • 市商机器人 做市策略实例 入门 根据您的需求修改配置。 然后执行run.py python3 -m run -config=<path>
  • 浅谈比特币期货做市策略(3)

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

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


    期货移仓程序源码:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    from signalGenerator.futureSpotArb import *
    from signalGenerator.strategyConfig import changeFutureContractConfig as rollCfg
    import time
    
    class 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%。

    这里写图片描述

    总结

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

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

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

    展开全文
  • 浅谈比特币期货做市策略(2)

    千次阅读 2017-07-05 18:26:31
    上一期我们讲到做市策略的概念以及做市策略的一些相关注意事项。(链接:https://uqer.io/community/share/5954a1f8b9a91400528dea07) 做市策略是一种风险中立盘口价差套利策略。在策略中要注意时机的选择,净头寸...

    上一期(链接: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 rollCfg
    import time, threading
    
    class 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()


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

    展开全文
  • 浅谈比特币期货做市策略(1)

    万次阅读 2017-07-03 12:02:43
    做市策略”是策略中最有名的一个,在这里我想结合自己的想法给大家分享一下自己的一些经验看法。 下面我们从概念说起。   一、什么是做市策略 做市策略(market-maker strategy)是一种风险中立(risk-neutral)...

    今天想和大家分享一下我做比特币期货的一些策略研究。“做市策略”是策略中最有名的一个,在这里我想结合自己的想法给大家分享一下自己的一些经验看法。

    下面我们从概念说起。

     

    一、什么是做市策略

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

    做市策略是一种增加交易所流动性的策略,一般来讲,成熟的交易市场为了提升自身的流动性,会用低佣金(甚至为做市商提供流动性奖励金)的办法,吸引做市商来该市场做市。

     

    二、做市策略需要注意的事项

     

    1 做市时机的选择

    做市商本质上是整个市场的交易对手方。如果市场呈现急剧的单边行情,做市商下达的买卖委托单会大概率出现单边成交的情况,因此做市商手中就会积累大量的风险头寸,这是做市商不想承担的风险。因此,做市商在选择是否下达做市指令之前,都会预判一下市场的趋势明显程度,如果市场短期内呈现非常明显的趋势信号,做市商就会相应地减少自己的做市单数量(甚至停止做市)

     

    2 净头寸的处理

    做市商手中累计的净头寸,可以通过很多种办法来处理,下面列举其中两种:

     

    (1)在下一次做市时,处理掉累积的净头寸。比如做市商目前净头寸有2BTC,下次做市时,他就可以下达一个卖3BTC的委卖单,一个买1BTC的委买单。这种做法好处是净头寸可以及时得到处理,坏处是净头寸处理的时机(价格)可能不是最优的。

     

    (2)第二种方法是开立另外一个独立的程序,对累积的净头寸进行成本计算,然后按照成本价*(1+一定比例的手续费+一定比例的profit margin),将该头寸反向甩出市场,甩出方法又有两种:a. 按限价单从价优到价劣依次甩出市场,超时不成交的部分则撤单,等待下次机会;b. 先按限价单从价优到价劣依次甩出市场,超时不成交的部分,则按市价单甩货。第一种方法的好处是甩货成本可控,但是甩货周期可能会拖得比较长;第二种方法则能有效地控制甩货周期,但是成本不可控,孰优孰劣,需要做市商根据自己的风险偏好慎重考虑。

     

    3 期货换合约(移仓)的处理

     

    期货合约都有一个到期日,在到期日结束时刻的前几个小时,我们不建议做市商继续做市,而是利用这几个小时,将即将到期的期货合约进行移仓。移仓的意思就是平掉当前期货合约的仓位,然后再开同样仓位大小的下周合约。当然,移仓也是需要考虑成本的。如果当前持仓是多头,那么我们希望移仓的时间点是在下周期货贴水最厉害的时候;反之,我们则希望移仓的时间点是在下周期货升水最厉害的时候。等移仓做完以后,做市策略继续恢复执行。

    概念先简单介绍到这里,后面我会继续为大家分享做市策略,也欢迎大家留言讨论。

    展开全文
  • 数字货币稳定币对网格做市策略

    千次阅读 2021-07-08 20:04:42
    我们知道,交易手续费是高频交易的天敌,频率越高,手续费也越高,而币安对于稳定币对的0交易手续费,为我们的高频网格做市策略,提供了最好的环境。从币安手续费的延续来看,零费率的优惠活动已经多次延期,这一次...

     ​​

    数量技术宅团队在CSDN学院推出了量化投资系列课程

    欢迎有兴趣系统学习量化投资的同学,点击下方链接报名:

    量化投资速成营(入门课程)

    Python股票量化投资

    Python期货量化投资

    Python数字货币量化投资

    C++语言CTP期货交易系统开发

    数字货币JavaScript语言量化交易系统开发


    什么是稳定币对

    稳定币是数字货币中特有的一类资产,不同于BTC、ETH等币值大幅波动的数字货币, 稳定币通常锚定美元等法币或者其他价值稳定的资产,因此为加密货币市场带来了难得的稳定性。

    其中,USDT是最著名,也是目前市值最大的稳定币,其市值达到了目前所有加密货币的第3名。而除了USDT外,市场上发行的稳定币种数量日趋扩大。以USDC、TUSD为代表的稳定币,其交易额、市值正在逐步靠拢USDT,而主流交易所币安、火币,也分别推出了自己的稳定币BUSD、HUSD。目前,BUSD的市值位于所有稳定币的第6名。

    稳定币种数量增加,带来了稳定币配对的交易机会,我们以币安和火币交易所为例,其中,币安上线了BUSD/USDT、SUSD/USDT、TUSD/USDT、USDC/USDT、TUSD/BUSD、USDC/BUSD等多个稳定币货币对。

    而火币也上线了USDC、USDT、HUSD之间,两两配对的稳定币货币对。

    稳定币对的交易特征

    1. 稳定币对均值回复概率接近百分百:偏离幅度越大、交易机会越好、预期收益越高

      我们从稳定币对设计的底层逻辑出发,目前几乎所有主流的稳定币,对标的都是美元。如果其中一种储备稳定币(如USDT)的价格超过了1美元,而另一种稳定币USDC的价格低于1美元,那么就会有套利者进场交易,将USDT卖出换成DUSD,以将DUSD价格重新拉回1美元。 当两个稳定币对的价差越来越大,此时从高价币种兑换成低价币种的预期收益也会越来越高,并且这个收益是接近无风险的收益,会有源源不断的套利交易者进场,直到价差被拉平。

      我们观察币安、火币市场的稳定币交易对的历史行情,也能很明显的发现这一确定性的规律。以BUSD/USDT为例,长期来看,稳定币对的交易均值,在十分接近1的位置,且一直稳定在这个位置。

      我们再来看火币交易所的稳定币对,USDT/HUSD,也是一模一样的规律,长期均值稳定在1附近,价差偏离是绝佳交易机会。

    2. 币安部分稳定币对:交易零手续费

      在币安交易所交易稳定币对,相比较其他交易所,还有一个显著的优势,币安对于BUSD/USDT、USDC/BUSD、TUSD/BUSD等货币对采用0交易手续费。

      我们知道,交易手续费是高频交易的天敌,频率越高,手续费也越高,而币安对于稳定币对的0交易手续费,为我们的高频网格做市策略,提供了最好的环境。从币安手续费的延续来看,零费率的优惠活动已经多次延期,这一次即使到年底,也大概率会延期。

    稳定币对网格做市原理

    介绍完了稳定币对的基础知识,我们来看稳定币对,能够带来怎样的交易机会:

    首先,稳定币对不稳定,日常波动率带来的机会很丰富。在很多人的直观印象中,稳定币对应该是长期不怎么波动的,在实际情况并非如此,稳定币的日常波动率就不小,足够我们做交易了。比如我们截取的最近一段BUSD/USDT对的行情,可以看到,最低到过0.9883,而最高到1.0013,中间有超过1.3%的振幅。足以说明,稳定币对,并不稳定。

    我们知道,标的资产的波动率是交易策略利润的来源。假设我们通过网格+做市策略,能够每天赚取BUSD/USDT币对1/3的日波动率,在过去两年不到的时间,累积下来能够获得40%以上的总收益率,和平均20%以上的年化收益率。

    其次,除了日常波动率带来的机会,如果仔细观察稳定币对的挂单盘口可以发现,挂盘往往集中的距离最新价的几个档位,远处的挂单很稀薄。这就导致了,一旦出现市价的超大单,稳定币对市场所提供的流动性,是不够的。这种流动性击穿来带的机会,反应在市场中,是长长的上、下引线,也就是我们俗称的”插针行情“。

    我们任意选取一些货币对,都能看到一些很夸张的插针行情,少的收益有5%、10%,多的收益甚至达到几倍,而且这样的行情,出现的频率还不低。通过设置较大间隔的网格交易,我们完全有机会抓到这样的行情的。

    最后,由于稳定币对的内生逻辑,造就了其偏离必回归,偏离幅度越大回归收益越高的特征。我们在使用网格策略的时候,是无需担心网格交易应用在传统资产中会发生的网格被击穿,亏损无限扩大的致命弱点。相反,一旦网格被击穿,说明此时市场犯了大错误,我们可以用更多的闲置资金,在更好的位置,进行加仓。

    总结一下,根据稳定币对的形成原理和特征,我们可以采用网格+高频做市相结合的方式,来对稳定币构建交易策略。既可以通过小网格+高频做市,来捕捉那些零费率的稳定币对的日内波动收益;也可以通过大网格,来捕捉市场插针犯错时的大机会;当然,如果将大、小网格结合,那么我们的交易将会更加稳定。

    稳定币网格做市自动交易

    由于数字货币是7*24小时不间断连续交易的,不论是高频网格做市,还是大网格捕捉插针,手工交易都不太现实。如果是高频网格做市,我们需要用程序持续不断的捕捉市场的小波段,在零手续费的前提下尽可能多的交易,不断重复挂单开仓,挂单平仓,挂单开仓这个过程;而如果是大网格捕捉插针,我们需要尽可能同时监控多个交易所的多个货币对,有时候插针行情带来的盘口巨大空档,我们甚至能用程序做好几个来回,拿到比k线上看到的更多收益。

    第一,稳定币对网格做市自动交易,我们设计了币安版本、火币版本

    币安版本:由于币安零手续费、且以BUSD/USDT为代表的币对,交易极其活跃,我们既可以通过小网格高频做市,捕捉日常波动带来的机会,也可以通过大网格捕捉流动性击穿的机会。

    火币版本:火币目前的稳定币对需要交易手续费,我们可以通过大网格捕捉流动性击穿的机会,大网格对手续费不敏感,与此同时,火币也会在某些活动时间开发HUSD相关币对的零手续费活动,我们也可以在活动期间,应用小网格高频做市策略。

    第二,自动交易程序做到了高度个性化

    我们所设计的网格做市自动交易程序,其核心参数是高度个性化的:

    网格中心既可以由用户指定固定值,也可以由程序根据过去一段时间的行情计算;

    网格大小自由设定:帮助我们用一套程序捕捉两类机会,大网格捕捉流动性击穿,小网格捕捉零费率币对的日内高频波动;

    网格数量&单网格下单量:小资金、大资金可以根据各自收益风险偏好,调整网格数量和单格下单量,从而实现风控。

    第三,自动交易程序的容错机制

    首先,数字货币交易所常有拔网线的情况发生,我们的程序能够做到在拔网线前和恢复后的无缝衔接。

    其次,即使不小心关闭程序,或是由于某些不可抗力停止程序,程序在启动时会恢复此前所有挂单,并继续交易。

    最后,一起来看一下,我们的程序在币安稳定币对BUSD/USDT上的一些交易记录(每一笔交易手续费都是0)。

    想要获取本次分享的完整代码,或是任何关于数据分析、量化投资的问题,欢迎添加技术宅微信:sljsz01,一起交流

     图片


    往期干货分享推荐阅读

    万物皆可秒——淘宝秒杀Python脚本,扫货618,备战双11!

    数字货币资金费策略

    数字货币无风险收益率又双叒叕扩大了!

    分享一个年化15%以上的无风险套利机会

    【数量技术宅|交易系统开发系列分享】网格交易系统开发

    通过深度学习股价截面数据分析和预测股票价格

    剖析一个数字货币高频策略

    数字货币交易信号实时预警推送(含群聊)

    Omega System Trading and Development Club内部分享策略Easylanguage源码

    量化交易如何选择云服务器,如何在本地远程开发与调试云服务器程序

    一个真实数据集的完整机器学习解决方案(下)

    一个真实数据集的完整机器学习解决方案(上)

    如何使用交易开拓者(TB)开发数字货币策略

    股指期货高频数据机器学习预测

    如何使用TradingView(TV)回测数字货币交易策略

    如何投资股票型基金?什么时间买?买什么?

    【数量技术宅|量化投资策略系列分享】基于指数移动平均的股指期货交易策略

    AMA指标原作者Perry Kaufman 100+套交易策略源码分享

    【 数量技术宅 | 期权系列分享】期权策略的“独孤九剑”

    如何获取免费的数字货币历史数据

    【数量技术宅|金融数据分析系列分享】套利策略的价差序列计算,恐怕没有你想的那么简单

    【数量技术宅|量化投资策略系列分享】成熟交易者期货持仓跟随策略

    【数量技术宅|量化投资策略系列分享】多周期共振交易策略

    【数量技术宅|金融数据分析系列分享】为什么中证500(IC)是最适合长期做多的指数

      大宗商品现货数据不好拿?商品季节性难跟踪?技术宅带你Python爬虫一键解决没烦恼

    【数量技术宅|金融数据分析系列分享】如何正确抄底商品期货、大宗商品

    【数量技术宅|量化投资策略系列分享】股指期货IF分钟波动率统计策略

    【数量技术宅 | Python爬虫系列分享】实时监控股市重大公告的Python爬虫

    展开全文
  • 期权做市策略简介

    千次阅读 2019-07-31 08:31:51
    期权做市策略与其他资产如股票、债券、期货、外汇的市并没有本质不同,最为核心的策略都是以获取买卖价差,规避单边风险为基础的。一个优秀的市商策略是市机构立足于市场的核心竞争力,被视为公司的核心机密。...
  • 策略需要搭配火币API 使用,此策略利用30分钟的MA5和MA30判断趋势,当MA5上穿MA30时就开多,不断开多,平多,开多,平多,赚取差价,我设置是0.02的莱特。你可以根据实际修改。同样的下穿MA30就开空。
  • 做市商交易策略-期货

    2020-12-09 14:29:10
    但如果当时合约价格持续走高或走低,做市商没有对手方能够成交,这时就不得不提高自己的买价或降低自己的卖价进行交易,做市商就会亏损。因此,做市商并不是稳赚不赔的。 2. 策略思路 第一步:订阅tick数据(只有...
  • 做市策略(Market Making Strategy)

    万次阅读 2013-06-09 17:14:15
    高频交易策略中最主要的一类策略就是Market Making,即通过赚取买卖价差来获取利润,该策略虽然应用于连续竞价机制,但由于与传统的做市商市场类似,所以命名为Market Making。目前有几篇学术论文已经对策略设计了...
  • alphahunter 本系统实现数据采集,存储,依次,研究,仿真模拟,..../web量化交易接口API(纯websocket版),利用此接口可以支持C / C ++,Go,Java,Javascript等语言进行策略开发 快速体验 框架说明 本框架使用的是P
  • 论文研究-基于限价订单簿的最优高频做市策略研究.pdf, 建立具有成交风险和存货风险的价差过程模型,在引入存货惩罚函数的同时将策略的目标确定为效用最大化.将策略...
  • 经典量化策略——做市商交易(期货)

    千次阅读 2019-01-09 17:10:02
    阅读原文
  • 想用python设计一个简单的基于做市商的股票高频交易策略,之前的主要class都已经写好了,现在在主程序里面实现策略,但是始终想不出一个合理的代码结构来实现,有没有哪位大神敢尝试啊哈哈: 先给出模仿的论文策略图...
  • ATR作为一种入场工具的应用示例 入场背景:(记住,入场背景告诉我们不久将会出现交易机会,而入场触发器告诉我们现在入场交易) 波动区间收缩背景:许多技术派已经注意到大幅价格运动往往出现在价格平静的横盘...
  • 相信来查找宜昌石油公司竞争策略研究的你对于这一行业多少也有些了解,而宜昌石油公司竞争策略研究就...该文档为宜昌石油公司竞争策略研究,是一份很不错的参考资料,具有较高参考价值,感兴趣的可以下载看看
  • 临沂小学语文教学策略.doc
  • 临沂小学数学教学策略.doc
  • 衡阳县域电商发展策略研究.pdf
  • 金华仙湖美墅宣传推广策略.pptx
  • 沈阳演出团体的营销策略.zip
  • 黄山会展旅游的发展策略.zip
  • 黄山会展旅游的发展策略.doc
  • 耒阳城乡医疗保障发展策略.pdf
  • 针对黑龙江省煤炭产业现状,分析了在煤炭产能过剩、煤炭产业疲软态势下,作为资源型城市,黑龙江省双鸭山面临着煤炭...在目前经济状况下,抓住机遇,加快产业结构调整,保证双鸭山经济持续发展,找出应对策略,势在必行。
  • 2019万科西市区项目营销策略提案.pdf
  • 湘潭某项目营销策略分析报告.doc
  • 数字货币趋势策略实盘

    千次阅读 2021-09-11 18:02:16
    ​​ 数量技术宅团队在CSDN学院推出了量化投资系列课程 ... 量化投资速成营(入门课程) ...数字货币稳定币对网格做市策略 期现套利策略 大多属于套利、对冲类型的策略,所谓套利对冲,指的是.
  • 深圳地铁商业物业经营策略研究.docx

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 33,803
精华内容 13,521
关键字:

做市策略