Type/to search
2
Follow
481
Followers
浅谈数字货币做市策略(2):盘口策略
Discussions
Created 2025-08-01 11:28:35  Updated 2025-08-04 14:15:40
 0
 1218

img

前言

在上一篇文章《数字货币中的刷量型对敲策略》中,我们详细介绍了一种通过同价买卖来积累交易量的策略框架。该策略的主要目的是获取交易所返佣或等级优惠,而非通过价差套利获得收益。虽然刷量型对敲策略在学习交易框架架构方面具有参考价值,但其实际盈利能力有限,且可能面临合规风险。

本篇文章将在前文的基础上,介绍另一种更具实用价值的做市策略——盘口策略。与刷量型对敲策略不同,盘口策略是一种真正的套利策略,通过在买卖价格之间设置价差来获取收益,更符合传统做市商的盈利模式。

⚠️ 重要声明

本文展示的盘口策略代码仅为学习参考框架,不具有任何实盘运行经验。文中的策略实现仅用于技术学习和研究目的,未经过实际市场环境的充分验证。读者在参考本文内容时,务必进行充分的回测验证和风险评估,切勿直接用于实盘交易。


盘口策略原理

盘口策略是一种利用市场订单簿(即盘口深度)进行套利的做市策略。在这种策略下,做市商通过在买卖价格的差距内,根据市场波动动态调整挂单价格,进行挂单和撤单操作,从而利用市场的流动性和短期价格波动来获得利润。

核心特点

  1. 动态调整挂单价格:根据市场深度和价格波动,动态调整买卖单的价格,以提高成交概率。
  2. 控制挂单数量:根据账户资金和持仓情况,控制挂单数量,避免过度暴露在市场风险中。
  3. 订单状态管理:定期检查订单状态,处理未完成的订单。

与对敲策略的区别

特征刷量型对敲策略盘口策略
买卖价格相同价格不同价格(有价差)
盈利模式交易所返佣/激励买卖价差
风险暴露低(同价成交)高(价格波动风险)
实用性有限较高

盘口策略的优势

  • 提高市场流动性:通过在盘口挂单,增加市场的买卖深度,吸引更多交易者参与。
  • 赚取买卖价差:通过提供流动性,做市商可以赚取买卖价差,从而获得收益。
  • 灵活应对市场波动:盘口策略可以根据市场波动动态调整挂单价格,降低市场风险。

盘口策略的挑战

  • 市场风险:市场价格波动可能导致做市商的挂单无法成交,甚至造成亏损。
  • 资金压力:做市商需要足够的资金来维持盘口的买卖深度,资金不足可能导致策略失效。
  • 订单管理复杂:盘口策略需要定期检查订单状态,处理未完成的订单,增加了策略的复杂性。

盘口策略结构

与对敲策略一致,本文的代码实现了一个基于盘口策略的做市策略,主要分为两个类:

  1. MidClass:交易所中间层,负责与交易所的接口交互,获取市场数据、账户信息、订单状态等。
  2. MarketMaker:做市策略类,负责执行盘口策略,动态生成挂单价格,生成挂单、检查订单状态、更新策略状态等。

盘口策略流程

1. 初始化

MarketMaker 类的初始化方法中,首先获取交易所的精度信息,并初始化策略参数,如交易量精度、价格精度等。

python
self.precision_info = self.exchange_mid.get_precision() # 获取精度信息 self.price_precision = self.precision_info['price_precision'] # 价格精度 self.amount_precision = self.precision_info['amount_precision'] # 交易量精度

2. 生成盘口挂单字典

盘口策略的核心是生成盘口挂单字典,包含买卖价格和数量。代码中通过计算中间价和价格偏移量,生成盘口挂单字典。

3. 盘口挂单价格的移动

盘口挂单价格的移动是通过计算价格偏移量来实现的。价格偏移量是根据价格范围(price_range)和最小价格间隔(min_price_step)计算得出的。

python
price_offset = price_range - self.pending_order_count * min_price_step # 计算价格偏移量 do_trade = price_offset > 0
  • price_range:价格范围,表示挂单价格与中间价的偏离范围。
  • min_price_step:最小价格间隔,表示每次挂单价格的最小调整步长。
  • price_offset:价格偏移量,表示当前挂单价格与中间价的偏离量。

如果价格偏移量大于 0,则表示可以继续挂单;否则,重置挂单次数。

4. 生成挂单字典

根据价格偏移量,计算买卖价格,并生成挂单字典。

python
if do_trade: buy_price = mid_price - price_offset # 计算买价 buy_price = round(buy_price, self.price_precision) # 四舍五入买价 sell_price = mid_price + price_offset # 计算卖价 sell_price = round(sell_price, self.price_precision) # 四舍五入卖价 trade_dict = { 'do_trade': do_trade, 'buy_price': buy_price, 'sell_price': sell_price, 'amount': trade_amount } Log('返回盘口挂单字典:', trade_dict) return trade_dict else: self.pending_order_count = 0 # 重置挂单次数
  • buy_price:买价,计算为中间价减去价格偏移量。
  • sell_price:卖价,计算为中间价加上价格偏移量。
  • trade_dict:挂单字典,包含买卖价格和数量。

5. 执行盘口交易

根据生成的盘口挂单字典,执行盘口交易。代码中通过调用交易所中间层的 create_order 方法,同时挂出买单和卖单。

python
def make_trade_by_dict(self, trade_dict): if trade_dict['do_trade']: buy_id = self.exchange_mid.create_order('buy', trade_dict['buy_price'], trade_dict['amount']) # 挂买单 sell_id = self.exchange_mid.create_order('sell', trade_dict['sell_price'], trade_dict['amount']) # 挂卖单 self.traded_pairs['pan_kou'].append({ 'buy_id': buy_id, 'sell_id': sell_id, 'init_time': time.time(), 'amount': trade_dict['amount'] })

6. 检查订单状态

定期检查订单状态,处理未完成的订单。订单状态处理逻辑与对敲策略类似,但由于存在价差,部分成交的情况会产生实际的盈利或亏损。

盘口策略的主要缺点

1. 盘口挂单价格移动不够灵活

本策略中的价格调整机制相对简单,存在以下限制:

python
price_offset = price_range - self.pending_order_count * min_price_step # 计算价格偏移量
  • 线性调整限制:价格偏移量采用线性递减的方式,无法根据市场实际波动率进行动态调整
  • 参数固化price_rangemin_price_step 是固定参数,不能根据市场状况实时调整
  • 响应迟滞:当市场价格快速变化时,策略的价格调整可能跟不上市场节奏
  • 缺乏市场感知:没有考虑订单簿深度、交易量等市场微观结构因素

改进方向

  • 引入基于波动率的动态价格调整机制
  • 根据市场深度和流动性调整挂单价格
  • 增加对市场趋势的判断,避免逆势挂单

2. 库存风险(Inventory Risk)

盘口策略面临严重的库存风险问题:

风险表现

  • 单边成交风险:当只有买单或卖单成交时,会导致持仓不平衡
  • 方向性风险:在趋势市场中,可能大量累积单向持仓
  • 资金占用:过多的库存会占用大量资金,影响策略效率

代码中的风险点

python
if buy_order_status['Status'] == ORDER_STATE_PENDING: self.sell_amount += traded_pair['amount'] # 只有卖单成交,积累空头持仓 elif sell_order_status['Status'] == ORDER_STATE_PENDING: self.buy_amount += traded_pair['amount'] # 只有买单成交,积累多头持仓

库存风险的影响

  • 盈利能力下降:单边持仓在不利价格变动时会产生亏损
  • 流动性压力:需要额外的资金来对冲库存风险
  • 策略失效:极端情况下可能导致策略无法继续运行

风险管理措施

  • 库存限制:设置最大持仓限制,防止过度累积
  • 动态对冲:当库存超过阈值时,主动平仓或对冲
  • 价格倾斜:根据当前库存调整买卖价格,鼓励反向交易

策略总结

盘口策略是一种基于市场深度的做市策略,通过动态调整买卖单的价格和数量,维持市场的流动性。与刷量型对敲策略相比,盘口策略具有以下特点:

✅ 优势

  • 通过价差获取真正的套利收益
  • 符合传统做市商的盈利模式
  • 提供真正的市场流动性

❌ 挑战

  • 面临市场价格波动风险
  • 需要更复杂的风险管理
  • 对资金和技术要求更高
  • 价格调整机制不够灵活:线性的价格移动机制难以适应复杂的市场环境
  • 库存风险突出:单边成交容易导致持仓不平衡,在趋势市场中风险尤为显著

🔮 未来优化方向

针对当前盘口策略存在的不足,未来可以从以下几个方向进行优化改进:

  1. 动态做市策略

    • 基于市场波动率的自适应价格调整
    • 根据订单簿深度动态调整挂单策略
    • 引入机器学习预测市场方向
  2. 库存管理策略

    • 实时库存监控和风险评估
    • 动态对冲机制和库存平衡算法
    • 基于库存状态的价格倾斜策略
  3. 多层级做市策略

    • 在多个价格层级同时提供流动性
    • 分散单点风险,提高整体稳定性
    • 更接近专业做市商的实际操作
  4. 智能风险管理

    • 实时风险指标监控
    • 自动止损和风险控制机制
    • 市场异常情况的应急处理

策略代码(修正版)

python
import time, json class MidClass: def __init__(self, exchange_instance): ''' 初始化交易所中间层 Args: exchange_instance: FMZ的交易所结构 ''' self.init_timestamp = time.time() # 记录初始化时间 self.exchange = exchange_instance # 保存交易所对象 self.exchange_name = self.exchange.GetName() # 获取交易所名称 self.trading_pair = self.exchange.GetCurrency() # 获取交易对名称(如 BTC_USDT) def get_precision(self): ''' 获取交易对的精度信息 Returns: 返回包含精度信息的字典,失败时返回 None ''' symbol_code = self.exchange.GetCurrency() ticker = self.exchange.GetTicker(symbol_code) # 回测系统需要 exchange_info = self.exchange.GetMarkets() data = exchange_info.get(symbol_code) if not data: Log("获取市场信息失败", GetLastError()) return None # 获取该交易对的精度信息 self.precision_info = { 'tick_size': data['TickSize'], # 价格精度 'amount_size': data['AmountSize'], # 数量精度 'price_precision': data['PricePrecision'], # 价格小数位精度 'amount_precision': data['AmountPrecision'], # 数量小数位精度 'min_qty': data['MinQty'], # 最小下单数量 'max_qty': data['MaxQty'] # 最大下单数量 } return self.precision_info def get_account(self): ''' 获取账户信息 Returns: 获取信息成功返回 True,获取信息失败返回 False ''' self.balance = '---' # 账户余额 self.amount = '---' # 账户持仓量 self.frozen_balance = '---' # 冻结余额 self.frozen_stocks = '---' # 冻结持仓量 self.init_balance = None self.init_stocks = None self.init_equity = None try: account_info = self.exchange.GetAccount() # 获取账户信息 self.balance = account_info['Balance'] # 更新账户余额 self.amount = account_info['Stocks'] # 更新持仓量 self.frozen_balance = account_info['FrozenBalance'] # 更新冻结余额 self.frozen_stocks = account_info['FrozenStocks'] # 更新冻结持仓量 self.equity = self.balance + self.frozen_balance + (self.amount + self.frozen_stocks) * self.last_price if not self.init_balance or not self.init_stocks or not self.init_equity: if _G("init_balance") and _G("init_balance") > 0 and _G("init_stocks") and _G("init_stocks") > 0: self.init_balance = round(_G("init_balance"), 2) self.init_stocks = round(_G("init_stocks"), 2) self.init_equity = round(_G("init_equity"), 2) else: self.init_balance = round(self.balance + self.frozen_balance, 2) self.init_stocks = self.amount + self.frozen_stocks self.init_equity = round(self.init_balance + (self.init_stocks * self.last_price), 2) _G("init_balance", self.init_balance) _G("init_stocks", self.init_stocks) _G("init_equity", self.init_equity) Log('获取初始eqity', self.init_equity) self.profit = self.equity - self.init_equity self.profitratio = round((self.equity - self.init_equity)/self.init_equity, 4) * 100 return True except: return False # 获取账户信息失败 def get_ticker(self): ''' 获取市价信息(如买一价、卖一价、最高价、最低价等) Returns: 获取信息成功返回 True,获取信息失败返回 False ''' self.high_price = '---' # 最高价 self.low_price = '---' # 最低价 self.sell_price = '---' # 卖一价 self.buy_price = '---' # 买一价 self.last_price = '---' # 最新成交价 self.volume = '---' # 成交量 try: ticker_info = self.exchange.GetTicker() # 获取市价信息 self.high_price = ticker_info['High'] # 更新最高价 self.low_price = ticker_info['Low'] # 更新最低价 self.sell_price = ticker_info['Sell'] # 更新卖一价 self.buy_price = ticker_info['Buy'] # 更新买一价 self.last_price = ticker_info['Last'] # 更新最新成交价 self.volume = ticker_info['Volume'] # 更新成交量 return True except: return False # 获取市价信息失败 def get_depth(self): ''' 获取深度信息(买卖盘的挂单列表) Returns: 获取信息成功返回 True,获取信息失败返回 False ''' self.ask_orders = '---' # 卖盘挂单列表 self.bid_orders = '---' # 买盘挂单列表 try: depth_info = self.exchange.GetDepth() # 获取深度信息 self.ask_orders = depth_info['Asks'] # 更新卖盘挂单列表 self.bid_orders = depth_info['Bids'] # 更新买盘挂单列表 return True except: return False # 获取深度信息失败 def get_ohlc_data(self, period=PERIOD_M5): ''' 获取K线信息 Args: period: K线周期,PERIOD_M1 指1分钟, PERIOD_M5 指5分钟, PERIOD_M15 指15分钟, PERIOD_M30 指30分钟, PERIOD_H1 指1小时, PERIOD_D1 指一天。 ''' self.ohlc_data = self.exchange.GetRecords(period) # 获取K线数据 def create_order(self, order_type, price, amount): ''' 提交一个挂单信息 Args: order_type:挂单类型,'buy'指挂买单,'sell'指挂卖单 price:挂单价格 amount:挂单数量 Returns: 挂单Id号,可用以取消挂单 ''' if order_type == 'buy': try: order_id = self.exchange.Buy(price, amount) # 提交买单 except: return False # 买单提交失败 elif order_type == 'sell': try: order_id = self.exchange.Sell(price, amount) # 提交卖单 except: return False # 卖单提交失败 return order_id # 返回订单ID def get_orders(self): ''' 获取未完成的订单列表 Returns: 未完成的订单列表 ''' self.open_orders = self.exchange.GetOrders() # 获取未完成订单 return self.open_orders def cancel_order(self, order_id): ''' 取消一个挂单信息 Args: order_id:希望取消的挂单ID号 Returns: 取消挂单成功返回 True,取消挂单失败返回 False ''' return self.exchange.CancelOrder(order_id) # 取消订单 def refresh_data(self): ''' 刷新信息(账户、市价、深度、K线) Returns: 刷新信息成功返回 'refresh_data_finish!' 否则返回相应刷新失败的信息提示 ''' if not self.get_ticker(): # 刷新市价信息 return 'false_get_ticker' if not self.get_account(): # 刷新账户信息 return 'false_get_account' if not self.get_depth(): # 刷新深度信息 return 'false_get_depth' try: self.get_ohlc_data() # 刷新K线信息 except: return 'false_get_K_line_info' return 'refresh_data_finish!' # 刷新成功 class MarketMaker: def __init__(self, mid_class): ''' 初始化做市策略 Args: mid_class: 交易所中间层对象 ''' self.exchange_mid = mid_class # 交易所中间层对象 self.precision_info = self.exchange_mid.get_precision() # 获取精度信息 self.done_amount = {'pan_kou': 0} # 已完成交易量 # 修正:正确分配精度信息 self.price_precision = self.precision_info['price_precision'] # 价格精度 self.amount_precision = self.precision_info['amount_precision'] # 交易量精度 self.traded_pairs = {'pan_kou': []} # 已挂单的交易对 self.pending_orders = [] # 未完成的订单状态 self.pending_order_count = 0 # 挂单次数 self.buy_amount = 0 self.sell_amount = 0 self.fee = 0 self.fee_rate = 0.08 / 100 self.chart = { "__isStock": True, "tooltip": {"xDateFormat": "%Y-%m-%d %H:%M:%S, %A"}, "title": {"text": "挂单数量"}, "xAxis": {"type": "datetime"}, "yAxis": { "title": {"text": "挂单数量"}, "opposite": False }, "series": [ {"name": "挂单买量", "id": "挂单买量", "data": []}, {"name": "挂单卖量", "id": "挂单卖量", "dashStyle": "shortdash", "data": []} ] } def refresh_data(self): ''' 刷新数据(账户、市价、深度、K线) ''' self.exchange_mid.refresh_data() # 刷新交易所数据 self.position_amount = 0 if isinstance(self.exchange_mid.amount, str) else self.exchange_mid.amount # 持仓量 self.available_balance = 0 if isinstance(self.exchange_mid.balance, str) else self.exchange_mid.balance # 账户余额 self.can_buy_amount = self.available_balance / float(self.exchange_mid.buy_price) # 可买的数量 self.mid_price = (self.exchange_mid.sell_price + self.exchange_mid.buy_price) / 2 # 中间价 def make_trade_by_dict(self, trade_dict): ''' 根据交易字典执行交易 Args: trade_dict: 交易字典 ''' Log('4按照字典开始交易') self.refresh_data() # 刷新数据 if trade_dict['do_trade']: Log('当前账户资金: 币数余额: ', self.position_amount, '资金余额: ', self.can_buy_amount) Log('检查开仓: 币数限制: ', self.position_amount > trade_dict['amount'], '资金限制: ', self.can_buy_amount > trade_dict['amount']) if self.position_amount > trade_dict['amount'] and self.can_buy_amount > trade_dict['amount']: buy_id = self.exchange_mid.create_order('buy', trade_dict['buy_price'], trade_dict['amount']) # 挂买单 sell_id = self.exchange_mid.create_order('sell', trade_dict['sell_price'], trade_dict['amount']) # 挂卖单 self.traded_pairs['pan_kou'].append({ 'buy_id': buy_id, 'sell_id': sell_id, 'init_time': time.time(), 'amount': trade_dict['amount'] }) self.last_time = time.time() # 更新上次交易时间 def handle_pending_orders(self): ''' 处理未完成的订单 ''' pending_orders = self.exchange_mid.get_orders() # 获取未完成订单 if len(pending_orders) > 0: for order in pending_orders: self.exchange_mid.cancel_order(order['Id']) # 取消未完成订单 def make_pankou_dict(self, price_range, min_price_step, trade_amount): ''' 生成盘口挂单字典 Args: price_range: 价格范围 min_price_step: 最小价格间隔 trade_amount: 每次交易量 Returns: 盘口挂单字典列表 ''' Log('3制作盘口挂单字典', '移动盘口次数', self.pending_order_count) mid_price = self.mid_price # 中间价 price_offset = price_range - self.pending_order_count * min_price_step # 计算价格偏移量 do_trade = price_offset > 0 if do_trade: buy_price = mid_price - price_offset # 计算买价 buy_price = round(buy_price, self.price_precision) # 四舍五入买价 sell_price = mid_price + price_offset # 计算卖价 sell_price = round(sell_price, self.price_precision) # 四舍五入卖价 trade_dict = { 'do_trade': do_trade, 'buy_price': buy_price, 'sell_price': sell_price, 'amount': trade_amount } Log('返回盘口挂单字典:', trade_dict) return trade_dict else: Log('重置移动盘口次数:', self.pending_order_count) self.pending_order_count = 0 # 重置移动盘口次数 # 修正:当不能交易时返回None或空字典 return None def check_order_status(self, current_time): ''' 检查订单状态 Args: current_time: 当前时间戳 ''' Log('1开始订单信息检查') Log(self.traded_pairs['pan_kou']) self.buy_pending = 0 self.sell_pending = 0 for traded_pair in self.traded_pairs['pan_kou'].copy(): Log('检查订单:', traded_pair['buy_id'], traded_pair['sell_id']) try: buy_order_status = self.exchange_mid.exchange.GetOrder(traded_pair['buy_id']) # 获取买单状态 sell_order_status = self.exchange_mid.exchange.GetOrder(traded_pair['sell_id']) # 获取卖单状态 except: Log(traded_pair, '取消') self.exchange_mid.cancel_order(traded_pair['buy_id']) # 取消买单 self.exchange_mid.cancel_order(traded_pair['sell_id']) # 取消卖单 self.traded_pairs['pan_kou'].remove(traded_pair) # 移除订单 return Log('检查订单:', traded_pair['buy_id'], buy_order_status, traded_pair['sell_id'], sell_order_status, [sell_order_status['Status'], buy_order_status['Status']]) if [sell_order_status['Status'], buy_order_status['Status']] == [0, 0]: self.buy_pending += 1 self.sell_pending += 1 if current_time % 5 == 0: Log('检查挂单,取消挂单(两未完)', buy_order_status['Status'], sell_order_status['Status'], current_time % 5) self.exchange_mid.cancel_order(traded_pair['buy_id']) # 取消买单 self.exchange_mid.cancel_order(traded_pair['sell_id']) # 取消卖单 self.pending_order_count += 1 # 移动盘口次数次数加1 self.traded_pairs['pan_kou'].remove(traded_pair) # 移除订单 elif {sell_order_status['Status'], buy_order_status['Status']} == {1, 0}: if buy_order_status['Status'] == ORDER_STATE_PENDING: self.buy_pending += 1 if sell_order_status['Status'] == ORDER_STATE_PENDING: self.sell_pending += 1 if current_time % 5 == 0: Log('检查挂单,取消挂单(一未完)', buy_order_status['Status'], sell_order_status['Status']) self.done_amount['pan_kou'] += traded_pair['amount'] # 更新交易量 if buy_order_status['Status'] == ORDER_STATE_PENDING: self.sell_amount += traded_pair['amount'] self.fee += sell_order_status['Amount'] * self.fee_rate * sell_order_status['Price'] Log('取消该买订单,增加未完成买列表', traded_pair['buy_id']) self.exchange_mid.cancel_order(traded_pair['buy_id']) # 取消买单 self.pending_orders.append(['buy', buy_order_status['Status']]) # 记录未完成订单 Log('清除前:', self.traded_pairs['pan_kou']) Log('清除id:', traded_pair) self.traded_pairs['pan_kou'].remove(traded_pair) # 移除订单 Log('清除后:', self.traded_pairs['pan_kou']) elif sell_order_status['Status'] == ORDER_STATE_PENDING: self.buy_amount += traded_pair['amount'] self.fee += buy_order_status['Amount'] * self.fee_rate * buy_order_status['Price'] Log('取消该卖订单,增加未完成卖列表', traded_pair['sell_id']) self.exchange_mid.cancel_order(traded_pair['sell_id']) # 取消卖单 self.pending_orders.append(['sell', sell_order_status['Status']]) # 记录未完成订单 Log('清除前:', self.traded_pairs['pan_kou']) Log('清除id:', traded_pair) self.traded_pairs['pan_kou'].remove(traded_pair) # 移除订单 Log('清除后:', self.traded_pairs['pan_kou']) elif [sell_order_status['Status'], buy_order_status['Status']] == [1, 1]: Log('两订单都已完成') Log('完成状态:', buy_order_status['Status'], sell_order_status['Status'], traded_pair['amount']) self.done_amount['pan_kou'] += 2 * traded_pair['amount'] # 更新交易量 self.buy_amount += traded_pair['amount'] self.sell_amount += traded_pair['amount'] self.fee += buy_order_status['Amount'] * self.fee_rate * buy_order_status['Price'] self.fee += sell_order_status['Amount'] * self.fee_rate * sell_order_status['Price'] self.traded_pairs['pan_kou'].remove(traded_pair) # 移除订单 else: Log('两订单处于未知状态:', buy_order_status, sell_order_status) Log('未知订单状态:', buy_order_status['Status'], sell_order_status['Status']) Log('未知订单信息:', traded_pair) def update_status(self): self.exchange_mid.refresh_data() table1 = { "type": "table", "title": "账户信息", "cols": [ "初始资金", "现存资金", "盘口买入数量", "盘口卖出数量", "费率", "总收益", "收益率" ], "rows": [ [ self.exchange_mid.init_equity, self.exchange_mid.equity, round(self.buy_amount, 4), round(self.sell_amount, 4), round(self.fee, 2), self.exchange_mid.profit, str(self.exchange_mid.profitratio) + "%" ], ], } LogStatus( f"初始化时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(self.exchange_mid.init_timestamp))}\n", f"`{json.dumps(table1)}`\n", f"最后执行时间: {_D()}\n" ) LogProfit(round(self.exchange_mid.profit, 3), '&') def plot_pending(self): Log('盘口挂单数量:', self.buy_pending, self.sell_pending) self.obj_chart = Chart(self.chart) now_time = int(time.time() * 1000) # 更新挂单买量数据 self.obj_chart.add(0, [now_time, self.buy_pending]) # 更新挂单卖量数据 self.obj_chart.add(1, [now_time, self.sell_pending]) def main(): ''' 主函数,运行做市策略 ''' exchange.IO('simulate', True) #OKX现货模拟账户 exchange.IO("trade_super_margin") current_time = 0 target_amount = 1 # 目标交易量 price_range = 5 # 价格范围 min_price_step = 1 # 最小价格间隔 trade_amount = 0.01 # 每次交易量 exchange_mid = MidClass(exchange) # 初始化交易所中间层 Log(exchange_mid.refresh_data()) # 刷新数据 market_maker = MarketMaker(exchange_mid) # 初始化做市策略 # 修正:初始化trade_dict trade_dict = None while market_maker.done_amount['pan_kou'] < target_amount: # 循环直到完成目标交易量 Log(market_maker.traded_pairs['pan_kou']) market_maker.check_order_status(current_time) # 检查订单状态 Sleep(1000) # 等待1秒 market_maker.refresh_data() # 刷新数据 if len(market_maker.traded_pairs['pan_kou']) < 1: # 价格移动,盘口挂单撤销,等待至所有挂单完毕,制定新的挂单字典 Log('2盘口交易对数量小于1') trade_dict = market_maker.make_pankou_dict(price_range, min_price_step, trade_amount) # 生成盘口挂单字典 Log('新交易字典', trade_dict) # 修正:确保trade_dict存在且不为None if trade_dict and trade_dict.get('do_trade', False): market_maker.make_trade_by_dict(trade_dict) # 执行交易 Log('盘口做市数量:', market_maker.done_amount['pan_kou']) # 记录交易量 market_maker.plot_pending() market_maker.update_status() current_time += 1 Log(market_maker.position_amount, market_maker.can_buy_amount) # 记录持仓量和可买数量 Log('现存订单:', exchange.GetOrders()) # 记录现存订单 def onexit(): Log("执行扫尾函数") _G("init_balance", None) _G("init_stocks", None) _G("init_equity", None)
Comment
All comments (0)
No data
No data
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)