Dans notre article précédent, « Stratégies de trading fictif en cryptomonnaies », nous avons détaillé un cadre stratégique permettant d’accumuler du volume d’échange en achetant et en vendant au même prix. L’objectif principal de cette stratégie est d’obtenir des remises sur les échanges ou des avantages liés aux niveaux, plutôt que de tirer profit de l’arbitrage des prix. Si les stratégies de trading fictif sont utiles pour comprendre les cadres de trading, leur rentabilité réelle est limitée et elles peuvent présenter des risques de conformité.
Cet article présentera une autre stratégie de création de marché plus pratique basée sur l’article précédent :Stratégie de handicapContrairement à la stratégie de wash-trading, la stratégie de market maker est une véritable stratégie d’arbitrage qui génère des profits en fixant un spread entre les prix d’achat et de vente, ce qui est plus conforme au modèle de profit des market makers traditionnels.
Le code de stratégie de marché présenté dans cet article est uniquement destiné à servir de cadre d’apprentissage et ne reflète aucune expérience de trading réelle. Les stratégies présentées ici sont uniquement destinées à l’apprentissage technique et à la recherche et n’ont pas été entièrement validées en conditions de marché réelles. Il est conseillé aux lecteurs de procéder à des tests rétrospectifs et à une évaluation des risques approfondis avant d’utiliser ces informations, et de ne pas les utiliser directement en trading réel.
La stratégie du carnet d’ordres de marché est une stratégie de tenue de marché qui exploite le carnet d’ordres (c’est-à-dire la profondeur du marché) à des fins d’arbitrage. Dans ce cadre, les teneurs de marché ajustent dynamiquement le prix de l’ordre dans l’écart entre les cours acheteur et vendeur en fonction des fluctuations du marché, en plaçant et en annulant des ordres, tirant ainsi profit de la liquidité du marché et des fluctuations de prix à court terme pour générer des profits.
| fonctionnalité | Stratégie d’augmentation du volume | Stratégie de handicap |
|---|---|---|
| Prix d’achat et de vente | Même prix | Différents prix (avec différence de prix) |
| Modèle de profit | Remises/incitations d’échange | écart acheteur-vendeur |
| Exposition à risque | Faible (transaction au même prix) | Élevé (risque de volatilité des prix) |
| Praticité | limité | Plus haut |
Conformément à la stratégie de grève, le code de cet article met en œuvre une stratégie de market making basée sur la stratégie de cotation du marché, qui est principalement divisée en deux catégories :
MidClass:La couche intermédiaire de l’échange est chargée d’interagir avec l’interface de l’échange pour obtenir des données de marché, des informations sur les comptes, l’état des commandes, etc.MarketMaker: Cours de stratégie de création de marché, responsable de l’exécution de la stratégie de marché, de la génération dynamique des prix des commandes en attente, de la génération des commandes en attente, de la vérification de l’état des commandes, de la mise à jour de l’état de la stratégie, etc.exister MarketMakerDans la méthode d’initialisation de classe, obtenez d’abord les informations de précision de l’échange et initialisez les paramètres de stratégie, tels que la précision du volume des transactions, la précision des prix, 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'] # 交易量精度
Le cœur de la stratégie de marché consiste à générer un dictionnaire des ordres en attente, contenant les prix d’achat et de vente ainsi que les quantités. Le code génère ce dictionnaire en calculant le prix médian et l’écart de prix.
L’évolution du prix de l’ordre en attente est obtenue en calculant le décalage de prix. Ce décalage est basé sur la fourchette de prix (price_range) et l’intervalle de prix minimum (min_price_step) calculé.
price_offset = price_range - self.pending_order_count * min_price_step # 计算价格偏移量
do_trade = price_offset > 0
price_range:Plage de prix, indiquant la plage d’écart entre le prix de la commande en attente et le prix moyen.min_price_step:Intervalle de prix minimum, indiquant l’étape d’ajustement minimum de chaque prix de commande en attente.price_offset: Décalage de prix, qui indique l’écart entre le prix de la commande actuelle et le prix moyen.Si le décalage de prix est supérieur à 0, cela signifie que la commande peut continuer à être passée ; sinon, le nombre de commandes en attente est réinitialisé.
Sur la base du décalage de prix, les prix d’achat et de vente sont calculés et un dictionnaire des commandes en attente est généré.
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:Prix de l’offre, calculé comme le prix moyen moins le décalage de prix.sell_price:Prix demandé, calculé comme le prix moyen plus le décalage de prix.trade_dict:Dictionnaire des ordres en attente, incluant les prix d’achat et de vente et les quantités.Selon le dictionnaire de commandes généré, exécutez la transaction de commande.create_orderMéthode, passez des ordres d’achat et des ordres de vente en même temps.
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']
})
Vérifiez régulièrement l’état des ordres et traitez les ordres non exécutés. La logique de traitement de l’état des ordres est similaire à celle de la stratégie de cross-trading, mais en raison des différences de prix, une exécution partielle peut entraîner un gain ou une perte.
1. Le mouvement des prix des ordres en attente n’est pas suffisamment flexible
Le mécanisme d’ajustement des prix dans cette stratégie est relativement simple, avec les limitations suivantes :
price_offset = price_range - self.pending_order_count * min_price_step # 计算价格偏移量
price_range et min_price_stepIl s’agit d’un paramètre fixe et ne peut pas être ajusté en temps réel en fonction des conditions du marchéOrientation d’amélioration:
2. Risque d’inventaire
La stratégie de marché est confrontée à de sérieux problèmes de risque d’inventaire :
Performance du risque:
Points de risque dans le code:
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'] # 只有买单成交,积累多头持仓
L’impact du risque d’inventaire:
Mesures de gestion des risques:
La stratégie de market making repose sur la profondeur du marché. Elle maintient la liquidité du marché en ajustant dynamiquement le prix et le volume des ordres d’achat et de vente. Comparée à la stratégie de wash trading, la stratégie de market making présente les caractéristiques suivantes :
✅ Avantages
❌ Défi
🔮 Orientations d’optimisation futures
Compte tenu des lacunes de la stratégie actuelle en matière de handicap, nous pouvons l’optimiser et l’améliorer dans les directions suivantes à l’avenir :
Stratégie de création de marché dynamique:
Stratégie de gestion des stocks:
Stratégie de création de marché à plusieurs niveaux:
Une gestion intelligente des risques:
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)