В этой статье представлена стратегия увеличения объёма торгов для изучения принципов трейдинга, которая принципиально отличается от традиционной стратегии арбитражного маркет-мейкинга. Основная цель этой стратегии — увеличение объёма торгов путём покупки и продажи по одинаковой цене и получение биржевых скидок или дисконтов, а не получение прибыли за счёт арбитража на разнице цен.
Код, представленный в этой статье, является лишь справочной платформой и не имеет опыта работы в режиме реального времени. Реализация стратегии в этой статье предназначена исключительно для технического обучения и исследований и не была полностью проверена в реальных рыночных условиях. При обращении к содержанию этой статьи читатели должны провести достаточное тестирование на исторических данных и оценку рисков и не должны использовать её напрямую для торговли в режиме реального времени.
На рынке цифровых валют стратегии маркет-мейкинга — это не только инструмент повышения ликвидности рынка и стимулирования транзакций, но и ключевой компонент многих количественных торговых стратегий. Маркет-мейкеры получают прибыль в различных рыночных условиях, публикуя котировки на покупку и продажу и обеспечивая ликвидность. Реализация кода профессиональных маркет-мейкеров зачастую чрезвычайно сложна и включает в себя такие продвинутые функции, как оптимизация высокочастотных задержек, сложные системы управления рисками и арбитраж на нескольких биржах. На этот раз мы изучим основные идеи стратегии контрторговли с помощью кисти-объемов и покажем, как реализовать упрощенную обучающую платформу на платформе Inventor Quantitative (FMZ).
Основная часть этой статьи взята из книги «Идея и метод написания стратегии маркет-мейкинга» автора Зинана. Некоторые части были оптимизированы и воспроизведены на платформе fmz. С сегодняшней точки зрения некоторые методы написания могут показаться устаревшими, но она по-прежнему вдохновляет всех, кто хочет понять структуру кода и основные идеи контртрейдинга:
Стратегия маркет-мейкинга подразумевает, что трейдеры (маркет-мейкеры) размещают на рынке ордера на покупку и продажу одновременно, обеспечивая ликвидность для поддержания стабильности рынка. Эта стратегия не только помогает поддерживать глубину рынка, но и предоставляет контрагентов другим трейдерам. Предоставляя котировки на покупку и продажу в различных ценовых диапазонах, маркет-мейкеры получают прибыль от колебаний цен.
Роль маркет-мейкеров критически важна для рынка криптовалют, особенно на рынках с низкими объёмами торгов и высокой волатильностью. Обеспечивая ликвидность, маркет-мейкеры помогают уменьшить проскальзывание рынка и предоставляют трейдерам более удобные цены для торговли.
Основной принцип традиционной стратегии маркет-мейкинга заключается в получении прибыли от спреда между ценами спроса и предложения за счёт обеспечения ликвидности. Цена ордера на покупку, размещаемого маркет-мейкером, ниже цены ордера на продажу, и прибыль формируется за счёт спреда. Например, когда спотовая цена на рынке растёт, маркет-мейкер продаёт по более высокой цене и покупает по более низкой, зарабатывая спред. Основные источники дохода:
Однако маркет-мейкеры также сталкиваются с риском рыночной волатильности, особенно в условиях высокой волатильности рынка цифровых валют. Резкие колебания рынка могут привести к значительному отклонению ордеров на покупку и продажу, размещаемых маркет-мейкерами, от фактической цены, что приведет к убыткам.
На рынке криптовалют маркет-мейкеры обычно выбирают различные стратегии маркет-мейкинга в зависимости от рыночных условий, объема торгов, волатильности и т. д. К распространенным типам стратегий маркет-мейкинга относятся:
Стратегии пассивного маркет-мейкинга:Маркет-мейкеры размещают ордера на покупку и продажу, основываясь на глубине рынка, исторической волатильности и других факторах, и ждут рыночных транзакций. Эта стратегия характеризуется низкой частотой и надёжностью, и маркет-мейкеры используют рыночные колебания для получения прибыли.
Активная стратегия создания рынка: В рамках этой стратегии маркет-мейкеры корректируют цену и количество ордеров на покупку и продажу в режиме реального времени в соответствии с рыночными условиями, чтобы увеличить вероятность заключения сделки. Маркет-мейкеры обычно увеличивают количество ордеров, когда цена близка к текущей рыночной, чтобы лучше использовать рыночные колебания.
Стратегия увеличения объема: Тип стратегии, которому посвящена эта статья.Стратегия увеличения объемаЭто стратегия, направленная на увеличение объёма торгов путём покупки и продажи по одинаковой цене. В отличие от традиционных стратегий маркет-мейкинга, основная цель этой стратегии — не зарабатывание разницы в цене, а получение биржевых скидок, скидок за уровень или вознаграждений за майнинг ликвидности за счёт большого количества транзакций.
В стратегии промывки объёма маркет-мейкеры размещают ордера на покупку и продажу по одинаковой цене. Когда ордера исполняются, несмотря на отсутствие прибыли от разницы цен, объём торгов может быстро накапливаться. Модель прибыли в этой стратегии полностью основана на механизме стимулирования биржи, а не на рыночном арбитраже.
Основные характеристики:
Торговля по той же цене:В отличие от традиционных стратегий маркет-мейкинга, цена покупки и цена продажи одинаковы, и прибыль от разницы цен не генерируется.
Ориентированный на объем:Основная цель стратегии — быстрое накопление объема торговли, а не ценовой арбитраж.
Опора на стимулы:Прибыль полностью зависит от политики скидок биржи, скидок VIP-уровня или программ поощрения маркет-мейкеров.
Важные отличия: В отличие от традиционных стратегий маркет-мейкинга, стратегии фиктивной торговли приносят прибыль не за счёт обеспечения реальной рыночной ликвидности, а за счёт искусственного создания объёма торгов для получения выгоды от биржи. В некоторых юрисдикциях такая стратегия может быть связана с рисками несоблюдения нормативных требований и требует тщательной оценки перед применением на практике.
Анализируя код, мы можем обнаружить, что цена покупки и цена продажи в этой стратегии абсолютно одинаковы:
def make_duiqiao_dict(self, trade_amount):
mid_price = self.mid_price # 中间价
trade_price = round(mid_price, self.price_precision) # 精准交易价格
trade_dict = {
'trade_price': trade_price, # 买卖都使用同一个价格
'amount': trade_amount
}
return trade_dict
1. Стратегия объема торговли
2. Механизм возврата платы
✅ Применимые сценарии
❌ Не применимо
⚠️ Напоминание о риске
В этой статье будет использована кодовая платформа г-на Зинана для простой реализации стратегии увеличения объёма торгов, с упором на наращивание объёма торгов с помощью стратегии покупки и продажи по одинаковой цене на бирже. Стратегическая платформа состоит из двух основных классов:MidClass и MarketMakerЭти два класса отвечают за взаимодействие на среднем уровне биржи и конкретное выполнение стратегии нокдауна.
Эта стратегическая архитектура использует многоуровневую структуру, разделяющую биржевой интерфейс и стратегию маркет-мейкинга, что обеспечивает хорошую масштабируемость и гибкость системы. Основные компоненты архитектуры включают:
MidClass:Промежуточный уровень биржи отвечает за взаимодействие с интерфейсом биржи для получения рыночных данных, информации о счете, статусе заказа и т. д. Этот уровень инкапсулирует все взаимодействия с внешними биржами, обеспечивая разделение торговой логики и интерфейса биржи.MarketMaker:Класс стратегии создания рынка, отвечающий за реализацию стратегии «стук-ту-трейд», генерацию отложенных ордеров, проверку статуса ордера, обновление статуса стратегии и т. д. Он взаимодействует со средним уровнем биржи для предоставления определенных операций создания рынка и «стук-ту-трейд».MidClassКак средний уровень обмена, его основная обязанность — управление взаимодействием с обменом, инкапсуляция всех внешних вызовов API и предоставление краткого интерфейса дляMarketMakerИспользование. Его архитектура включает следующие ключевые функции:
Сбор рыночных данных:
Управление информацией об аккаунте:
Управление заказами:
Хранение и обновление данных:
Инкапсулируя эти функции вMidClassВ приведенном выше примере вы можете убедиться, что класс торговой стратегии (например,MarketMaker) Сосредоточьтесь на реализации торговых стратегий, не беспокоясь о взаимодействии с биржами. Такая структура повышает удобство обслуживания и масштабируемость системы, упрощая добавление поддержки различных бирж или оптимизацию существующих функций.
MarketMakerЭто базовый класс кросс-трейдинговой стратегии, отвечающий за выполнение маркет-мейкинговых операций и кросс-трейдинговых транзакций. Его архитектура включает следующие основные модули:
инициализация:
MidClass, получите основную информацию о бирже, такую как торговые пары, точность, глубина рынка и т. д.Обновление данных:
Реализация стратегии стука:
MarketMakerОн будет отправлен на рынок, и ордера на покупку и продажу будут исполнены одновременно. Цель — быстро нарастить объём торгов, покупая и продавая по одной и той же цене.MarketMakerСистема будет постоянно проверять статус отложенного ордера, чтобы гарантировать его своевременную обработку. Если ордер не будет исполнен, система скорректирует цену или количество отложенного ордера до его полного исполнения.Обновление статуса:
MarketMakerМетод реализации стратегии будет динамически корректироваться с учетом различных рыночных условий.Реализация стратегии кросс-трейдинга зависит от точности рыночных данных и быстрого исполнения.MarketMakerМониторинг рыночной ситуации в режиме реального времени и использование метода встречных ордеров (покупка и продажа по одной цене) позволяет достигать стратегических целей за счет быстрого наращивания объема торгов.
существовать MarketMakerВ методе инициализации класса сначала получите информацию о точности биржи и инициализируйте параметры стратегии, такие как точность объема транзакций, точность цены и т. д.
self.precision_info = self.exchange_mid.get_precision() # 获取精度信息
self.price_precision = self.precision_info['price_precision'] # 价格精度
self.amount_precision = self.precision_info['amount_precision'] # 交易量精度
Суть стратегии кросс-трейдинга заключается в формировании словаря кросс-трейдинговых ордеров, включающего цены покупки и продажи, а также объёмы. Код формирует словарь кросс-трейдинговых ордеров, рассчитывая среднюю цену.
def make_duiqiao_dict(self, trade_amount):
mid_price = self.mid_price # 中间价
trade_price = round(mid_price, self.price_precision) # 精准交易价格
trade_dict = {
'trade_price': trade_price,
'amount': trade_amount
}
return trade_dict
На основании сформированного словаря кросс-торговых ордеров осуществляется исполнение кросс-торговой сделки.create_orderМетод заключается в одновременном размещении ордеров на покупку и продажу.
def make_trade_by_dict(self, trade_dict):
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['trade_price'], trade_dict['amount']) # 挂买单
sell_id = self.exchange_mid.create_order('sell', trade_dict['trade_price'], trade_dict['amount']) # 挂卖单
self.traded_pairs['dui_qiao'].append({
'buy_id': buy_id, 'sell_id': sell_id, 'init_time': time.time(), 'amount': trade_dict['amount']
})
Регулярно проверяйте статус заказа и обрабатывайте незавершенные заказы.GetOrderМетод, получение статуса заказа и принятие решения об отмене заказа на основе его статуса. Логика обработки заказа с нокдауном включает в себя следующие основные этапы:
Получить статус заказа:
Решение о статусе заказа:
0(ORDER_STATE_PENDING): Не завершено (ожидаемый заказ).1(ORDER_STATE_CLOSED): Завершено (полностью продано).2(ORDER_STATE_CANCELED): Отозвано.3(ORDER_STATE_UNKNOWN): Статус неизвестен.Обработка статуса заказа:
0), затем в соответствии со временем голосования (current_time % 5 == 0) решает, следует ли отменить заказ.1), а другой заказ не выполнен (статус0), затем решите, следует ли отменить незавершенный заказ, основываясь на времени опроса.1), объем транзакции обновляется, и заказ удаляется из записи.0Не совсем1, он регистрируется как неизвестный статус и регистрируется в журнале.Обновление записи:
Представленная в этой статье стратегия увеличения объёма используется в основном для изучения архитектуры торговой платформы, и её фактическая практическая ценность ограничена. Если читателям интересны реальные стратегии маркет-мейкинга, мы представим более практическую информацию по ним позже:
1. Стратегия создания рынка
2. Динамическая стратегия создания рынка
3. Стратегия многоуровневого маркет-мейкинга
Эти стратегии будут больше фокусироваться на реальной логике прибыли и управлении рисками, предоставляя более ценную справочную информацию для количественных трейдеров.
Стратегия фиктивной торговли основана на политике стимулирования биржи. Изменение этой политики может привести к её недействительности. Поэтому стратегия должна быть способна адаптироваться к изменениям, например, динамически отслеживать ставку комиссии или внедрять несколько моделей прибыли для снижения риска зависимости от одного источника. Кроме того, стратегия фиктивной торговли может быть расценена как манипулирование рынком и сопряжена с регуляторными рисками. В реальных условиях трейдерам необходимо внимательно следить за соблюдением соответствующих законов и нормативных актов, чтобы обеспечить соблюдение стратегии и избежать убытков, связанных с регуляторными проблемами.
Надеюсь, что читатели смогут оптимизировать и улучшить свои стратегии, основываясь на собственных торговых концепциях и понимании рынка, а также на понимании базовой структуры. Прелесть количественной торговли заключается в постоянном обучении, практике и совершенствовании. Желаю вам всем дальнейшего прогресса на пути количественной торговли!
”`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 = {'dui_qiao': 0} # 已完成交易量
self.price_precision = self.precision_info['price_precision'] # 价格精度
self.amount_precision = self.precision_info['amount_precision'] # 交易量精度
self.traded_pairs = {'dui_qiao': []} # 已挂单的交易对
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 # 账户余额
Log('检查ticker', self.exchange_mid.buy_price)
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_duiqiao_dict(self, trade_amount):
'''
生成对敲挂单字典
Args:
trade_amount: 每次交易量
Returns:
对敲挂单字典列表
'''
Log('3制作对敲挂单字典')
mid_price = self.mid_price # 中间价
trade_price = round(mid_price, self.price_precision) # 精准交易价格
trade_dict = {
'trade_price': trade_price,
'amount': trade_amount
}
Log('返回盘口挂单字典:', trade_dict)
return trade_dict
def make_trade_by_dict(self, trade_dict):
'''
根据交易字典执行交易
Args:
trade_dict: 交易字典
'''
Log('4按照字典开始交易')
self.refresh_data() # 刷新数据
if trade_dict:
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['trade_price'], trade_dict['amount']) # 挂买单
sell_id = self.exchange_mid.create_order('sell', trade_dict['trade_price'], trade_dict['amount']) # 挂卖单
self.traded_pairs['dui_qiao'].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 check_order_status(self, current_time):
'''
检查订单状态
current_time: 轮询检查次数
'''
Log('1开始订单信息检查')
Log(self.traded_pairs['dui_qiao'])
self.buy_pending = 0
self.sell_pending = 0
for traded_pair in self.traded_pairs['dui_qiao'].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['dui_qiao'].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['dui_qiao'].remove(traded_pair) # 移除订单