2
konzentrieren Sie sich auf
319
Anhänger

Python Multi-Currency Quantitative Strategy Framework: Designideen und Implementierung im Detail

Erstellt in: 2025-08-29 13:10:54, aktualisiert am: 2025-08-31 09:11:53
comments   0
hits   626

Einführung:

Kürzlich ein Benutzer auf Xiaocao LehrerSo erstellen Sie nach dem FMZ-Upgrade schnell eine universelle Handelsstrategie für mehrere WährungenBitte hinterlassen Sie einen Kommentar im Kommentarbereich dieses Artikels, in der Hoffnung, eine Python-Implementierung dieses Strategie-Frameworks bereitzustellen. Um den Anforderungen von Python-Entwicklern gerecht zu werden, baut dieser Artikel auf Xiaocaos ursprünglichen Ideen auf und kombiniert sie mit der simulierten Handelsumgebung von Binance, um detailliert zu erklären, wie ein universelles quantitatives Handels-Framework für mehrere Währungen erstellt wird.

Dieses Framework verfügt über die folgenden Funktionen:

  • Basierend auf der Python-Sprache, leicht zu verstehen und zu erweitern
  • Unterstützt gleichzeitige Transaktionen in mehreren Währungen
  • Verwendung des simulierten Binance-Austauschs für Sicherheitstests
  • Bietet vollständige Codebeispiele und ausführliche Kommentare

Wir hoffen, dass dieser Artikel Ihnen den Einstieg in den quantitativen Multi-Währungs-Handel erleichtert. Entwickler sind herzlich eingeladen, auf Basis dieser Erfahrungen Innovationen und Optimierungen vorzunehmen und noch umfassendere und personalisierte Handelsstrategien zu entwickeln. Lassen Sie uns gemeinsam den Weg des quantitativen Handels weiter erkunden!

Initialisierungsstrategie

In der Initialisierungsphase der Handelsstrategie definieren wir zunächst die globalen VariablenSYMBOLSQUOTOINTERVAL, stellt die Zieltransaktionswährung, die Basiswährung und die Intervallzeit dar,InfoVariablen werden verwendet, um alle wichtigen Daten zu speichern, die während der Ausführung der Strategie erforderlich sind.InitInfoDie Funktion initialisiert diese Daten, einschließlich Kontoinformationen, Zeitmanagement, Marktdaten für jede Handelswährung, Auftragsinformationen, Positionsinformationen usw. Diese Initialisierungsschritte stellen sicher, dass die Strategie bei der Ausführung über eine klare Datenstruktur und einen klaren Anfangszustand verfügt und legen damit den Grundstein für die anschließende Strategieausführung.

import time
import json 

SYMBOLS = 'LINK,ETH,TRB'
QUOTO = 'USDT'
INTERVAL = 5

# 全局变量,储存数据
# SYMBOLS代表要交易的币种,格式如"BTC,ETH,LTC"
# QUOTO为基础货币,永续合约常见的有USDT,USDC
# INTERVAL代表循环的间隔
Info = {
    'trade_symbols': SYMBOLS.split(','),  # 交易币种
    'base_coin': QUOTO,                   # 基础货币
    'ticker': {},                         # 行情数据
    'order': {},                          # 订单信息
    'account': {},                        # 账户信息
    'precision': {},                      # 精度信息
    'position': {},                       # 仓位信息
    'time': {},                           # 时间相关数据
    'count': {},                          # 计数器
    'interval': INTERVAL                  # 循环的间隔时间
}

# 初始化策略
def InitInfo():

    # 初始化账户信息,初始余额为0
    Info['account'] = {
        'init_balance': 0,  # 初始余额
        'wallet_balance': 0,  # 钱包余额
        'margin_balance': 0,  # 保证金余额
        'margin_used': 0,  # 已用保证金
        'margin_free': 0,  # 可用保证金
        'profit': 0,  # 总收益
        'profit_rate': 0,  # 收益率
        'unrealised_profit': 0,  # 未实现收益
    }

    # 初始化时间数据,控制更新的时间
    Info['time'] = {
        'update_ticker_time': 0,    # 更新行情的时间
        'update_pos_time': 0,       # 更新仓位的时间
        'update_profit_time': 0,    # 更新利润的时间
        'update_account_time': 0,   # 更新账户信息的时间
        'update_status_time': 0,    # 更新状态的时间
        'last_loop_time': 0,        # 上一次主循环的时间
        'loop_delay': 0,             # 循环延迟
        'start_time': time.time()
    }

    # 初始化每个交易币种的数据
    for symbol in Info['trade_symbols']:
        Info['ticker'][symbol] = {'last': 0, 'ask': 0, 'bid': 0}  # 行情
        Info['order'][symbol] = {                                 # 订单信息
            'buy': {'id': 0, 'price': 0, 'amount': 0},
            'sell': {'id': 0, 'price': 0, 'amount': 0}
        }
        Info['position'][symbol] = {                              # 仓位信息
            'amount': 0, 'hold_price': 0, 'unrealised_profit': 0, 'open_time': 0, 'value': 0
        }
        Info['precision'][symbol] = {}  # 精度信息初始化为空
        Info['position'][symbol] = {                              # 仓位信息
            'amount': 0, 'hold_price': 0, 'unrealised_profit': 0, 'open_time': 0, 'value': 0
        }

Erhalten Sie Marktinformationen und Präzisionseinstellungen

Dieser Schritt stellt sicher, dass die Genauigkeit von Preisen, Mengen und anderen Aspekten der von uns verarbeiteten Währungen sowie der Bestellmenge den Standards der Börse entspricht. Verschiedene Handelspaare (wie BTC/USD oder ETH/USDT) haben unterschiedliche Mindestgenauigkeitsanforderungen für Preise und Mengen. Daher müssen wir diese Genauigkeitsinformationen von der API der Börse beziehen, um nicht konforme Bestellungen zu vermeiden. Beispielsweise sind bei ETH/USDT möglicherweise zwei Dezimalstellen zulässig, während bei BTC/USDT acht Dezimalstellen zulässig sind.

Zweck:

  • Ermitteln Sie die Preis- und Mengengenauigkeit für jede Währung, um die Genauigkeit der Bestelldaten sicherzustellen.
  • Verhindern Sie Bestellfehler aufgrund von Präzisionsfehlern.
# 获取精度信息
def GetPrecision():
    # 获取交易所的市场信息
    for presym in Info['trade_symbols']:
        curcontract = presym + '_USDT.swap'
        exchange.GetTicker(curcontract)
    exchange_info = exchange.GetMarkets()
    
    # 遍历市场中的所有交易对
    for pair, data in exchange_info.items():
        symbol = pair.split('_')[0]  # 永续合约交易对的格式为 BTC_USDT.swap
        
        # 检查该交易对是否为我们要交易的币种,基础货币是否匹配,且是永续合约
        if symbol in Info['trade_symbols'] and pair.split('.')[0].endswith(Info['base_coin']) and pair.endswith('swap'):
            # 获取该交易对的精度信息
            Info['precision'][symbol] = {
                'tick_size': data['TickSize'],                  # 价格精度
                'amount_size': data['AmountSize'],              # 数量精度
                'price_precision': data['PricePrecision'],      # 价格小数位精度
                'amount_precision': data['AmountPrecision'],    # 数量小数位精度
                'min_qty': data['MinQty'],                      # 最小下单数量
                'max_qty': data['MaxQty'],                      # 最大下单数量
                'min_notional': data['MinNotional'],            # 最小交易额
                'ctVal': data['CtVal']                          # 合约价值,如1张代表0.01个币
            }
            
            # 检查合约价值的计价货币是否为symbol,避免币本位情况
            if data['CtValCcy'] != symbol:
                raise Exception("不支持币本位")

GetPrecisionFunktion

  • Erhalten Sie über APIs Marktinformationen von Börsen, einschließlich Präzisionseinstellungen für Handelspaare.
  • Erfassen Sie für zulässige Handelspaare Informationen wie Preisgenauigkeit, Mengengenauigkeit, minimales und maximales Transaktionsvolumen und Vertragswert.
  • Überprüft, ob es sich um eine Transaktion mit Münzmarge handelt, und löst in diesem Fall eine Ausnahme aus.

Angebote einholen

Greifen Sie über die API auf aktuelle Marktdaten zu, wie z. B. den aktuellen Kurs, das beste Gebot, das beste Angebot und die Orderbuchtiefe. Diese Informationen sind entscheidend für nachfolgende Handelsentscheidungen. Je nach Strategie können diese Daten auf Candlestick-Charts (OHLC-Daten) oder Tick-by-Tick-Daten basieren.

Zweck:

  • Holen Sie sich die neuesten Handelsdaten des aktuellen Marktes, damit die Strategie Kauf- und Verkaufsentscheidungen auf der Grundlage dieser Daten treffen kann.
  • Enthält die Erfassung von Echtzeit- und historischen Daten für technische Indikatorberechnungen.
# 更新行情信息
def UpdateTicker():
    
    # 记录当前更新时间戳
    Info['time']['update_ticker_time'] = time.time() * 1000 # 使用time.time()获取当前时间的时间戳
    
    # 遍历获取到的行情数据
    for ticpre in Info['trade_symbols']:
        
        curcontract = ticpre + '_' + QUOTO + '.swap'
        data = exchange.GetTicker(curcontract)
        
        if not data:
            Log("获取行情失败", GetLastError())
            return
        # 提取交易币种,永续合约格式如 'BTC_USDT.swap',这里取币种名 'BTC'
        symbol = data['Symbol'].split('_')[0]
        
        # 过滤掉不是基础货币(Info['base_coin'])的交易对或不是永续合约的交易对
        if not data['Symbol'].split('.')[0].endswith(Info['base_coin']) or symbol not in Info['trade_symbols'] or not data['Symbol'].endswith('swap'):
            continue
        
        # 更新行情的卖出价、买入价和最后成交价
        Info['ticker'][symbol]['ask'] = float(data['Sell'])  # 卖出价
        Info['ticker'][symbol]['bid'] = float(data['Buy'])   # 买入价
        Info['ticker'][symbol]['last'] = float(data['Last']) # 最后成交价
  1. Marktdaten abrufen

    • verwendenexchange.GetTickersErhalten Sie Marktinformationen in Echtzeit für alle Handelspaare.tickerDie Variable speichert alle Transaktionspaarinformationen.
  2. Fehlerbehandlung

    • Wenn die Marktdaten nicht erfolgreich abgerufen werden können, übergibt das ProgrammLogFunktionsprotokolle und -ausgabenGetLastErrorDie Fehlermeldung wurde zurückgegeben.
  3. Aktualisierungszeit

    • verwendentime.timeZum Aufzeichnen des Zeitstempels der aktuellen Zeit, der zum Markieren des Zeitpunkts der Marktaktualisierung verwendet wird.
  4. Datenfilterung

    • Extrahieren Sie den Namen der Handelswährung aus den Marktdaten.
    • Filtern Sie Handelspaare heraus, die die Anforderungen nicht erfüllen, z. B. Handelspaare, die nicht in der Basiswährung abgewickelt werden, oder Handelspaare, bei denen es sich nicht um unbefristete Verträge handelt.
  5. Marktdaten aktualisieren

    • Aktualisieren Sie für zulässige Handelswährungen deren Kaufpreis, Verkaufspreis und letzten Handelspreis.

Durch diese Funktion kann das System die neuesten Marktinformationen der Zielhandelswährung in Echtzeit abrufen und aktualisieren.

Erhalten Sie Informationen zur Kontoposition

Verwenden Sie die API, um Ihren Kontostand und Ihre aktuellen Bestände (Währung, Menge, Kosten usw.) abzurufen. Dieser Schritt ist entscheidend für die Bewertung der verfügbaren Mittel, die Berechnung des Risikos und die Verwaltung von Positionen. Beispielsweise bestimmen Ihre aktuellen Bestände, ob Sie Ihre Position erhöhen oder verringern.

Zweck:

  • Stellen Sie sicher, dass auf Ihrem Konto ausreichend Guthaben oder offene Positionen vorhanden sind, um die Transaktion auszuführen.
  • Bestimmen Sie die Größe und Richtung der Transaktion basierend auf der aktuellen Position und den Mitteln auf dem Konto.
# 更新账户信息
def UpdateAccount():
   
    # 如果上次更新时间距现在不到1分钟,直接返回
    if time.time() - Info['time']['update_account_time'] < 60:
        return
    
    # 记录账户信息更新时间
    Info['time']['update_account_time'] = time.time() * 1000
    
    # 获取账户信息
    account = exchange.GetAccount()
    
    # 如果账户信息获取失败,记录日志并返回
    if account is None:
        Log("更新账户失败")
        return
    
    # 计算账户信息
    Info['account']['margin_used'] = round(account['Equity'] - account['Balance'], 2)  # 使用的保证金
    Info['account']['margin_balance'] = round(account['Equity'], 2)  # 当前账户余额
    Info['account']['margin_free'] = round(account['Balance'], 2)  # 可用余额
    Info['account']['wallet_balance'] = round(account['Equity'] - account['UPnL'], 2)  # 钱包余额
    Info['account']['unrealised_profit'] = round(account['UPnL'], 2)  # 未实现盈亏

    # 初始化账户初始余额
    if not Info['account']['init_balance']:
        if _G("init_balance") and _G("init_balance") > 0:
            Info['account']['init_balance'] = round(_G("init_balance"), 2)
        else:
            Info['account']['init_balance'] = Info['account']['margin_balance']
            _G("init_balance", Info['account']['init_balance'])
    
    # 计算账户利润及利润率
    Info['account']['profit'] = round(Info['account']['margin_balance'] - Info['account']['init_balance'], 2)
    Info['account']['profit_rate'] = round((100 * Info['account']['profit']) / Info['account']['init_balance'], 2)

    # 计算仓位总价值和杠杆率
    Info['count']['total'] = round(Info['count']['long'] + Info['count']['short'], 2)
    Info['count']['leverage'] = round(Info['count']['total'] / Info['account']['margin_balance'], 2)


# 更新仓位信息
def UpdatePosition():
    
    # 获取永续合约的仓位信息
    pos = exchange.GetPositions(Info['base_coin'] + ".swap")
    
    # 记录仓位信息更新时间
    Info['time']['update_pos_time'] = time.time() * 1000

    # 初始化仓位信息
    position_info = {symbol: {'amount': 0, 'hold_price': 0, 'unrealised_profit': 0} for symbol in Info['trade_symbols']}

    # 遍历仓位信息,更新相应币种的仓位
    for data in pos:
        symbol = data['Symbol'].split("_")[0]
        
        # 过滤掉不符合条件的币种
        if not data['Symbol'].split(".")[0].endswith(Info['base_coin']) or symbol not in Info['trade_symbols']:
            continue
        
        # 如果仓位不为零,则需要单向持仓
        if position_info[symbol]['amount'] != 0:
            raise Exception("需要单向持仓")
        
        # 更新仓位信息
        position_info[symbol] = {
            'amount': data['Amount'] * Info['precision'][symbol]['ctVal'] if data['Type'] == 0 else -data['Amount'] * Info['precision'][symbol]['ctVal'],
            'hold_price': data['Price'],
            'unrealised_profit': data['Profit']
        }

    # 初始化仓位统计数据
    Info['count'] = {'long': 0, 'short': 0, 'total': 0, 'leverage': 0}

    # 遍历更新后的仓位信息
    for symbol, info in position_info.items():
        deal_volume = abs(info['amount'] - Info['position'][symbol]['amount'])
        direction = 1 if info['amount'] - Info['position'][symbol]['amount'] > 0 else -1
        
        # 如果仓位发生变化,记录成交信息
        if deal_volume:
            deal_price = Info['order'][symbol]['buy']['price'] if direction == 1 else Info['order'][symbol]['sell']['price']
            Log(
                symbol,
                "仓位更新:",
                round(Info['position'][symbol]['value'], 1),
                " -> ",
                round(info['amount'] * Info['ticker'][symbol]['last'], 1),
                ", 买" if direction == 1 else ", 卖",
                ", 成交价:",
                deal_price,
                ", 成本价:",
                round(Info['position'][symbol]['hold_price'], Info['precision'][symbol]['price_precision']),
            )

        # 更新仓位信息
        Info['position'][symbol]['amount'] = info['amount']
        Info['position'][symbol]['hold_price'] = info['hold_price']
        Info['position'][symbol]['value'] = round(Info['position'][symbol]['amount'] * Info['ticker'][symbol]['last'], 2)
        Info['position'][symbol]['unrealised_profit'] = info['unrealised_profit']

        # 统计多头和空头仓位价值
        if Info['position'][symbol]['amount'] > 0:
            Info['count']['long'] += abs(Info['position'][symbol]['value'])
        else:
            Info['count']['short'] += abs(Info['position'][symbol]['value'])
  1. UpdateAccountFunktion

    • Prüfintervall: Achten Sie bei jeder Aktualisierung Ihres Kontos darauf, dass die letzte Aktualisierung mehr als 1 Minute zurückliegt, um zu häufige Aktualisierungen zu vermeiden.
    • Kontoinformationen aktualisieren: Anrufexchange.GetAccountErhalten Sie Kontoinformationen und berechnen Sie verschiedene Kontoparameter, wie z. B.margin_usedwallet_balanceunrealised_profitWarten.
    • Guthaben initialisieren: Initialisieren Sie den Anfangssaldo des Kontos beim ersten Ausführen und speichern Sie ihn in der globalen VariableInfo['account']['init_balance']Mitte.
    • Gewinnberechnung: Berechnet Gewinn und Gewinnspanne basierend auf dem aktuellen und dem Anfangssaldo.
  2. UpdatePositionFunktion

    • Positionsinformationen abrufen: Anrufexchange.GetPositions()Holen Sie sich den aktuellen Positionsstatus.
    • Position aktualisieren:Aktualisieren Sie die Positionsinformationen der Zielwährung basierend auf den erfassten Positionsdaten (wie z. B.amounthold_priceunrealised_profitWarten).
    • Berechnung der HebelwirkungBerechnet die Gesamthebelquote basierend auf den aktuellen Long- und Short-Positionswerten und dem Margin-Saldo.

Durch diese beiden Funktionen kann die Strategie den Kontostatus und Positionsänderungen kontinuierlich überwachen und so Echtzeitdatenunterstützung für nachfolgende Handelsentscheidungen bereitstellen.

Handel

Führen Sie Kauf- oder Verkaufsaufträge basierend auf der Strategielogik aus. Dies können Marktaufträge, Limitaufträge oder andere Auftragsarten sein. Dieser Schritt beinhaltet die Interaktion mit der API der Börse, um Kauf- oder Verkaufsaufträge zu senden. Die erfolgreiche Auftragsausführung wirkt sich auf den Kontostand und das offene Interesse aus.

Zweck:

  • Geben Sie Handelsanweisungen über die API aus, um Kauf- und Verkaufsvorgänge abzuschließen.
  • Stellen Sie sicher, dass Auftragsart und -menge den Strategieanforderungen und Börsenvorschriften entsprechen.
# 订单函数
def Order(symbol, direction, price, amount, msg):
    pair = f"{symbol}_{Info['base_coin']}.swap"  # 构造交易对名称
    ret = exchange.CreateOrder(pair, direction, price, amount, msg)  # 执行下单操作
    
    # 判断是否下单成功
    if ret:
        Info['order'][symbol][direction]['id'] = ret  # 记录订单ID
        Info['order'][symbol][direction]['price'] = price  # 记录下单价格
    else:
        Log(f"{symbol} {direction} {price} {amount} 下单异常")  # 输出异常信息

# 交易函数
def Trade(symbol, direction, price, amount, msg):
    
    # 根据最小价格变动调整价格
    price = round(price - (price % Info['precision'][symbol]['tick_size']), Info['precision'][symbol]['price_precision'])
    
    # 计算调整后的交易数量
    amount = amount / Info['precision'][symbol]['ctVal']  # 计算真实合约数量
    amount = round(amount - (amount % Info['precision'][symbol]['amount_size']), Info['precision'][symbol]['amount_precision'])

    # 限制最大交易数量
    if Info['precision'][symbol]['max_qty'] > 0:
        amount = min(amount, Info['precision'][symbol]['max_qty'])
    
    new_order = False
    
    # 如果新价格与之前的订单价格差异大于0.0001,则重新下单

    if Info['order'][symbol][direction]['price'] > 0 and abs(price - Info['order'][symbol][direction]['price']) / price > 0.0001:
        Log('已持订单,订单价格发生变化')
        new_order = True
    
    # 如果交易数量为0或者当前订单ID为0,则撤单
    if amount <= 0 or Info['order'][symbol][direction]['id'] == 0:
        Log('新订单产生')
        new_order = True
    
    # 如果需要新订单
    if new_order:
        # 如果有原有订单,撤销它
        if Info['order'][symbol][direction]['id'] != 0:
            exchange.CancelOrder(Info['order'][symbol][direction]['id'])
            Info['order'][symbol][direction]['id'] = 0
            Info['order'][symbol][direction]['price'] = 0
            Log('撤单成功:', symbol)
        
        
        # 如果更新仓位或ticker的延迟太高,则不下单
        if (time.time() * 1000 - Info['time']['update_pos_time'] > 2 * Info['interval'] * 1000 or 
            time.time() * 1000 - Info['time']['update_ticker_time'] > 2 * Info['interval'] * 1000):
            Log(time.time() * 1000, Info['time']['update_pos_time'], time.time() * 1000 - Info['time']['update_pos_time'])
            Log(time.time() * 1000, Info['time']['update_ticker_time'], time.time() * 1000 - Info['time']['update_ticker_time'])
            Log('延迟过高')
            return
        
        # 如果订单金额或数量过低,不执行下单操作
        if price * amount <= Info['precision'][symbol]['min_notional'] or amount < Info['precision'][symbol]['min_qty']:
            Log(f"{symbol} 下单量太低", price * amount)
            return
        
        # 执行下单操作
        Log('order下单:', symbol)
        Order(symbol, direction, price, amount, msg)
  1. OrderFunktion

    • Verantwortlich für die Erstellung einer Bestellung. Bei Erfolg werden die Bestellnummer und der Preis aufgezeichnet. Bei einem Fehler wird eine Fehlermeldung ausgegeben.
  2. TradeFunktion

    • Passen Sie dies anhand des Marktpreises und der Menge an, um zu bestimmen, ob die Bestellung storniert und eine neue aufgegeben werden soll, um Fehler bei der Auftragsausführung oder wiederholte Vorgänge zu vermeiden.
  3. CancelOrderFunktion

    • Es handelt sich um eine benutzerdefinierte Auftragsstornierungsoperation, die für die Stornierung des aktuellen ausstehenden Auftrags verantwortlich ist.

Statusanzeige

Der Betriebsstatus der Strategie wird in Echtzeit angezeigt, einschließlich Kontostand, aktuellen Positionen, Handelsausführungsstatus, aktuellem Marktpreis usw. Dieser Schritt dient nicht nur der Überwachung des Betriebs der Strategie, sondern auch dem schnellen Verständnis der Leistung der Strategie während der Strategieoptimierung und des Debuggens.

Zweck:

  • Zeigen Sie wichtige Informationen zum Strategiebetrieb rechtzeitig an, um die Benutzerüberwachung zu erleichtern.
  • Bietet einen Feedback-Mechanismus, der anzeigt, ob die Transaktion erfolgreich ausgeführt wurde oder ob Fehler aufgetreten sind.
# 更新状态函数
def UpdateStatus():
    
    # 如果距离上次更新的时间小于4秒,则直接返回
    if time.time() * 1000 - Info['time']['update_status_time'] < 4000:
        return
    
    # 更新状态时间
    Info['time']['update_status_time'] = time.time() * 1000

    # 账户信息表格
    table1 = {
        "type": "table",
        "title": "账户信息",
        "cols": [
            "初始余额", "钱包余额", "保证金余额", "已用保证金", "可用保证金",
            "总收益", "收益率", "未实现收益", "总持仓", "已用杠杆", "循环延时"
        ],
        "rows": [
            [
                Info['account']['init_balance'],  # 初始余额
                Info['account']['wallet_balance'],  # 钱包余额
                Info['account']['margin_balance'],  # 保证金余额
                Info['account']['margin_used'],  # 已用保证金
                Info['account']['margin_free'],  # 可用保证金
                Info['account']['profit'],  # 总收益
                str(Info['account']['profit_rate']) + "%",  # 收益率
                round(Info['account']['unrealised_profit'], 2),  # 未实现收益
                round(Info['count']['total'], 2),  # 总持仓
                Info['count']['leverage'],  # 已用杠杆
                str(Info['time']['loop_delay']) + "ms",  # 循环延时
            ],
        ],
    }
    
    # 交易对信息表格
    table2 = {
        "type": "table",
        "title": "交易对信息",
        "cols": [
            "币种", "方向", "数量", "持仓价格", "持仓价值", 
            "现价", "挂单买价", "挂单卖价", "未实现盈亏"
        ],
        "rows": [],
    }

    # 遍历每个交易对,填充交易对信息
    for symbol in Info['trade_symbols']:
        table2['rows'].append([
            symbol,  # 币种
            "LONG" if Info['position'][symbol]['amount'] > 0 else "SHORT",  # 方向
            round(Info['position'][symbol]['amount'], Info['precision'][symbol]['amount_precision'] + 2),  # 数量
            round(Info['position'][symbol]['hold_price'], Info['precision'][symbol]['price_precision']),  # 持仓价格
            round(Info['position'][symbol]['value'], 2),  # 持仓价值
            round(Info['ticker'][symbol]['last'], Info['precision'][symbol]['price_precision']),  # 现价
            Info['order'][symbol]['buy']['price'],  # 挂单买价
            Info['order'][symbol]['sell']['price'],  # 挂单卖价
            round(Info['position'][symbol]['unrealised_profit'], 2),  # 未实现盈亏
        ])

    # 输出状态日志
    LogStatus(
        f"初始化时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(Info['time']['start_time']))}\n",
        f"`{json.dumps(table1)}`\n" + f"`{json.dumps(table2)}`\n",
        f"最后执行时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}\n"
    )

    # 每10秒钟更新一次账户信息
    if time.time() * 1000 - Info['time']['update_profit_time'] > 10 * 1000:
        UpdateAccount()  # 更新账户信息
        LogProfit(round(Info['account']['profit'], 3), '&')  # 输出收益日志
        Info['time']['update_profit_time'] = time.time() * 1000  # 更新收益时间

Transaktionslogik

Der zentrale Entscheidungsprozess im Handel. Basierend auf Marktdaten, Kontoinformationen und Positionen, kombiniert mit technischen Indikatoren oder quantitativen Modellen, werden Entscheidungen darüber getroffen, ob Positionen gekauft, verkauft, erhöht oder reduziert werden. Die Handelslogik variiert je nach Strategie, z. B. Trendfolge-, Mean-Reversion- oder Breakout-Strategien.

Zweck:

  • Treffen Sie intelligente Handelsentscheidungen basierend auf Marktdaten und Kontostatus.
  • Bewältigen Sie verschiedene Marktsituationen und stellen Sie sicher, dass Strategien in unterschiedlichen Marktumgebungen sinnvoll funktionieren.

Um die Anwendbarkeit des Frameworks zu demonstrieren, verwendet die Handelsstrategie in diesem Artikel eine einfache Logik. Jede Order ist auf 50 USDT festgelegt, und bei Handelsausführung wird die entsprechende Kauf- oder Verkaufsmenge basierend auf den aktuellen Marktangebots- und -angebotskursen berechnet. Die Ausführungsregeln dieser Strategie sind sehr einfach gehalten und sollen die Anwendung des Frameworks für den Handel mit Multi-Currency-Futures in einer Live-Handelsumgebung demonstrieren. Um Einfachheit und Bedienbarkeit zu gewährleisten, wird eine Stoppbedingung festgelegt: Sobald der Gesamtwert der offenen Positionen eines Handelspaares 2.000 USDT erreicht, werden keine weiteren Orders mehr angenommen. Dies ermöglicht uns, die Grundstruktur der Strategie und die Interaktion des Frameworks mit Marktdaten von Börsen bequem zu demonstrieren.

def MakeOrder():
    
    # 遍历所有交易对
    for symbol in Info['trade_symbols']:
        
        # 获取买价(挂单买价)
        buy_price = Info['ticker'][symbol]['bid']
        
        # 计算买入数量,根据买入金额除以买价
        buy_amount = 50 / buy_price

        # 获取卖价(挂单卖价)
        sell_price = Info['ticker'][symbol]['ask']
        
        # 计算买入数量,根据买入金额除以买价
        sell_amount = 50 / sell_price

        
        # 如果当前持仓的总价值小于2000,则进行买入操作
        if Info['position'][symbol]['value'] < 2000:
            Log('进入交易')
            Log('设定价格:', Info['ticker'][symbol]['bid'])
            Trade(symbol, "buy", buy_price, buy_amount, symbol)  # 执行买入操作
        
        #if Info['position'][symbol]['value'] < 3000:
        #    Trade(symbol, "sell", sell_price, sell_amount, symbol)  # 执行买入操作

Hauptschleife

Die Hauptschleife ist der Kern des Strategierahmens und sorgt für die konsistente und stabile Performance der Strategie am Markt. Sie führt regelmäßig in festgelegten Intervallen verschiedene Operationen durch, wie z. B. das Abrufen aktueller Marktdaten, die Aktualisierung von Positionsinformationen und die Ausführung von Handelsentscheidungen. Durch die Hauptschleife kann die Strategie in Echtzeit auf Marktveränderungen reagieren und sicherstellen, dass jede Ausführung auf den neuesten Marktdaten basiert. Typischerweise wird die Hauptschleife einmal pro neuem Zeitraum ausgelöst (z. B. jede Minute, jede Stunde oder wenn eine neue Kerze generiert wird).

Zweck:

  • Stellen Sie den kontinuierlichen und stabilen Betrieb der Strategie sicher, erhalten Sie Marktdaten in Echtzeit und treffen Sie Handelsentscheidungen.
  • Jeder Zyklus gewährleistet die Echtzeit und Genauigkeit der Strategieausführung.
def OnTick():
    try:
        # 更新市场行情信息
        UpdateTicker()
        # 更新持仓信息
        UpdatePosition()
        # 执行下单操作
        MakeOrder()
        # 更新状态信息
        UpdateStatus()
    except Exception as error:
        # 记录循环中发生的错误
        Log("循环出错: " + str(error))

def main():
    LogReset(0)  
    apiBase = "https://testnet.binancefuture.com"  # 币安期货仿真交易所        
    exchange.SetBase(apiBase)  # 设置仿真交易所基站
    # 初始化信息
    exchange.IO('dual', False)  # 单向持仓
    InitInfo()
    GetPrecision()
    
    while True:  # 无限循环
        loop_start_time = time.time() * 1000  # 获取当前时间(毫秒)
        
        # 检查上次循环时间与设定的间隔时间是否已过
        if time.time() * 1000 - Info['time']['last_loop_time'] > Info['interval'] * 1000:
            OnTick()  # 调用 OnTick 函数
            
            # 更新最后一次循环时间
            Info['time']['last_loop_time'] = time.time() * 1000
            # 计算当前循环的延迟时间
            Info['time']['loop_delay'] = time.time() * 1000 - loop_start_time
        
        # 暂停5毫秒,避免过度消耗CPU资源
        Sleep(5000)

Code-Erklärung:

  1. OnTickFunktionDiese Funktion ist die Kernaufgabe, die jedes Mal innerhalb der Hauptschleife ausgeführt wird. Sie ist verantwortlich für die Aktualisierung von Marktinformationen, Positionsinformationen, die Ausführung von Trades und die Aktualisierung des Strategiestatus. Alle Handels- und Informationsaktualisierungen werden innerhalb dieser Funktion durchgeführt. Alle Fehler während der Ausführung werden erfasst und protokolliert.

  2. mainFunktion:Die Hauptfunktion initialisiert die relevanten Informationen, stellt die Austauschbasisstation ein und startet eine Endlosschleife. In jeder Schleife prüft das Programm, ob das eingestellte Zeitintervall abgelaufen ist. Wenn ja,OnTickDie Funktion wird aufgerufen, um die Strategie auszuführen. Wenn das Zeitintervall noch nicht erreicht ist, wartet das Programm und setzt die Schleife fort, um sicherzustellen, dass die Strategie gemäß dem vorgegebenen Zeitintervall ausgeführt wird.

  3. Verzögerungssteuerung: Nach jeder Schleife pausiert das Programm für 5 Millisekunden, um die CPU-Last zu reduzieren. Dies soll einen übermäßigen Verbrauch von Rechenressourcen durch hochfrequente Schleifen vermeiden.

Betriebslogik

  • Initialisierungsphase: Legen Sie zuerst die API und andere erforderliche Parameter fest, initialisieren Sie dann die Informationen und ermitteln Sie die Währungsgenauigkeit.
  • Hauptschleifenphase:Geben Sie eine Endlosschleife ein. Jede Schleife überprüft das Zeitintervall, um sicherzustellen, dass das Zeitintervall für die Richtlinienausführung den voreingestellten Einstellungen entspricht.
  • Ausführungsphase:Nachdem die Zeitintervallbedingung erfüllt ist,OnTickDie Funktion wird aufgerufen, um alle Strategieoperationen durchzuführen, einschließlich Aktualisierungen der Marktinformationen, Handelsausführung usw.

Dieses Hauptschleifendesign stellt sicher, dass die Strategie unter Echtzeit-Marktbedingungen weiterläuft und zeitnahe Handelsentscheidungen trifft, wodurch die Stabilität und Genauigkeit der Strategie verbessert wird.

Zusammenfassen

Dieses Strategie-Framework ist modular und skalierbar konzipiert. Jeder Schritt hat klare Verantwortlichkeiten, die Robustheit gewährleisten und gleichzeitig zukünftige Erweiterungen und Optimierungen ermöglichen. Durch die Nutzung von Börsen-APIs können Strategien optimiert und durch Backtesting und Echtzeithandel konsistenter gestaltet werden.

brauchenBeachtenBeachten Sie, dass dieses Demonstrationsframework die simulierte Börse Binance als Beispiel verwendet und einen grundlegenden Rahmen für die Strategieentwicklung und -anwendung bietet. In der Praxis ist eine Optimierung basierend auf der tatsächlichen Strategielogik erforderlich, z. B. die dynamische Anpassung von Parametern an die Marktbedingungen, die Optimierung von Risikokontrollmechanismen und die Implementierung von Ausnahmebehandlungen. Aufgrund unterschiedlicher API-Schnittstellen, Handelsregeln, Präzisionseinstellungen und Gebührenstrukturen zwischen den Börsen ist in der tatsächlichen Implementierung eine detaillierte Optimierung und Anpassung basierend auf den spezifischen Anforderungen der Zielbörse erforderlich, um die Stabilität und Kompatibilität der Strategie zu gewährleisten. Es wird empfohlen, die Zuverlässigkeit und Leistung Ihrer Strategie vor dem Einsatz im realen Handel umfassend zu testen und zu überprüfen.

AnhangAdresse des Python-Frameworks für mehrere Währungen