avatar of ianzeng123 ianzeng123
关注 私信
2
关注
319
关注者

浅谈数字货币领域几种网格策略

创建于: 2025-08-15 16:13:33, 更新于: 2025-08-26 10:30:15
comments   0
hits   660

[TOC]

浅谈数字货币领域几种网格策略

数字货币市场具有独特的交易环境,为网格交易策略提供了理想的应用场景。与传统金融市场相比,数字货币领域实行24小时不间断交易,价格变动连续且频繁,为网格策略创造了丰富的套利机会。同时,现货和永续合约等主要交易品种不存在到期时间限制,使得交易者可以长期持有头寸而无需担心合约到期的风险。此外,数字货币市场的高波动性、相对较高的流动性,都为网格策略的实施提供了有利条件。

正是基于这些特点,网格交易策略在数字货币市场中展现出了强大的适用性和盈利潜力。网格交易策略是一种在数字货币市场中广泛应用的策略,能够让交易者在无需预测市场方向的前提下,利用市场的波动性获利。通过在不同价格区间设置买入和卖出订单,网格交易能够帮助交易者在价格上涨和下跌的过程中捕捉利润。

网格交易策略拥有很多变体,本文只是浅谈几种格式,帮助新生朋友入门了解这一经典的量化交易方法。网格交易策略的核心思想是在不同的价格水平设置一系列的买入和卖出订单。当价格达到网格的下方节点时进行买入,达到上方节点时进行卖出,从而在市场波动中赚取小幅利润。这一策略的优势在于,交易者不必预测市场方向,靠的是市场价格在网格内的波动。

网格策略原理

传统网格交易的关键要素

  • 网格节点(Grid Nodes): 预设的价格点,即在这些价格点设置买入或卖出订单。
  • 网格间距(Grid Spacing): 相邻网格节点之间的价格距离,决定了价格需要波动多大才能触发一次交易。
  • 网格数量(Grid Size): 网格节点的总数,控制策略覆盖的价格范围。

网格交易策略的工作原理

  • 当价格从低位上涨,突破设定的网格节点时,触发卖出订单。
  • 当价格从高位回落,突破设定的网格节点时,触发买入订单。
  • 通过不断地在不同区间进行”低买高卖”,即使价格在区间内来回波动,也能够从每次波动中获取利润。

示例说明

假设一个网格策略的网格区间设定为8000至9000美元,网格间距为500美元。当价格从8000上涨至8500时,策略会在8000美元买入,8500美元卖出;如果价格进一步上涨到9000美元,再次卖出一部分持仓;当价格从9000跌回8500时,则会重新买入。如此反复操作,策略可以在市场波动中不断累积收益。

网格交易策略与平衡策略的比较

平衡策略的核心是始终保持一个固定比例的资产,例如50%的数字货币和50%的法币。当币价上涨,持有的币的比例超过50%时卖出,反之则买入,使得持有的资产价值始终维持在固定的比例附近。无论市场如何变化,平衡策略都会持有一定数量的币。

网格策略与平衡策略的异同

  • 相同点: 两者都通过低买高卖的方式在波动中获利,并且在市场回到原始价格时,策略可以实现增值。
  • 不同点: 网格策略只在预设的价格区间内操作,而平衡策略不依赖于具体的价格区间。网格策略可能会因为价格超出区间而无法继续操作,而平衡策略则始终可以进行买卖操作,保持资金的流动性。

合约:等差网格策略

等差网格策略是一种经典的量化交易策略,常用于波动市场中。该策略通过在固定的价格间隔(等差)设置买卖单来捕捉价格波动带来的收益。适用于波动较大但方向难以预测的市场,比如加密货币或某些期货合约。

核心逻辑

核心概念:

  1. 等差间隔
    在等差网格策略中,买卖单的价格之间有固定的价格间隔,也就是代码中的 grid。例如,当价格每波动300个单位(如代码中的 grid=300),就会触发一次买入或卖出的订单。

  2. 网格初始化
    策略根据当前价格,生成初始的买入和卖出价格,分别是 buypsellp。这两个价格间隔是根据网格间隔 grid 进行设置的,分别在当前价格上方和下方各 grid 个单位。

  3. 止盈反手
    当价格上涨到一定区域时,策略会在多头持仓区域买入,同时设置卖出单进行止盈。如果价格继续上涨至反手区域(upper),则多头仓位会止盈并反手做空,反之亦然。

  4. 网格内仓位管理
    网格内的每一个买入或卖出行为都会在价格到达预设的 buypsellp 时触发。在每次成交后,系统会自动调整下一组的买入和卖出价格,使其继续保持固定的网格间隔。

  5. 加仓和减仓
    策略根据网格价格不断调整仓位。当价格触及买入点时,会增加仓位(加仓);当价格触及卖出点时,逐步减少仓位(减仓)。通过多次买卖,捕捉每一波小幅度的市场波动。

策略代码

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

等差网格策略在数字货币领域具有一定的适用性,特别是在波动较大但方向难以预测的市场中。通过在固定的价格间隔设置买卖单,该策略能够有效捕捉市场的波动收益,同时保持操作的自动化和逻辑的简洁性。数字货币市场的高波动性为这一策略提供了良好的发挥空间。

值得注意的是,等差网格策略的交易成本主要来源于频繁的买卖订单,而非挂单或撤单。这种特性在交易手续费较高的数字货币交易所中需要特别关注。为了优化收益,建议选择手续费较低的交易所,同时根据具体市场情况调整网格间隔和资金分配比例。

整体来看,等差网格策略非常适合震荡行情的数字货币市场,但在单边行情中可能面临较大风险。通过合理设置参数和优化资金管理,可以有效提升策略的稳健性和盈利能力。

现货:动态网格策略

动态网格策略不同于传统的固定网格策略,它通过动态生成调整网格节点,使策略在市场波动中更为灵活。这种策略能够根据市场的实时波动生成新的网格节点,从而提高策略的适应性与风险控制能力。核心思想是在价格波动超过某个设定阈值时,才生成新节点,并对仓位进行合理的管理。

核心特点

  1. 动态网格节点生成

    • 市场价格突破上一个网格节点,且波动幅度超过预设区间(由_GridPointDis控制)时,策略会生成新的网格节点。
    • 每个网格节点记录当前价格和持仓信息,并设定平仓条件(由_GridCovDis控制的平仓差价)。
  2. 买卖操作

    • 做多方向direction = 1):当价格上涨突破网格节点时,卖出已持有资产;回调时,再买入。
    • 做空方向direction = -1):当价格下跌突破网格节点时,买入资产;反弹时,卖出已持有资产。
  3. 平仓操作

    • 当价格触及设定的平仓差价(由_GridCovDis设定),根据当前方向执行回购(做多时)或卖出(做空时)操作,完成平仓。
  4. 网格数量控制

    • 若网格节点数超过最大设定值(_GridNum),策略会自动删除最早的网格节点,从而防止仓位过多,降低风险。

核心逻辑

  1. 初始化参数

    • _GridNum:最大网格节点数量,控制策略最多允许同时持有的网格节点数。
    • _GridPointAmount:每个网格节点的下单量。
    • _GridPointDis:网格节点间的价格间距。
    • _GridCovDis:平仓的价格差,当市场价格与网格价格的波动超过该差价时,进行平仓操作。
  2. UpdateGrid函数

    • 根据当前价格(current_price)、买入价格(bids_price)和卖出价格(asks_price)更新网格节点。每当市场价格突破某个网格节点时,策略会生成新的网格节点并执行相应的交易操作。
    • 检查是否触发平仓条件,并在触发时执行平仓操作。
    • 控制最大网格节点数量,若超过最大数量,会删除最早的网格节点。
  3. 主循环

    • main函数不断获取市场实时价格数据,调用UpdateGrid函数更新网格节点并执行交易操作。
    • 通过LogStatus记录当前网格状态、账户信息等,便于实时监控策略运行情况。

策略代码(需要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

注意事项: 1. 为了帮助大家理解网格的生成过程,代码添加很多注释,大家在实际应用中可以删除。 2. 为方便交易,现货策略使用到现货模版交易类库,大家可以观察源码学习一下。 3. 当应用于实盘,需根据不同交易所特性进行完善。

期货:多空双向网格策略

多空双向网格策略是一种更为复杂但功能强大的网格变体,它能够同时在多空两个方向进行交易,从而在震荡市场中最大化收益机会。该策略的核心是基于价格偏离初始价格的程度来动态调整持仓,实现真正的市场中性策略。

核心特点

  1. 多空都做模式:无论价格上涨还是下跌,策略都能通过相应的方向操作获得收益
  2. 动态仓位调整:根据价格偏离初始价格的比例计算目标持仓
  3. 双向网格订单:同时设置买单和卖单,捕捉价格双向波动
  4. 风险控制:通过合理的仓位管理和订单控制,降低单边风险

策略逻辑

策略的核心逻辑是基于价格与初始价格的偏离程度来确定目标持仓: - 当价格上涨时,目标持仓为负(空头),价格上涨越多,空头仓位越大 - 当价格下跌时,目标持仓为正(多头),价格下跌越多,多头仓位越大 - 通过网格订单的成交来逐步调整实际持仓向目标持仓靠拢

策略代码

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

浅谈数字货币领域几种网格策略

多空双向网格策略的优势在于能够适应各种市场环境,无论是上涨、下跌还是震荡,都能通过相应的操作获得收益。但同时也需要注意风险控制,特别是在极端行情下的资金管理。

总结

网格策略的灵活性和自动化特性使其成为量化交易中的常用工具,不同的网格变种能适应多种市场环境。每种策略都有其特定的适用场景和优势,投资者可以根据具体的市场波动特点和个人风险偏好,选择适合的网格策略,并结合动态仓位管理、止盈止损等工具,进一步优化策略效果。

需要说明的是,本文所谈的三种类型皆来自于发明者平台的策略广场,进行了一定的总结。网格策略作为量化策略中的经典类型,还有很多值得深挖的地方,比如怎样避免爆仓降低风险,以及更好地提高资金使用率从而提升收益。如果有兴趣的朋友,可以点击策略广场,这里有实盘级别的网格策略可以供大家参考学习。

相关推荐