Este artículo muestra una estrategia de aumento de volumen para aprender el marco de trading, que difiere fundamentalmente de la estrategia tradicional de arbitraje de creación de mercado. El objetivo principal de esta estrategia es aumentar el volumen de trading comprando y vendiendo al mismo precio y obtener descuentos por tipo de cambio o de nivel, en lugar de obtener ganancias mediante el arbitraje de diferencias de precio.
El código proporcionado en este artículo es solo un marco de referencia y no cuenta con experiencia en operaciones en tiempo real. La implementación de la estrategia en este artículo tiene fines exclusivamente de aprendizaje técnico e investigación, y no se ha verificado completamente en el mercado real. Al consultar el contenido de este artículo, los lectores deben realizar pruebas retrospectivas y una evaluación de riesgos suficientes, y no deben utilizarlo directamente para operar en tiempo real.
En el mercado de divisas digitales, las estrategias de creación de mercado no solo son una herramienta para mejorar la liquidez del mercado y promover las transacciones, sino también un componente clave de muchas estrategias de trading cuantitativo. Los creadores de mercado obtienen beneficios en diferentes entornos de mercado publicando cotizaciones de compra y venta y proporcionando liquidez. La implementación del código de los creadores de mercado profesionales suele ser extremadamente compleja e implica funciones avanzadas como la optimización de retardos de alta frecuencia, sistemas complejos de control de riesgos y arbitraje multimercado. En esta ocasión, estudiaremos los conceptos básicos de la estrategia de contracomercio de volumen de pincel y cómo implementar un marco de aprendizaje simplificado en la plataforma Inventor Quantitative (FMZ).
La parte principal de este artículo proviene de “La idea y el método de escritura de la estrategia de creación de mercado” del autor original, Zinan. Algunas partes se han optimizado y reproducido en la plataforma fmz. Desde la perspectiva actual, algunos métodos de escritura pueden estar obsoletos, pero sigue siendo inspirador para todos comprender la estructura del código y las ideas básicas del contra-trading.
La estrategia de creación de mercado se refiere a la colocación simultánea de órdenes de compra y venta en el mercado por parte de los operadores (creadores de mercado), lo que proporciona liquidez para mantener la estabilidad del mercado. Esta estrategia no solo ayuda a mantener la profundidad del mercado, sino que también proporciona contrapartes para otros operadores. Al ofrecer cotizaciones de compra y venta en diferentes rangos de precios, los creadores de mercado se benefician de las fluctuaciones de precios.
El papel de los creadores de mercado es crucial para el mercado de criptomonedas, especialmente en mercados con bajo volumen de negociación y alta volatilidad. Al proporcionar liquidez, los creadores de mercado ayudan a reducir el deslizamiento del mercado y ofrecen a los operadores precios más accesibles para operar.
El principio fundamental de la estrategia tradicional de creación de mercado es obtener el diferencial entre oferta y demanda proporcionando liquidez. El precio de la orden de compra publicada por el creador de mercado es inferior al precio de la orden de venta, y las ganancias se obtienen mediante el diferencial de la transacción. Por ejemplo, cuando el precio spot del mercado sube, el creador de mercado vende a un precio más alto y compra a un precio más bajo, obteniendo así el diferencial. Las principales fuentes de ingresos incluyen:
Sin embargo, los creadores de mercado también se enfrentan al riesgo de la volatilidad del mercado, especialmente en el entorno altamente volátil del mercado de divisas digitales. Las fuertes fluctuaciones del mercado pueden provocar que las órdenes de compra y venta emitidas por los creadores de mercado se desvíen significativamente del precio real, lo que resulta en pérdidas.
En el mercado de criptomonedas, los creadores de mercado suelen elegir diferentes estrategias de creación de mercado según las condiciones del mercado, el volumen de operaciones, la volatilidad, etc. Los tipos comunes de estrategias de creación de mercado incluyen:
Estrategias de creación de mercado pasivoLos creadores de mercado colocan órdenes de compra y venta basándose en la profundidad del mercado, la volatilidad histórica y otros factores, y esperan las transacciones. Esta estrategia se caracteriza por su baja frecuencia y robustez, y los creadores de mercado se basan en las fluctuaciones del mercado para obtener ganancias.
Estrategia de creación de mercado activaCon esta estrategia, los creadores de mercado ajustan el precio y la cantidad de las órdenes de compra y venta en tiempo real según las condiciones del mercado para aumentar la probabilidad de cierre. Los creadores de mercado suelen aumentar las órdenes cuando el precio se acerca al precio actual del mercado para aprovechar mejor las fluctuaciones.
Estrategia para aumentar el volumen:El tipo de estrategia en el que se centra este artículo.Estrategia para aumentar el volumenEs una estrategia para aumentar el volumen de operaciones comprando y vendiendo al mismo precio. A diferencia de las estrategias tradicionales de creación de mercado, el objetivo principal de esta estrategia no es obtener diferencias de precio, sino obtener descuentos por cambio, niveles de descuento o recompensas por minería de liquidez mediante un gran número de transacciones.
En la estrategia de lavado de volumen, los creadores de mercado colocan órdenes de compra y venta al mismo precio. Cuando se ejecutan las órdenes, aunque no se obtiene beneficio por diferencia de precio, el volumen de negociación se acumula rápidamente. El modelo de rentabilidad de esta estrategia depende completamente del mecanismo de incentivos de la bolsa, más que del arbitraje de mercado.
Características principales:
Comercio al mismo precio:A diferencia de las estrategias tradicionales de creación de mercado, el precio de compra y el precio de venta son los mismos y no se generan ganancias por diferencia de precio.
Orientado al volumen:El objetivo principal de la estrategia es acumular rápidamente volumen comercial en lugar de arbitrar precios.
Dependencia de incentivos:Las ganancias dependen completamente de la política de reembolso del exchange, de los descuentos de nivel VIP o de los programas de incentivos de los creadores de mercado.
Diferencias importantes: En comparación con las estrategias tradicionales de creación de mercado, las estrategias de lavado de activos no generan ganancias proporcionando liquidez real al mercado, sino creando artificialmente volumen de operaciones para obtener beneficios de la bolsa. Esta estrategia puede presentar riesgos de cumplimiento normativo en algunas jurisdicciones y debe evaluarse cuidadosamente al aplicarse en la práctica.
Al analizar el código, podemos encontrar que el precio de compra y el precio de venta en esta estrategia son exactamente los mismos:
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. Estrategia de volumen de operaciones
2. Mecanismo de reembolso de tarifas
✅ Escenarios aplicables
❌ No aplicable
⚠️ Recordatorio de riesgo
Este artículo se basará en el marco de código del Sr. Zinan para presentar una implementación sencilla de una estrategia de aumento de volumen, centrándose en cómo acumular volumen de operaciones mediante la estrategia de compra y venta al mismo precio en un entorno bursátil. El marco de la estrategia consta de dos clases principales:MidClass y MarketMakerEstas dos clases son responsables de la interacción de la capa intermedia del intercambio y de la ejecución específica de la estrategia de reacción en cadena.
Esta arquitectura estratégica adopta un diseño en capas que separa la interfaz de intercambio y la estrategia de creación de mercado para garantizar la escalabilidad y flexibilidad del sistema. Los principales componentes de la arquitectura incluyen:
MidClass:La capa intermedia de intercambio es responsable de interactuar con la interfaz de intercambio para obtener datos del mercado, información de la cuenta, estado del pedido, etc. Esta capa encapsula todas las interacciones con intercambios externos para garantizar que la lógica comercial y la interfaz de intercambio estén desacopladas.MarketMaker:Clase de estrategia de creación de mercado, responsable de ejecutar la estrategia de golpe a comercio, generar órdenes pendientes, verificar el estado de las órdenes, actualizar el estado de la estrategia, etc. Interactúa con la capa intermedia del intercambio para proporcionar operaciones específicas de creación de mercado y golpe a comercio.MidClassComo capa intermedia del intercambio, su principal responsabilidad es manejar la interacción con el intercambio, encapsular todas las llamadas API externas y proporcionar una interfaz concisa paraMarketMakerUso. Su arquitectura incluye las siguientes funciones clave:
Adquisición de datos de mercado:
Gestión de información de cuentas:
Gestión de pedidos:
Almacenamiento y actualización de datos:
Al encapsular estas funciones enMidClassEn el ejemplo anterior, puede asegurarse de que la clase de estrategia comercial (comoMarketMaker) Concéntrese en la ejecución de estrategias de trading sin preocuparse por la interacción con las plataformas de intercambio. Esta estructura mejora la mantenibilidad y la escalabilidad del sistema, lo que facilita la compatibilidad con diferentes plataformas de intercambio o la optimización de funciones existentes.
MarketMakerEs la clase principal de la estrategia de trading cruzado, responsable de ejecutar operaciones de creación de mercado y transacciones de trading cruzado. Su arquitectura incluye los siguientes módulos principales:
inicialización:
MidClass, obtenga información básica del intercambio, como pares comerciales, precisión, profundidad del mercado, etc.Actualización de datos:
Ejecución de la estrategia de derribo:
MarketMakerSe enviará al mercado y las órdenes de compra y venta se ejecutarán simultáneamente. El objetivo es acumular rápidamente volumen de operaciones comprando y vendiendo al mismo precio.MarketMakerVerificará constantemente el estado del pedido para garantizar que el pedido pendiente se procese a tiempo. Si no se ejecuta, ajustará el precio o la cantidad hasta que se complete.Actualización de estado:
MarketMakerEl método de ejecución de la estrategia se ajustará dinámicamente para adaptarse a diferentes entornos de mercado.La implementación de la estrategia de comercio cruzado depende de datos de mercado precisos y de una ejecución rápida.MarketMakerAl monitorear la situación del mercado en tiempo real y utilizar el método de contraorden (compra y venta al mismo precio), se pueden lograr los objetivos estratégicos acumulando rápidamente el volumen comercial.
existir MarketMakerEn el método de inicialización de clase, primero se obtiene la información de precisión del intercambio e inicializa los parámetros de la estrategia, como la precisión del volumen de transacciones, la precisión del precio, etc.
self.precision_info = self.exchange_mid.get_precision() # 获取精度信息
self.price_precision = self.precision_info['price_precision'] # 价格精度
self.amount_precision = self.precision_info['amount_precision'] # 交易量精度
El núcleo de la estrategia de trading cruzado consiste en generar un diccionario de órdenes de trading cruzado, que incluye los precios y las cantidades de compra y venta. El código genera este diccionario calculando el precio medio.
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
De acuerdo con el diccionario generado de órdenes de cross-trading, se ejecuta la transacción de cross-trading.create_orderMétodo, colocar órdenes de compra y órdenes de venta al mismo tiempo.
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']
})
Verifique periódicamente el estado del pedido y procese los pedidos no terminados.GetOrderMétodo: obtener el estado del pedido y decidir si se cancela según dicho estado. La lógica de procesamiento de la orden de compra incluye principalmente los siguientes pasos:
Obtener el estado del pedido:
Sentencia sobre el estado de la orden:
0(ORDER_STATE_PENDING):No completado (pedido pendiente).1(ORDER_STATE_CLOSED):Completado (totalmente comercializado).2(ORDER_STATE_CANCELED):Revocado.3(ORDER_STATE_UNKNOWN):El estado es desconocido.Procesamiento del estado del pedido:
0), entonces según los horarios de votación (current_time % 5 == 0) decide si cancelar el pedido.1), y otro pedido no se completa (el estado es0), luego decide si cancelar el pedido inacabado en función de los tiempos de votación.1), se actualiza el volumen de transacciones y se elimina el pedido del registro.0No precisamente1, se registra como estado desconocido y se registra.Actualizar registro:
La estrategia de aumento de volumen presentada en este artículo se utiliza principalmente para aprender el diseño arquitectónico del marco de trading, y su valor práctico es limitado. Si los lectores están interesados en estrategias reales de creación de mercado, presentaremos contenido estratégico más práctico más adelante:
1. Estrategia de creación de mercado
2. Estrategia de creación de mercado dinámico
3. Estrategia de creación de mercado multinivel
Estas estrategias se centrarán más en la lógica de las ganancias reales y en la gestión de riesgos, proporcionando una referencia más valiosa para los traders cuantitativos.
La estrategia de lavado de activos se basa en la política de incentivos de la bolsa. Si esta cambia, la estrategia podría perder su validez. Por lo tanto, debe ser capaz de adaptarse a los cambios de política, como la monitorización dinámica de la tasa de comisiones o la introducción de múltiples modelos de rentabilidad para reducir el riesgo de dependencia única. Además, la estrategia de lavado de activos puede considerarse manipulación del mercado y estar sujeta a riesgos regulatorios. En la práctica, los operadores deben prestar mucha atención a las leyes y regulaciones pertinentes para garantizar el cumplimiento de la estrategia y evitar pérdidas derivadas de problemas regulatorios.
Espero que los lectores puedan optimizar y mejorar sus estrategias basándose en sus propios conceptos de trading y comprensión del mercado, basándose en su comprensión del marco básico. El encanto del trading cuantitativo reside en el aprendizaje, la práctica y la mejora continua. ¡Les deseo a todos un progreso continuo en el trading cuantitativo!
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) # 移除订单
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['dui_qiao'] += 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['dui_qiao'])
Log('清除id:', traded_pair)
self.traded_pairs['dui_qiao'].remove(traded_pair) # 移除订单
Log('清除后:', self.traded_pairs['dui_qiao'])
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['dui_qiao'])
Log('清除id:', traded_pair)
self.traded_pairs['dui_qiao'].remove(traded_pair) # 移除订单
Log('清除后:', self.traded_pairs['dui_qiao'])
elif [sell_order_status['Status'], buy_order_status['Status']] == [1, 1]:
Log('两订单都已完成')
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']
Log('完成状态:', buy_order_status['Status'], sell_order_status['Status'], traded_pair['amount'])
self.done_amount['dui_qiao'] += 2 * traded_pair['amount'] # 更新交易量
self.traded_pairs['dui_qiao'].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)
exchange.IO("trade_super_margin")
target_amount = 1 # 目标交易量
trade_amount = 0.01 # 每次交易量
trade_dict = {} # 初始化交易字典
exchange_mid = MidClass(exchange) # 初始化交易所中间层
Log(exchange_mid.refresh_data()) # 刷新数据
market_maker = MarketMaker(exchange_mid) # 初始化做市策略
check_times = 0
while market_maker.done_amount['dui_qiao'] < target_amount: # 循环直到完成目标交易量
Log(market_maker.traded_pairs['dui_qiao'])
market_maker.check_order_status(check_times) # 检查订单状态
Sleep(1000) # 等待1秒
market_maker.refresh_data() # 刷新数据
if len(market_maker.traded_pairs['dui_qiao']) < 1: # 价格移动,盘口挂单撤销,等待至所有挂单完毕,制定新的挂单字典
Log('2盘口交易对数量小于1')
trade_dict = market_maker.make_duiqiao_dict(trade_amount) # 生成盘口挂单字典
Log('新交易字典', trade_dict)
if trade_dict: # 判断字典是否非空
market_maker.make_trade_by_dict(trade_dict) # 执行交易
Log('盘口做市数量:', market_maker.done_amount['dui_qiao']) # 记录交易量
market_maker.plot_pending()
market_maker.update_status()
check_times += 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)