Le marché des cryptomonnaies offre un environnement de trading unique, idéal pour les stratégies de grid trading. Comparé aux marchés financiers traditionnels, le secteur des cryptomonnaies fonctionne 24h/24 et 7j/7, avec des fluctuations de prix continues et fréquentes, créant de nombreuses opportunités d’arbitrage pour les stratégies grid trading. De plus, les principaux instruments de trading, tels que les contrats au comptant et perpétuels, ne sont soumis à aucune restriction d’expiration, ce qui permet aux traders de conserver des positions à long terme sans se soucier du risque d’expiration. De plus, la forte volatilité et la liquidité relativement importante du marché des cryptomonnaies offrent des conditions favorables à la mise en œuvre de stratégies grid trading.
C’est précisément grâce à ces caractéristiques que les stratégies de grid trading présentent une forte applicabilité et un fort potentiel de profit sur le marché des cryptomonnaies. Le grid trading est une stratégie largement utilisée sur ce marché, permettant aux traders de tirer profit de la volatilité du marché sans avoir à anticiper son orientation. En plaçant des ordres d’achat et de vente à différentes fourchettes de prix, le grid trading permet aux traders de réaliser des profits, que les prix soient à la hausse ou à la baisse.
Les stratégies de trading en grille présentent de nombreuses variantes. Cet article n’abordera que brièvement quelques formats pour aider les débutants à se familiariser avec cette méthode classique de trading quantitatif. Le principe de base d’une stratégie de trading en grille est de placer une série d’ordres d’achat et de vente à différents niveaux de prix. Les ordres d’achat sont placés lorsque le prix atteint les nœuds inférieurs de la grille, et les ordres de vente lorsqu’il atteint les nœuds supérieurs, ce qui permet de réaliser de petits profits sur les fluctuations du marché. L’avantage de cette stratégie est que les traders n’ont pas besoin de prédire la direction du marché ; ils se basent sur les fluctuations des prix au sein de la grille.
Supposons qu’une stratégie de grille soit définie avec un intervalle de 8 000 \( à 9 000 \), avec un intervalle de 500 \(. Lorsque le prix passe de 8 000 \) à 8 500 \(, la stratégie achète à 8 000 \) et vend à 8 500 \(. Si le prix monte encore à 9 000 \), elle vend à nouveau une partie de ses positions. Lorsque le prix retombe de 9 000 \( à 8 500 \), elle achète à nouveau. En répétant ce processus, la stratégie peut continuellement accumuler des profits malgré les fluctuations du marché.
Le cœur d’une stratégie équilibrée est de maintenir un ratio fixe d’actifs, par exemple 50 % de monnaie numérique et 50 % de monnaie fiduciaire. Lorsque le cours d’une cryptomonnaie augmente et que la proportion de cryptomonnaies détenues dépasse 50 %, elle est vendue ; lorsque son cours baisse, elle est achetée. Cela garantit que la valeur des actifs détenus reste proche du ratio fixe. Quelles que soient les fluctuations du marché, une stratégie équilibrée maintient une certaine quantité de cryptomonnaies.
La stratégie de la grille arithmétique est une stratégie de trading quantitative classique, souvent utilisée sur les marchés volatils. Elle permet de capter les profits générés par les fluctuations de prix en plaçant des ordres d’achat et de vente à des intervalles de prix fixes (intervalles arithmétiques). Elle est adaptée aux marchés à forte volatilité mais à évolution imprévisible, comme ceux des cryptomonnaies et de certains contrats à terme.
Concepts de base :
intervalle équidistant
Dans la stratégie de grille arithmétique, il existe un écart entre les prix d’achat et de vente.Intervalles de prix fixes, qui est dans le codegridPar exemple, lorsque le prix fluctue de 300 unités (comme dans le codegrid=300), un ordre d’achat ou de vente est déclenché.
Initialisation de la grille
La stratégie génère les prix d’achat et de vente initiaux en fonction du prix actuel, qui sontbuyp et sellpLes deux intervalles de prix sont basés sur l’intervalle de grillegridPour fixer, respectivement au-dessus et en dessous du prix actuelgridunités.
Prendre des bénéfices et inverser
Lorsque le prix atteint une certaine fourchette, la stratégie achète dans la zone de position longue et place un ordre de vente pour prendre son profit. Si le prix continue de grimper jusqu’à la zone de position inverse (upper), la position longue prendra des bénéfices et deviendra courte, et vice versa.
Gestion des positions au sein de la grille
Chaque action d’achat ou de vente dans la grille sera déclenchée lorsque le prix atteint le seuil prédéfini.buyp ou sellpAprès chaque transaction, le système ajuste automatiquement le groupe suivant de prix d’achat et de vente pour maintenir un intervalle de grille fixe.
Ajout et réduction de positions
La stratégie ajuste continuellement sa position en fonction du prix de la grille. Lorsque le prix atteint le point d’achat, elle augmente sa position ; lorsqu’il atteint le point de vente, elle la réduit progressivement. En achetant et en vendant régulièrement, elle capte la moindre fluctuation du marché.
'''backtest
start: 2024-08-26 00:00:00
end: 2024-09-25 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT","balance":2500}]
args: [["H",30],["n1",0.001],["grid",300],["bottom",50000]]
'''
# 交易参数配置(设为策略参数)
M = 20 # 杠杆大小
H = 50 # 初始底仓份数
n1 = 1 # 单个网格交易数量
grid = 200 # 单个网格交易间距
bottom = 35000 # 开多点位
upper = 60000 # 开空点位
def CancelPendingOrders():
orders = _C(exchanges[0].GetOrders)
if len(orders)>0:
for j in range(len(orders)):
exchanges[0].CancelOrder(orders[j].Id, orders[j])
j=j+1
def main():
exchange.SetContractType('swap')
exchange.SetMarginLevel(M)
currency=exchange.GetCurrency()
if _G('buyp') and _G('sellp'):
buyp=_G('buyp')
sellp=_G('sellp')
Log('读取网格价格')
else:
ticker=exchange.GetTicker()
buyp=ticker["Last"]-grid
sellp=ticker["Last"]+grid
_G('buyp',buyp)
_G('sellp',sellp)
Log('网格数据初始化')
while True:
account=exchange.GetAccount()
ticker=exchange.GetTicker()
position=exchange.GetPosition()
orders=exchange.GetOrders()
if len(position)==0:
if ticker["Last"]>upper:
exchange.SetDirection('sell')
exchange.Sell(-1,n1*H)
Log(currency,'到达开空区域,买入空头底仓')
else:
exchange.SetDirection('buy')
exchange.Buy(-1,n1*H)
Log(currency,'到达开多区域,买入多头底仓')
if len(position)==1:
if position[0]["Type"]==1: #持有空头仓位
if ticker["Last"]<bottom:
Log(currency,'空单全部止盈反手')
exchange.SetDirection('closesell')
exchange.Buy(-1,position[0].Amount)
else:
orders=exchange.GetOrders()
if len(orders)==0:
exchange.SetDirection('sell')
exchange.Sell(sellp,n1)
exchange.SetDirection('closesell')
exchange.Buy(buyp,n1)
if len(orders)==1:
if orders[0]["Type"]==1: #止盈成交
Log(currency,'网格减仓,当前份数:',position[0].Amount)
CancelPendingOrders()
buyp=buyp-grid
sellp=sellp-grid
LogProfit(account["Balance"])
if orders[0]["Type"]==0:
Log(currency,'网格加仓,当前份数:',position[0].Amount)
CancelPendingOrders()
buyp=buyp+grid
sellp=sellp+grid
LogProfit(account["Balance"])
if position[0]["Type"]==0:
if ticker["Last"]>float(upper):
Log(currency,'多单全部止盈反手')
exchange.SetDirection('closebuy')
exchange.Sell(-1,position[0].Amount)
else:
orders=exchange.GetOrders()
if len(orders)==0:
exchange.SetDirection('buy')
exchange.Buy(buyp,n1)
exchange.SetDirection('closebuy')
exchange.Sell(sellp,n1)
if len(orders)==1:
if orders[0]["Type"]==0: #止盈成交
Log(currency,'网格减仓,当前份数:',position[0].Amount)
CancelPendingOrders()
buyp=buyp+grid
sellp=sellp+grid
LogProfit(account["Balance"])
if orders[0]["Type"]==1:
Log(currency,'网格加仓,当前份数:',position[0].Amount)
CancelPendingOrders()
buyp=buyp-grid
sellp=sellp-grid
LogProfit(account["Balance"])
La stratégie de la grille arithmétique est particulièrement applicable sur le marché des cryptomonnaies, notamment sur des marchés volatils et imprévisibles. En plaçant des ordres d’achat et de vente à des intervalles de prix fixes, cette stratégie capture efficacement les fluctuations du marché tout en préservant l’automatisation et la simplicité de ses opérations. La forte volatilité du marché des cryptomonnaies offre une excellente opportunité à cette stratégie de prospérer.
Il est important de noter que les coûts de transaction d’une stratégie de grille arithmétique proviennent principalement des ordres d’achat et de vente fréquents, plutôt que de leur placement ou de leur annulation. Cette caractéristique requiert une attention particulière sur les plateformes d’échange de cryptomonnaies aux frais de transaction élevés. Pour optimiser les rendements, il est recommandé de privilégier les plateformes offrant des frais moins élevés et d’ajuster l’intervalle de grille et le ratio d’allocation des fonds en fonction des conditions de marché spécifiques.
Globalement, la stratégie de grille arithmétique est bien adaptée au marché volatil des cryptomonnaies, mais peut présenter un risque important sur les marchés unilatéraux. En définissant correctement les paramètres et en optimisant la gestion des fonds, la robustesse et la rentabilité de la stratégie peuvent être efficacement améliorées.
Stratégie de grille dynamiqueDifférente de la stratégie traditionnelle de réseau fixe, elleGénération dynamiqueetRéglage des nœuds de maillageCette stratégie offre une plus grande flexibilité face aux fluctuations du marché. Elle génère de nouveaux nœuds de grille en fonction des fluctuations du marché en temps réel, améliorant ainsi son adaptabilité et ses capacités de contrôle des risques. Le concept principal est de ne générer de nouveaux nœuds que lorsque les fluctuations de prix dépassent un certain seuil et de gérer les positions en conséquence.
Génération de nœuds de maillage dynamique:
_GridPointDiscontrôle), la stratégie génère de nouveaux nœuds de grille._GridCovDis(Propagation de clôture contrôlée).Opérations d’achat et de vente:
direction = 1): Lorsque le prix augmente et franchit le nœud de la grille, vendez les actifs que vous détenez ; lorsqu’il retombe, achetez à nouveau.direction = -1): Lorsque le prix baisse et franchit le nœud de la grille, achetez l’actif ; lorsqu’il rebondit, vendez l’actif détenu.Opération de fermeture:
_GridCovDisDéfinir), exécuter des opérations de rachat (en position longue) ou de vente (en position courte) en fonction de la direction actuelle pour terminer la clôture de la position.Contrôle de la quantité de maille:
_GridNum), la stratégie supprimera automatiquement les premiers nœuds de la grille, évitant ainsi les positions excessives et réduisant les risques.Paramètres d’initialisation:
_GridNum: Nombre maximal de nœuds de grille, le nombre maximal de nœuds de grille que la stratégie de contrôle permet de conserver en même temps._GridPointAmount: La quantité commandée de chaque nœud de grille._GridPointDis: L’espacement des prix entre les nœuds de la grille._GridCovDis: Différence de prix pour la clôture d’une position. Lorsque la fluctuation entre le prix du marché et le prix de la grille dépasse cette différence, la position est clôturée.Fonction UpdateGrid:
current_price), prix d’achat (bids_price) et le prix de vente (asks_price) met à jour les nœuds de la grille. Chaque fois que le prix du marché franchit un nœud de la grille, la stratégie génère un nouveau nœud de grille et exécute la transaction correspondante.Boucle principale:
mainLa fonction obtient en continu des données de prix du marché en temps réel et appelleUpdateGridLes fonctions mettent à jour les nœuds de la grille et effectuent des opérations de trading.LogStatusEnregistrez l’état actuel du réseau, les informations du compte, etc. pour faciliter la surveillance en temps réel du fonctionnement de la stratégie.'''backtest
start: 2024-04-01 00:00:00
end: 2024-09-23 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
'''
direction = 1 # 网格方向:1表示向上,-1表示向下
_GridNum = 10 # 网格节点数量
_GridPointAmount = 0.1 # 每个网格节点的下单量
_GridPointDis = 100 # 网格节点之间的价格间距
_GridCovDis = 150 # 平仓价与网格节点的差距
_Grid = [] # 网格数据列表
def UpdateGrid(nowBidsPrice, nowAsksPrice, direction): # up 1, down -1
global _Grid
# 检查是否需要创建新的网格节点
if len(_Grid) == 0 or (direction == 1 and nowBidsPrice - _Grid[-1]['price'] > _GridPointDis) or \
(direction == -1 and _Grid[-1]['price'] - nowAsksPrice > _GridPointDis):
if len(_Grid) == 0:
Log('策略起始')
if len(_Grid) != 0 and direction == 1 and nowBidsPrice - _Grid[-1]['price'] > _GridPointDis:
Log('向上突破,突破阈值:', nowBidsPrice - _Grid[-1]['price'])
if len(_Grid) != 0 and direction == -1 and _Grid[-1]['price'] - nowAsksPrice > _GridPointDis:
Log('向下突破,突破阈值:', _Grid[-1]['price'] - nowAsksPrice)
# 根据方向决定当前网格节点的价格
nowPrice = nowBidsPrice if direction == 1 else nowAsksPrice
_Grid.append({
'price': nowPrice if len(_Grid) == 0 else _Grid[-1]['price'] + _GridPointDis * direction,
'hold': {'price': 0, 'amount': 0},
'coverPrice': (nowPrice - direction * _GridCovDis) if len(_Grid) == 0 else _Grid[-1]['price'] + _GridPointDis * direction - direction * _GridCovDis
})
Log('网格更新数量:', len(_Grid), '网格最新增添:', _Grid[-1])
# 下单操作,向上突破时卖出,向下突破时买入
tradeInfo = ext.Sell(_GridPointAmount) if direction == 1 else ext.Buy(_GridPointAmount)
_Grid[-1]['hold']['price'] = tradeInfo['price']
_Grid[-1]['hold']['amount'] = tradeInfo['amount']
Log('网格操作:', '向上卖出' if direction == 1 else '向下买入')
# 检查是否需要平仓
if len(_Grid) > 0 and (
(direction == 1 and nowAsksPrice < _Grid[-1]['coverPrice']) or
(direction == -1 and nowBidsPrice > _Grid[-1]['coverPrice'])):
coverInfo = ext.Buy(_Grid[-1]['hold']['amount']) if direction == 1 else ext.Sell(_Grid[-1]['hold']['amount'])
Log('价格跌破平仓价格,买入,去除最后添加网格' if direction == 1 else '价格突破平仓价格,卖出,去除最后添加网格')
_Grid.pop() # 移除已平仓的网格节点
# 如果网格数量超出设定值,则平掉最早的网格节点
elif len(_Grid) > _GridNum:
coverFirstInfo = ext.Buy(_Grid[0]['hold']['amount']) if direction == 1 else ext.Sell(_Grid[0]['hold']['amount'])
Log('网格数量过多,买入操作,去除初始网格' if direction == 1 else '网格数量过多,卖出操作,去除初始网格')
_Grid.pop(0)
def main():
global _Grid
while True:
ticker = _C(exchange.GetTicker)
records = _C(exchange.GetRecords)
ext.PlotRecords(records, "kline")
UpdateGrid(ticker['Buy'], ticker['Sell'], direction)
# 记录当前网格状态
msg = ""
for grid in _Grid:
msg += str(grid) + "\n"
LogStatus(_D(), _C(exchange.GetAccount), "\n", "_Grid.length:", len(_Grid), "_GridNum:", _GridNum, "\n", msg)
Sleep(500)
À noter:
La stratégie de grille bidirectionnelle Long-Short est une variante plus complexe mais puissante de la grille. Elle permet de négocier simultanément à l’achat et à la vente, maximisant ainsi les opportunités de profit sur des marchés volatils. Fondamentalement, cette stratégie ajuste dynamiquement les positions en fonction des écarts de prix par rapport au cours initial, obtenant ainsi une stratégie véritablement neutre face au marché.
La logique de base de la stratégie est de déterminer la position cible en fonction du degré d’écart entre le prix et le prix initial :
import time
import math
# 全局变量初始化
InitPrice = 800
Funding = 50000
# 策略参数(需要在策略页面设置)
pct = 5.0 # 网格间距百分比
value = 5000 # 每个网格的投入金额
Interval = 3 # 策略执行间隔(秒)
# 账户资产信息
assets = {
'USDT': {
'total_balance': 0,
'margin_balance': 0,
'margin': 0,
'unrealised_profit': 0
}
}
def init():
"""初始化策略"""
global symbol, Funding, base_currency
Log('交易模式:多空都做')
# 设置合约类型
exchange.SetContractType('swap')
# 获取交易币种
currency = exchange.GetCurrency()
symbol = currency # 保持原格式,如 "BTC_USDT"
base_currency = symbol.split('_')[0] # 获取基础币种,如 "BTC"
Log('交易币种:', symbol)
Log('基础币种:', base_currency)
swapcode = symbol + '.swap'
ticker = exchange.GetTicker(swapcode) # 回测系统需要
exchange_info = exchange.GetMarkets()
data = exchange_info.get(swapcode)
# 初始化资产信息
assets[base_currency] = {
'amount': 0,
'price': 0,
'hold_price': 0,
'price': 0,
'unrealised_profit': 0,
'leverage': 20,
'liquidation_price': 0,
'AmountPrecision': data['AmountPrecision'],
'PricePrecision': data['PricePrecision'],
'MinQty': data['MinQty']
}
# 撤销所有挂单
cancel_all_orders()
# 获取初始资金
account = exchange.GetAccount()
if account:
Funding = account.Balance + account.FrozenBalance
Log('初始资金:', Funding)
def calculate_grid_orders():
"""计算网格订单"""
if InitPrice == 0 or assets[base_currency]['price'] == 0:
return None
current_price = assets[base_currency]['price']
current_amount = assets[base_currency]['amount']
# 多空都做模式:根据价格变化计算目标持仓
price_change_ratio = (current_price - InitPrice) / InitPrice
target_amount = -price_change_ratio * (value / pct) / current_price
# 计算买卖价格
grid_spacing = current_price * (pct / 100) # 网格间距
buy_price = current_price - grid_spacing
sell_price = current_price + grid_spacing
# 计算订单数量
order_amount = value / current_price
return {
'buy_price': round(buy_price, assets[base_currency]['PricePrecision']),
'sell_price': round(sell_price, assets[base_currency]['PricePrecision']),
'buy_amount': round(order_amount, assets[base_currency]['AmountPrecision']),
'sell_amount': round(order_amount, assets[base_currency]['AmountPrecision']),
'target_amount': target_amount
}
def execute_strategy():
"""执行交易策略"""
# 计算网格订单
grid_info = calculate_grid_orders()
if not grid_info:
return
current_amount = assets[base_currency]['amount']
target_amount = grid_info['target_amount']
amount_diff = target_amount - current_amount
# 如果持仓偏离较大,先调整持仓
if abs(amount_diff) > assets[base_currency]['MinQty']:
cancel_all_orders()
Sleep(500)
# 判断需要的操作
if amount_diff > 0:
# 需要增加多头持仓或减少空头持仓
if current_amount >= 0:
# 当前是多头或空仓,直接开多
Log(f'当前持仓:{current_amount},需要开多:{abs(amount_diff):.6f}')
open_position('LONG', assets[base_currency]['price'], abs(amount_diff))
else:
# 当前是空头,需要先平空再开多
if abs(amount_diff) <= abs(current_amount):
# 只需要平掉部分空仓
Log(f'当前空仓:{current_amount},需要平仓:{abs(amount_diff):.6f}')
safe_close_position(abs(amount_diff), assets[base_currency]['price'])
else:
# 需要平掉所有空仓,然后开多
Log(f'平掉所有空仓:{abs(current_amount):.6f}')
if safe_close_position(abs(current_amount), assets[base_currency]['price']):
Sleep(1000) # 等待平仓完成
# 更新持仓信息
update_account()
remaining_amount = abs(amount_diff) - abs(current_amount)
if remaining_amount > assets[base_currency]['MinQty']:
Log(f'开多剩余数量:{remaining_amount:.6f}')
open_position('LONG', assets[base_currency]['price'], remaining_amount)
elif amount_diff < 0:
# 需要增加空头持仓或减少多头持仓
if current_amount <= 0:
# 当前是空头或空仓,直接开空
Log(f'当前持仓:{current_amount},需要开空:{abs(amount_diff):.6f}')
open_position('SHORT', assets[base_currency]['price'], abs(amount_diff))
else:
# 当前是多头,需要先平多再开空
if abs(amount_diff) <= current_amount:
# 只需要平掉部分多仓
Log(f'当前多仓:{current_amount},需要平仓:{abs(amount_diff):.6f}')
safe_close_position(abs(amount_diff), assets[base_currency]['price'])
else:
# 需要平掉所有多仓,然后开空
Log(f'平掉所有多仓:{current_amount:.6f}')
if safe_close_position(current_amount, assets[base_currency]['price']):
Sleep(1000) # 等待平仓完成
# 更新持仓信息
update_account()
remaining_amount = abs(amount_diff) - current_amount
if remaining_amount > assets[base_currency]['MinQty']:
Log(f'开空剩余数量:{remaining_amount:.6f}')
open_position('SHORT', assets[base_currency]['price'], remaining_amount)
# 检查是否需要重新挂网格单
orders = exchange.GetOrders()
if not orders or len(orders) < 2: # 多空都做模式需要2个订单
cancel_all_orders()
Sleep(500)
# 重新获取最新持仓信息
update_account()
current_amount = assets[base_currency]['amount']
# 挂买单和卖单(网格订单)
buy_amount = grid_info['buy_amount']
sell_amount = grid_info['sell_amount']
# 多空都做模式:无论当前持仓如何,都要挂多空双向网格单
place_grid_orders(current_amount, grid_info, buy_amount, sell_amount)
def place_grid_orders(current_amount, grid_info, buy_amount, sell_amount):
"""放置网格订单 - 多空都做模式"""
Log(f'放置网格订单 - 当前持仓:{current_amount}')
# 多空都做模式:无论当前持仓如何,都要挂多空双向网格单
Log(f'多空都做模式 - 挂开多单:数量={buy_amount:.6f},价格={grid_info["buy_price"]}')
open_position('LONG', grid_info['buy_price'], buy_amount)
Sleep(200)
Log(f'多空都做模式 - 挂开空单:数量={sell_amount:.6f},价格={grid_info["sell_price"]}')
open_position('SHORT', grid_info['sell_price'], sell_amount)
def cancel_all_orders():
"""撤销所有未成交订单"""
try:
orders = exchange.GetOrders()
if orders:
for order in orders:
exchange.CancelOrder(order['Id'])
Sleep(100) # 避免频繁操作
return True
except Exception as e:
Log('撤单异常:', str(e))
return False
def get_real_position():
"""获取真实持仓信息"""
try:
positions = exchange.GetPosition()
if positions:
for pos in positions:
if pos['ContractType'] == 'swap' and pos['Amount'] > 0:
position_amount = pos['Amount'] * (1 if pos['Type'] == 0 else -1)
return position_amount, pos['Price'], pos['Profit']
return 0, 0, 0
except Exception as e:
Log('获取持仓异常:', str(e))
return 0, 0, 0
def update_account():
"""更新账户信息"""
try:
account = exchange.GetAccount()
if not account:
Log('获取账户信息失败')
return False
# 更新USDT资产信息
assets['USDT']['total_balance'] = account.Balance + account.FrozenBalance
assets['USDT']['margin_balance'] = account.Balance
# 获取真实持仓信息
position_amount, hold_price, profit = get_real_position()
assets[base_currency]['amount'] = position_amount
assets[base_currency]['hold_price'] = hold_price
assets[base_currency]['unrealised_profit'] = profit
return True
except Exception as e:
Log('更新账户异常:', str(e))
return False
def update_price():
"""更新行情价格"""
global InitPrice
ticker = exchange.GetTicker()
if not ticker:
Log('获取行情失败')
return False
# 设置初始价格
if InitPrice == 0:
InitPrice = ticker.Last
Log('设置初始价格:', InitPrice)
assets[base_currency]['price'] = ticker.Last
return True
def create_order(side, price, amount, order_type="开仓"):
"""使用CreateOrder下单函数"""
try:
if amount <= 0:
Log(f'订单数量无效:{amount}')
return False
# 构造期货合约symbol
contract_symbol = f"{symbol}.swap"
# 下单
order_id = exchange.CreateOrder(contract_symbol, side, price, amount)
if order_id:
Log(f'{order_type} {side} 下单成功:价格={price}, 数量={amount}, 订单ID={order_id}')
return order_id
else:
Log(f'{order_type} {side} 下单失败:价格={price}, 数量={amount}')
return False
except Exception as e:
Log('下单异常:', str(e))
return False
def safe_close_position(close_amount, price=-1):
"""安全平仓函数"""
try:
if close_amount <= 0:
Log(f'平仓数量无效:{close_amount}')
return False
# 实时获取持仓信息
current_position, _, _ = get_real_position()
# 检查是否真的有持仓
if current_position == 0:
Log('当前无持仓,跳过平仓操作')
return False
# 检查平仓数量是否超过持仓
if abs(close_amount) > abs(current_position):
Log(f'平仓数量超过持仓:持仓{current_position},平仓{close_amount},调整为持仓数量')
close_amount = abs(current_position)
# 根据当前持仓方向确定平仓操作
if current_position > 0: # 当前是多仓
side = "closebuy" # 平多仓
Log(f'平多仓:数量={close_amount},价格={price}')
else: # 当前是空仓
side = "closesell" # 平空仓
Log(f'平空仓:数量={close_amount},价格={price}')
return create_order(side, price, close_amount, "平仓")
except Exception as e:
Log('平仓异常:', str(e))
return False
def open_position(direction, price, amount):
"""开仓函数"""
try:
if amount <= 0:
Log(f'开仓数量无效:{amount}')
return False
# 确定开仓方向
if direction == 'LONG':
side = "buy" # 开多仓
Log(f'开多仓:数量={amount},价格={price}')
else: # SHORT
side = "sell" # 开空仓
Log(f'开空仓:数量={amount},价格={price}')
return create_order(side, price, amount, "开仓")
except Exception as e:
Log('开仓异常:', str(e))
return False
def update_status():
"""更新状态显示"""
try:
if Funding > 0:
current_balance = assets['USDT']['total_balance']
profit = current_balance - Funding
profit_rate = (profit / Funding) * 100
status_info = f"""
策略状态 - {symbol}
交易模式: 多空都做
当前价格: {assets[base_currency]['price']}
初始价格: {InitPrice}
持仓数量: {assets[base_currency]['amount']}
持仓价格: {assets[base_currency]['hold_price']}
账户余额: {current_balance:.4f} USDT
总收益: {profit:.4f} USDT ({profit_rate:.2f}%)
未实现盈亏: {assets[base_currency]['unrealised_profit']:.4f} USDT
"""
LogStatus(status_info)
except Exception as e:
Log('状态更新异常:', str(e))
def main():
"""主函数"""
# 设置错误过滤
SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused|Unknown")
# 初始化
init()
Log('策略启动成功')
while True:
try:
# 更新账户信息
if not update_account():
Log('更新账户信息失败,等待重试')
Sleep(5000)
continue
# 更新价格信息
if not update_price():
Log('更新价格信息失败,等待重试')
Sleep(5000)
continue
# 执行策略
execute_strategy()
# 更新状态
update_status()
# 休眠
Sleep(Interval * 1000)
except Exception as e:
Log('主循环异常:', str(e))
Sleep(5000) # 发生异常时等待5秒再继续

L’avantage d’une stratégie bidirectionnelle long-short réside dans son adaptabilité aux différentes conditions de marché, permettant des rendements rentables grâce à des opérations appropriées, qu’elles soient à la hausse, à la baisse ou volatiles. Cependant, elle exige également une gestion prudente des risques, notamment dans des conditions de marché extrêmes.
La flexibilité et l’automatisation des stratégies de grille en font un outil courant en trading quantitatif. Différentes variantes de grille s’adaptent à différents environnements de marché. Chaque stratégie possède ses propres scénarios d’application et avantages. Les investisseurs peuvent choisir la stratégie de grille la plus adaptée aux fluctuations spécifiques du marché et à leur appétence au risque, et la combiner avec des outils tels que la gestion dynamique des positions et les stratégies stop-loss et take-profit pour optimiser encore davantage l’efficacité de leur stratégie.
besoinillustrerLes trois stratégies présentées dans cet article sont toutes issues de la Strategy Plaza sur la plateforme Inventor, offrant ainsi un résumé. En tant que stratégie quantitative classique, les stratégies de grille offrent encore beaucoup à explorer, notamment comment éviter les appels de marge et atténuer les risques, et comment optimiser l’utilisation des fonds pour optimiser les rendements. Les personnes intéressées peuvent consulter la Strategy Plaza, où des stratégies de grille en temps réel sont disponibles pour consultation et étude.