2
Seguir
319
Seguidores

Una breve discusión sobre varias estrategias de red en el campo de la moneda digital

Creado el: 2025-08-15 16:13:33, Actualizado el: 2025-08-26 10:30:15
comments   0
hits   660

El mercado de criptomonedas ofrece un entorno de trading único, lo que crea un escenario ideal para las estrategias de trading en red. A diferencia de los mercados financieros tradicionales, el sector de las criptomonedas opera 247, con fluctuaciones de precios continuas y frecuentes, lo que genera abundantes oportunidades de arbitraje para las estrategias de red. Además, los principales instrumentos de trading, como los contratos al contado y perpetuos, no tienen restricciones de vencimiento, lo que permite a los operadores mantener posiciones a largo plazo sin preocuparse por el riesgo de vencimiento. Asimismo, la alta volatilidad y la liquidez relativamente alta del mercado de criptomonedas ofrecen condiciones favorables para la implementación de estrategias de red.

Precisamente por estas características, las estrategias de trading en cuadrícula demuestran una gran aplicabilidad y un gran potencial de rentabilidad en el mercado de criptomonedas. El trading en cuadrícula es una estrategia ampliamente utilizada en el mercado de criptomonedas que permite a los operadores beneficiarse de la volatilidad del mercado sin tener que predecir su dirección. Al colocar órdenes de compra y venta en diferentes rangos de precios, el trading en cuadrícula ayuda a los operadores a obtener ganancias tanto durante las subidas como durante las bajadas de precios.

Las estrategias de trading en cuadrícula presentan muchas variantes. Este artículo solo analizará brevemente algunos formatos para ayudar a los principiantes a iniciarse en este método clásico de trading cuantitativo. La idea central de una estrategia de trading en cuadrícula es colocar una serie de órdenes de compra y venta a diferentes niveles de precio. Las órdenes de compra se colocan cuando el precio alcanza los nodos inferiores de la cuadrícula, y las órdenes de venta cuando alcanza los nodos superiores, obteniendo así pequeñas ganancias de las fluctuaciones del mercado. La ventaja de esta estrategia es que los operadores no necesitan predecir la dirección del mercado; se basan en las fluctuaciones del precio dentro de la cuadrícula.

Principios de la estrategia de red

Elementos clave del comercio tradicional en red

  • Nodos de la cuadrícula:Puntos de precio preestablecidos en los que se colocan órdenes de compra o venta.
  • Espaciado de cuadrícula:La distancia de precios entre nodos de la red adyacentes determina cuánto debe fluctuar el precio para activar una transacción.
  • Tamaño de la cuadrícula:El número total de nodos de la red controla el rango de precios cubierto por la estrategia.

Cómo funcionan las estrategias de trading en red

  • Cuando el precio sube desde un nivel bajo y rompe el nodo de la cuadrícula establecido, se activa una orden de venta.
  • Cuando el precio cae desde un nivel alto y rompe el nodo de la cuadrícula establecido, se activa una orden de compra.
  • Al “comprar barato y vender caro” constantemente en diferentes rangos, incluso si el precio fluctúa de un lado a otro dentro del rango, aún puede obtener ganancias de cada fluctuación.

Ejemplo

Supongamos que se establece una estrategia de cuadrícula con un intervalo de \(8,000 a \)9,000, con un intervalo de \(500. Cuando el precio sube de \)8,000 a \(8,500, la estrategia comprará a \)8,000 y venderá a \(8,500. Si el precio sube aún más a \)9,000, volverá a vender algunas de sus posiciones. Cuando el precio baje de \(9,000 a \)8,500, volverá a comprar. Al repetir este proceso, la estrategia puede acumular ganancias continuamente ante las fluctuaciones del mercado.

Comparación entre la estrategia de trading en cuadrícula y la estrategia de trading equilibrado

La base de una estrategia equilibrada es mantener una proporción fija de activos, como un 50% de moneda digital y un 50% de moneda fiduciaria. Cuando el precio de una criptomoneda sube y la proporción de criptomonedas en cartera supera el 50%, se vende; cuando baja, se compra. Esto garantiza que el valor de los activos en cartera se mantenga cercano a la proporción fija. Independientemente de las fluctuaciones del mercado, una estrategia equilibrada mantiene una cierta cantidad de criptomonedas.

Similitudes y diferencias entre la estrategia de red y la estrategia de equilibrio

  • Similitudes:Ambos se benefician de la volatilidad comprando barato y vendiendo caro, y la estrategia puede generar valor cuando el mercado vuelve a su precio original.
  • Diferencias:Las estrategias de cuadrícula operan únicamente dentro de un rango de precios preestablecido, mientras que las estrategias balanceadas son independientes de rangos de precios específicos. Una estrategia de cuadrícula podría no poder seguir operando si el precio cae fuera del rango, mientras que una estrategia balanceada permite la compra y venta constantes, manteniendo la liquidez.

Contrato: Estrategia de cuadrícula aritmética

La estrategia de cuadrícula aritmética es una estrategia clásica de trading cuantitativo, frecuentemente utilizada en mercados volátiles. Esta estrategia captura las ganancias de las fluctuaciones de precios mediante la colocación de órdenes de compra y venta a intervalos de precio fijos (intervalos aritméticos). Es adecuada para mercados con alta volatilidad pero dirección impredecible, como las criptomonedas y ciertos contratos de futuros.

Lógica básica

Conceptos básicos:

  1. intervalo equidistante
    En la estrategia de cuadrícula aritmética, existe una brecha entre los precios de compra y venta.Intervalos de precios fijos, que está en el códigogridPor ejemplo, cuando el precio fluctúa en 300 unidades (como en el códigogrid=300), se activa una orden de compra o venta.

  2. Inicialización de la cuadrícula
    La estrategia genera los precios iniciales de compra y venta en función del precio actual, que sonbuyp y sellpLos dos intervalos de precios se basan en el intervalo de la cuadrícula.gridPara fijar, respectivamente, por encima y por debajo del precio actualgridunidades.

  3. Tomar ganancias y revertir
    Cuando el precio sube hasta cierto rango, la estrategia comprará en la zona de posición larga y emitirá una orden de venta para obtener ganancias. Si el precio continúa subiendo hasta la zona de posición inversa (upper), la posición larga tomará ganancias y se convertirá en corta, y viceversa.

  4. Gestión de posiciones dentro de la red
    Cada acción de compra o venta dentro de la cuadrícula se activará cuando el precio alcance el valor preestablecido.buyp o sellpDespués de cada transacción, el sistema ajusta automáticamente el siguiente grupo de precios de compra y venta para mantener un intervalo de cuadrícula fijo.

  5. Adición y reducción de posiciones
    La estrategia ajusta continuamente su posición en función del precio de la red. Cuando el precio alcanza el punto de compra, aumenta su posición (incrementa su posición); cuando alcanza el punto de venta, la reduce gradualmente (disminuye su posición). Al comprar y vender repetidamente, captura cada pequeña fluctuación del mercado.

Código de estrategia

'''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"])

image

La estrategia de cuadrícula aritmética tiene una aplicabilidad considerable en el mercado de criptomonedas, especialmente en mercados volátiles pero impredecibles. Al colocar órdenes de compra y venta a intervalos de precio fijos, esta estrategia captura eficazmente las fluctuaciones del mercado, manteniendo las operaciones automatizadas y una lógica simple. La alta volatilidad del mercado de criptomonedas ofrece una buena oportunidad para que esta estrategia prospere.

Cabe destacar que los costos de transacción de una estrategia de cuadrícula aritmética provienen principalmente de las frecuentes órdenes de compra y venta, más que de su colocación o cancelación. Esta característica requiere especial atención en las plataformas de intercambio de criptomonedas con altas comisiones por transacción. Para optimizar la rentabilidad, se recomienda elegir plataformas con comisiones más bajas y ajustar el intervalo de la cuadrícula y la tasa de asignación de fondos según las condiciones específicas del mercado.

En general, la estrategia de cuadrícula aritmética es adecuada para el volátil mercado de criptomonedas, pero puede estar sujeta a un riesgo significativo en mercados unilaterales. Al establecer parámetros adecuados y optimizar la gestión de fondos, se puede mejorar eficazmente la solidez y la rentabilidad de la estrategia.

Spot: Estrategia de cuadrícula dinámica

Estrategia de red dinámicaA diferencia de la estrategia tradicional de red fija,Generación dinámicayAjuste de nodos de mallaEsta estrategia permite una mayor flexibilidad ante las fluctuaciones del mercado. Genera nuevos nodos de la red en función de las fluctuaciones del mercado en tiempo real, lo que mejora su adaptabilidad y la capacidad de control de riesgos. El concepto central es generar nuevos nodos únicamente cuando las fluctuaciones de precios superan un umbral determinado y gestionar las posiciones adecuadamente.

Características principales

  1. Generación dinámica de nodos de malla

    • El precio del mercado rompe el nodo de la cuadrícula anterior y el rango de fluctuación excede el rango preestablecido (en_GridPointDiscontrol), la estrategia genera nuevos nodos de red.
    • Cada nodo de la red registra el precio actual y la información de la posición, y establece las condiciones de cierre (por_GridCovDisSpread de cierre controlado).
  2. Operaciones de compra y venta

    • Dirección largadirection = 1): Cuando el precio sube y rompe el nodo de la red, vende los activos que tenías; cuando baja, vuelve a comprar.
    • Dirección cortadirection = -1): Cuando el precio cae y rompe el nodo de la red, compre el activo; cuando rebote, venda el activo retenido.
  3. Operación de cierre

    • Cuando el precio alcanza el precio de cierre establecido (_GridCovDisEstablecer), ejecutar operaciones de recompra (cuando se va largo) o venta (cuando se va corto) de acuerdo con la dirección actual para completar el cierre de la posición.
  4. Control de cantidad de malla

    • Si el número de nodos de la red excede el valor máximo de configuración (_GridNum), la estrategia eliminará automáticamente el primer nodo de la red, evitando así posiciones excesivas y reduciendo riesgos.

Lógica básica

  1. Parámetros de inicialización

    • _GridNum:Número máximo de nodos de la cuadrícula, la cantidad máxima de nodos de la cuadrícula que la estrategia de control permite mantener al mismo tiempo.
    • _GridPointAmount:La cantidad de pedido de cada nodo de la cuadrícula.
    • _GridPointDis:El espaciamiento de precios entre los nodos de la cuadrícula.
    • _GridCovDisLa diferencia de precio para cerrar una posición. Cuando la fluctuación entre el precio de mercado y el precio de la red supera esta diferencia, la posición se cerrará.
  2. Función UpdateGrid

    • Basado en el precio actual (current_price), precio de compra (bids_price) y el precio de venta (asks_price) actualiza los nodos de la red. Cuando el precio de mercado supera un nodo de la red, la estrategia genera un nuevo nodo y ejecuta la operación correspondiente.
    • Verifique si se activan las condiciones de cierre y ejecute la operación de cierre cuando se activen.
    • Controla el número máximo de nodos de la red. Si se supera este número, se eliminarán los nodos más antiguos.
  3. Bucle principal

    • mainLa función obtiene continuamente datos de precios de mercado en tiempo real y realiza llamadas.UpdateGridLas funciones actualizan los nodos de la red y realizan operaciones comerciales.
    • aprobarLogStatusRegistre el estado actual de la red, la información de la cuenta, etc. para facilitar el monitoreo en tiempo real del funcionamiento de la estrategia.

Código de estrategia (requiere referencias de plantillas de dibujo y puntos de Python)

'''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)

image

Nota: No se puede hacer esto.

  1. Para ayudar a todos a comprender el proceso de generación de la cuadrícula, se agregan muchos comentarios al código, que se pueden eliminar en la aplicación real.
  2. Para facilitar la negociación, la estrategia spot utiliza la biblioteca de plantillas de trading spot. Puede consultar el código fuente para obtener más información.
  3. Cuando se aplica al comercio real, es necesario mejorarlo de acuerdo con las características de los diferentes intercambios.

Futuros: Estrategia de red bidireccional de largo y corto plazo

La estrategia de Cuadrícula Bidireccional Largo-Corto es una variante de cuadrícula más compleja pero potente que permite operar simultáneamente en posiciones largas y cortas, maximizando las oportunidades de obtener ganancias en mercados volátiles. En esencia, esta estrategia ajusta dinámicamente las posiciones en función de las desviaciones del precio inicial, logrando una estrategia verdaderamente neutral al mercado.

Características principales

  1. Modos largo y corto:Independientemente de si el precio sube o baja, la estrategia puede obtener ganancias operando en la dirección correspondiente.
  2. Ajuste de posición dinámico:Calcule la posición objetivo en función de la relación entre la desviación del precio y el precio inicial.
  3. Orden de cuadrícula bidireccional:Establezca órdenes de compra y venta al mismo tiempo para capturar las fluctuaciones de precios en ambas direcciones
  4. Control de riesgos:Reducir los riesgos unilaterales mediante una gestión razonable de la posición y el control de órdenes.

Lógica de estrategia

La lógica central de la estrategia es determinar la posición objetivo en función del grado de desviación entre el precio y el precio inicial:

  • Cuando el precio sube, la posición objetivo es negativa (corta), y cuanto más sube el precio, mayor es la posición corta.
  • Cuando el precio baja, la posición objetivo es positiva (larga). Cuanto más baja el precio, mayor es la posición larga.
  • Ajuste gradualmente la posición actual a la posición objetivo mediante la ejecución de órdenes de cuadrícula

Código de estrategia

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秒再继续

Una breve discusión sobre varias estrategias de red en el campo de la moneda digital

La ventaja de una estrategia de red bidireccional de largo-corto plazo es su adaptabilidad a diversas condiciones de mercado, lo que permite obtener rentabilidad mediante operaciones adecuadas, ya sean alcistas, bajistas o volátiles. Sin embargo, también requiere una gestión cuidadosa del riesgo, especialmente en condiciones de mercado extremas.

Resumir

La flexibilidad y automatización de las estrategias de cuadrícula las convierten en una herramienta común en el trading cuantitativo. Las diferentes variantes de cuadrícula se adaptan a diversos entornos de mercado. Cada estrategia tiene sus propios escenarios de aplicación y ventajas. Los inversores pueden elegir la estrategia de cuadrícula adecuada en función de las fluctuaciones específicas del mercado y su tolerancia al riesgo, y combinarla con herramientas como la gestión dinámica de posiciones y las estrategias de stop-loss y take-profit para optimizar aún más su eficacia.

necesidadilustrarLas tres estrategias analizadas en este artículo provienen de Strategy Plaza, en la plataforma Inventor, y ofrecen un resumen. Como estrategia cuantitativa clásica, las estrategias de cuadrícula aún ofrecen mucho por explorar, como la forma de evitar las llamadas de margen y mitigar el riesgo, y la forma de optimizar la utilización de los fondos para aumentar la rentabilidad. Los interesados pueden visitar Strategy Plaza, donde encontrarán estrategias de cuadrícula en tiempo real para consulta y estudio.