2
フォロー
319
フォロワー

デジタル通貨分野におけるいくつかのグリッド戦略についての簡単な議論

作成日:: 2025-08-15 16:13:33, 更新日:: 2025-08-26 10:30:15
comments   0
hits   660

暗号通貨市場は独自の取引環境を提供し、グリッド取引戦略の理想的な適用シナリオを形成しています。従来の金融市場と比較して、暗号通貨セクターは24時間365日稼働しており、価格変動が継続的かつ頻繁に発生するため、グリッド戦略にとって豊富な裁定機会が生まれます。さらに、スポット契約や無期限契約などの主要な取引商品には満期制限がないため、トレーダーは契約満了リスクを心配することなく、長期にわたってポジションを保有することができます。さらに、暗号通貨市場の高いボラティリティと比較的高い流動性は、グリッド戦略の実施に有利な条件を提供します。

まさにこれらの特性こそが、グリッド取引戦略が暗号資産市場において高い適用性と収益性を示している理由です。グリッド取引は暗号資産市場で広く利用されている戦略であり、トレーダーは市場の方向性を予測することなく、市場のボラティリティから利益を得ることができます。異なる価格帯で売買注文を出すことで、グリッド取引はトレーダーが価格上昇時と下降時の両方で利益を獲得することを可能にします。

グリッド取引戦略には様々なバリエーションがあります。この記事では、初心者がこの古典的な定量取引手法を始めるのに役立つよう、いくつかの形式について簡単に説明します。グリッド取引戦略の核となる考え方は、異なる価格レベルで一連の買い注文と売り注文を出すことです。買い注文は価格がグリッドの下位ノードに達したときに発注され、売り注文は価格が上位ノードに達したときに発注されます。これにより、市場の変動からわずかな利益を得ることができます。この戦略の利点は、トレーダーが市場の方向性を予測する必要がなく、グリッド内の市場価格の変動に頼ることができることです。

グリッド戦略の原則

従来のグリッド取引の主要要素

  • グリッドノード:購入注文または売却注文が出される事前設定された価格ポイント。
  • グリッド間隔:隣接するグリッド ノード間の価格距離によって、トランザクションをトリガーするために価格がどの程度変動する必要があるかが決まります。
  • グリッドサイズ:グリッド ノードの合計数によって、戦略がカバーする価格範囲が制御されます。

グリッド取引戦略の仕組み

  • 価格が低レベルから上昇し、設定されたグリッドノードを突破すると、売り注文がトリガーされます。
  • 価格が高値から下落し、設定されたグリッド ノードを突破すると、買い注文がトリガーされます。
  • 常に異なるレンジで「安く買って高く売る」ことで、レンジ内で価格が上下に変動したとしても、その変動ごとに利益を得ることができます。

グリッド戦略を、グリッド間隔が8,000ドルから9,000ドル、グリッド間隔が500ドルに設定されているとします。価格が8,000ドルから8,500ドルに上昇すると、この戦略は8,000ドルで買い、8,500ドルで売ります。価格がさらに9,000ドルまで上昇すると、保有株の一部を再び売却します。価格が9,000ドルから8,500ドルまで下落すると、再び買います。このプロセスを繰り返すことで、この戦略は市場の変動の中でも継続的に利益を積み上げることができます。

グリッド取引戦略とバランス取引戦略の比較

バランス戦略の核心は、資産の固定比率を維持することです。例えば、デジタル通貨50%と法定通貨50%などです。仮想通貨の価格が上昇し、保有する仮想通貨の割合が50%を超えると、仮想通貨を売却し、価格が下落すると購入します。これにより、保有資産の価値が固定比率に近づきます。バランス戦略では、市場の変動に関わらず、一定量の仮想通貨を維持します。

グリッド戦略とバランス戦略の類似点と相違点

  • 類似点:どちらも、安く買って高く売ることでボラティリティから利益を得ており、市場が元の価格に戻ったときに価値を実現できる戦略です。
  • 違い:グリッド戦略は事前に設定された価格帯内でのみ取引を行いますが、バランス戦略は特定の価格帯に依存しません。グリッド戦略では、価格がレンジ外に下落すると取引を継続できなくなる可能性がありますが、バランス戦略では、常に売買を行い、流動性を維持できます。

契約:算術グリッド戦略

算術グリッド戦略は、ボラティリティの高い市場でよく用いられる、古典的なクオンツ取引戦略です。この戦略は、固定価格間隔(算術間隔)で売買注文を出すことで、価格変動から利益を獲得します。仮想通貨や特定の先物契約など、ボラティリティは高いものの方向性が予測しにくい市場に適しています。

コアロジック

コアコンセプト:

  1. 等間隔
    算術グリッド戦略では、買値と売値の間にギャップがあります。固定価格間隔コード内にあるgrid例えば、価格が300単位変動した場合(コードではgrid=300)になると、買い注文または売り注文がトリガーされます。

  2. グリッドの初期化
    この戦略は、現在の価格に基づいて初期の買値と売値を生成する。buyp そして sellp2つの価格間隔はグリッド間隔に基づいていますgrid現在の価格より上または下に設定するgridユニット。

  3. 利益確定と反転
    価格が特定のレンジまで上昇すると、この戦略はロングポジションエリアで買い注文を出し、利益確定のために売り注文を出す。価格が逆ポジションエリア(upper)、ロングポジションは利益を確定してショートし、その逆も同様です。

  4. グリッド内の位置管理
    グリッド内の各購入または販売アクションは、価格が事前設定された値に達するとトリガーされます。buyp または sellp各取引の後に、システムは固定グリッド間隔を維持するために次の買値と売値のグループを自動的に調整します。

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

デジタル通貨分野におけるいくつかのグリッド戦略についての簡単な議論

ロング・ショート双方向グリッド戦略のメリットは、様々な市場状況への適応力にあります。上昇相場、下降相場、あるいはボラティリティの高い相場状況など、適切な運用を通じて収益性の高いリターンを得ることができます。しかし、特に極端な市場状況においては、慎重なリスク管理も必要です。

要約する

グリッド戦略は柔軟性と自動化により、クオンツ取引において一般的なツールとなっています。様々なグリッドバリエーションがあり、様々な市場環境に適応できます。それぞれの戦略には、それぞれ固有の適用シナリオと利点があります。投資家は、具体的な市場変動と個人のリスク許容度に基づいて適切なグリッド戦略を選択し、ダイナミックポジション管理やストップロス・テイクプロフィット戦略などのツールと組み合わせることで、戦略の有効性をさらに最適化することができます。

必要例示するこの記事で解説した3つの戦略はすべて、Inventorプラットフォームの戦略プラザに掲載されており、概要を説明しています。グリッド戦略は古典的なクオンツ戦略の一種ですが、マージンコールを回避しリスクを軽減する方法、資金活用を最適化してリターンを向上させる方法など、まだ探求すべき点が数多くあります。ご興味のある方は、戦略プラザをご覧ください。リアルタイムのグリッド戦略を参照・研究することができます。