В процессе загрузки ресурсов... загрузка...

Подробная информация о стратегии торговли цифровыми валютами

Автор:Трава, Создано: 2024-07-05 16:23:42, Обновлено: 2024-07-12 09:19:11

img

Подробная информация о стратегии торговли цифровыми валютами

Преамбула

В последнее время в количественных журналах Буо упоминается, что можно использовать отрицательные котировки, чтобы получить прибыль в зависимости от прорыва цены. Цифровые валюты в основном являются положительными, а отрицательными являются несколько валют, которые часто имеют особые рынки, такие как независимые рынки MEME, которые не следуют за большим диапазоном, отбирают эти валюты, и после прорыва делают больше, чтобы получить прибыль в определенных условиях.

Курсовая торговля - это стратегия торговли, основанная на статистическом сборе, которая используется для получения прибыли от отклонения цены путем одновременного покупки и продажи двух сильно связанных цифровых валютных длительных контрактов. В этой статье подробно описываются принципы этой стратегии, механизмы получения прибыли, методы отбора монет, потенциальные риски и способы их улучшения, а также приведены некоторые практические примеры кода Python.

Принципы стратегии

Стратегия парирования зависит от исторической взаимосвязи между ценами двух цифровых валют. Когда цены двух валют проявляют сильную взаимосвязь, их движение в целом синхронизируется. Если в какой-то момент наблюдается значительное отклонение в соотношении цен, это может считаться временным аномалием, когда цены стремятся вернуться к нормальному уровню.

Предположим, что A и B имеют более высокую ценовую корреляцию. В какой-то момент среднее значение соотношения A/B составляет 1. Если в какой-то момент соотношение A/B увеличилось более чем на 0.001, то есть больше чем на 1.001, то можно торговать следующим образом: открыть позицию больше, чем B, открыть позицию больше, чем A. В противоположном случае, когда соотношение A/B ниже, чем 0.999: открыть позицию больше, чем A, открыть позицию больше, чем B.

Ключ к прибыли заключается в получении прибыли от разницы, когда цена отклоняется к нормальному. Поскольку отклонения от цены обычно бывают кратковременными, трейдеры могут выйти из нее и заработать на разнице, когда цена возвращается к среднему значению.

Подготовка данных

Введите соответствующую библиотеку

Эти коды можно использовать непосредственно, предпочтительно загрузив Anancoda и дешифруя их в jupyer notebook.

import requests
from datetime import date,datetime
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import requests, zipfile, io
%matplotlib inline

Получить все пары сделок, которые торгуются.

Info = requests.get('https://fapi.binance.com/fapi/v1/exchangeInfo')
b_symbols = [s['symbol'] for s in Info.json()['symbols'] if s['contractType'] == 'PERPETUAL' and s['status'] == 'TRADING' and s['quoteAsset'] == 'USDT']
b_symbols = list(filter(lambda x: x[-4:] == 'USDT', [s.split('_')[0] for s in b_symbols]))
b_symbols = [x[:-4] for x in b_symbols]
print(b_symbols) # 获取所有的正在交易的交易对

Функции для загрузки K-линий

Основная функция функции GetKlines заключается в получении исторических данных K-линий с определенной сделки на постоянные контракты на бирже Binance и хранении этих данных в Pandas DataFrame.

def GetKlines(symbol='BTCUSDT',start='2020-8-10',end='2024-7-01',period='1h',base='fapi',v = 'v1'):
    Klines = []
    start_time = int(time.mktime(datetime.strptime(start, "%Y-%m-%d").timetuple()))*1000 + 8*60*60*1000
    end_time =  min(int(time.mktime(datetime.strptime(end, "%Y-%m-%d").timetuple()))*1000 + 8*60*60*1000,time.time()*1000)
    intervel_map = {'m':60*1000,'h':60*60*1000,'d':24*60*60*1000}
    while start_time < end_time:
        time.sleep(0.3)
        mid_time = start_time+1000*int(period[:-1])*intervel_map[period[-1]]
        url = 'https://'+base+'.binance.com/'+base+'/'+v+'/klines?symbol=%s&interval=%s&startTime=%s&endTime=%s&limit=1000'%(symbol,period,start_time,mid_time)
        res = requests.get(url)
        res_list = res.json()
        if type(res_list) == list and len(res_list) > 0:
            start_time = res_list[-1][0]+int(period[:-1])*intervel_map[period[-1]]
            Klines += res_list
        if type(res_list) == list and len(res_list) == 0:
            start_time = start_time+1000*int(period[:-1])*intervel_map[period[-1]]
        if mid_time >= end_time:
            break
    df = pd.DataFrame(Klines,columns=['time','open','high','low','close','amount','end_time','volume','count','buy_amount','buy_volume','null']).astype('float')
    df.index = pd.to_datetime(df.time,unit='ms')
    return df

Загрузка данных

Данные относительно большие, для быстрой загрузки получены только данные за последние 3 месяца.

start_date = '2024-04-01'
end_date   = '2024-07-05'
period = '1h'
df_dict = {}

for symbol in b_symbols:   
    print(symbol)
    if symbol in df_dict.keys():
        continue
    df_s = GetKlines(symbol=symbol+'USDT',start=start_date,end=end_date,period=period)
    if not df_s.empty:
        df_dict[symbol] = df_s
df_close = pd.DataFrame(index=pd.date_range(start=start_date, end=end_date, freq=period),columns=df_dict.keys())
for symbol in symbols:
    df_close[symbol] = df_dict[symbol].close
df_close = df_close.dropna(how='all')

Рекомендационный двигатель

Определение объекта Exchange для последующих повторных измерений

class Exchange:
    def __init__(self, trade_symbols, fee=0.0002, initial_balance=10000):
        self.initial_balance = initial_balance #初始的资产
        self.fee = fee
        self.trade_symbols = trade_symbols
        self.account = {'USDT':{'realised_profit':0, 'unrealised_profit':0, 'total':initial_balance,
                                'fee':0, 'leverage':0, 'hold':0, 'long':0, 'short':0}}
        for symbol in trade_symbols:
            self.account[symbol] = {'amount':0, 'hold_price':0, 'value':0, 'price':0, 'realised_profit':0,'unrealised_profit':0,'fee':0}
            
    def Trade(self, symbol, direction, price, amount):
        cover_amount = 0 if direction*self.account[symbol]['amount'] >=0 else min(abs(self.account[symbol]['amount']), amount)
        open_amount = amount - cover_amount
        self.account['USDT']['realised_profit'] -= price*amount*self.fee #扣除手续费
        self.account['USDT']['fee'] += price*amount*self.fee
        self.account[symbol]['fee'] += price*amount*self.fee
        if cover_amount > 0: #先平仓
            self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount  #利润
            self.account[symbol]['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount
            self.account[symbol]['amount'] -= -direction*cover_amount
            self.account[symbol]['hold_price'] = 0 if self.account[symbol]['amount'] == 0 else self.account[symbol]['hold_price']
        if open_amount > 0:
            total_cost = self.account[symbol]['hold_price']*direction*self.account[symbol]['amount'] + price*open_amount
            total_amount = direction*self.account[symbol]['amount']+open_amount
            
            self.account[symbol]['hold_price'] = total_cost/total_amount
            self.account[symbol]['amount'] += direction*open_amount      
    
    def Buy(self, symbol, price, amount):
        self.Trade(symbol, 1, price, amount)
        
    def Sell(self, symbol, price, amount):
        self.Trade(symbol, -1, price, amount)
        
    def Update(self, close_price): #对资产进行更新
        self.account['USDT']['unrealised_profit'] = 0
        self.account['USDT']['hold'] = 0
        self.account['USDT']['long'] = 0
        self.account['USDT']['short'] = 0
        for symbol in self.trade_symbols:
            if not np.isnan(close_price[symbol]):
                self.account[symbol]['unrealised_profit'] = (close_price[symbol] - self.account[symbol]['hold_price'])*self.account[symbol]['amount']
                self.account[symbol]['price'] = close_price[symbol]
                self.account[symbol]['value'] = self.account[symbol]['amount']*close_price[symbol]
                if self.account[symbol]['amount'] > 0:
                    self.account['USDT']['long'] += self.account[symbol]['value']
                if self.account[symbol]['amount'] < 0:
                    self.account['USDT']['short'] += self.account[symbol]['value']
                self.account['USDT']['hold'] += abs(self.account[symbol]['value'])
                self.account['USDT']['unrealised_profit'] += self.account[symbol]['unrealised_profit']
        self.account['USDT']['total'] = round(self.account['USDT']['realised_profit'] + self.initial_balance + self.account['USDT']['unrealised_profit'],6)
        self.account['USDT']['leverage'] = round(self.account['USDT']['hold']/self.account['USDT']['total'],3)

Анализ корреляции

Коррелятивный расчет - это метод в статистике, используемый для измерения линейных отношений между двумя переменными. Наиболее часто используемый метод расчета коррелятивных отношений - пирсонский коррелятивный расчет. Ниже приведены принципы, формулы и методы реализации расчета коррелятивных отношений.

  • 1Означает, что две переменные всегда изменяются одновременно. Когда одна из переменных увеличивается, другая увеличивается пропорционально. Чем ближе к 1, тем сильнее зависимость.
  • -1обозначает полную отрицательную корреляцию, когда две переменные всегда изменяются в обратном направлении. Чем ближе к -1, тем сильнее отрицательная корреляция.
  • 0Это означает, что между двумя переменными нет прямолинейной связи.

Пирсонская корреляция определяется путем вычисления сопоставимого и стандартного расстояния двух переменных. Формула выглядит следующим образом:

{ \ rho_{X,Y} = \ frac{\ text{cov}(X,Y) }{ \ sigma_X \ sigma_Y}

Среди них:

  • ( \rho_{X,Y}) - пирсонский коэффициент переменных (X) и (Y).
  • (\text{cov}(X,Y)) - это расхождение коэффициентов между X и Y.
  • ( \sigma_X) и ( \sigma_Y) являются стандартными отклонениями (X) и (Y) соответственно.

Конечно, без особого внимания к тому, как вычисляется, можно вычислить взаимосвязь всех монет с помощью 1-го строка кода Python. На рисунке показана тепловая диаграмма взаимосвязи, красный представляет положительную взаимосвязь, синий представляет отрицательную взаимосвязь, чем глубже цвет, тем сильнее взаимосвязь.

img

import seaborn as sns
corr = df_close.corr()
plt.figure(figsize=(20, 20))
sns.heatmap(corr, annot=False, cmap='coolwarm', vmin=-1, vmax=1)
plt.title('Correlation Heatmap of Cryptocurrency Closing Prices', fontsize=20);

По релевантности были отобраны 20 наиболее релевантных валютных пар. Результаты были следующими. Все они имеют очень сильную релевантность, все выше 0,99.

MANA     SAND     0.996562
ICX      ZIL      0.996000
STORJ    FLOW     0.994193
FLOW     SXP      0.993861
STORJ    SXP      0.993822
IOTA     ZIL      0.993204
         SAND     0.993095
KAVA     SAND     0.992303
ZIL      SXP      0.992285
         SAND     0.992103
DYDX     ZIL      0.992053
DENT     REEF     0.991789
RDNT     MANTA    0.991690
STMX     STORJ    0.991222
BIGTIME  ACE      0.990987
RDNT     HOOK     0.990718
IOST     GAS      0.990643
ZIL      HOOK     0.990576
MATIC    FLOW     0.990564
MANTA    HOOK     0.990563

Код для этого:

corr_pairs = corr.unstack()

# 移除自身相关性(即对角线上的值)
corr_pairs = corr_pairs[corr_pairs != 1]

sorted_corr_pairs = corr_pairs.sort_values(kind="quicksort")

# 提取最相关和最不相关的前20个币种对
most_correlated = sorted_corr_pairs.tail(40)[::-2]

print("最相关的前20个币种对:")
print(most_correlated)

Повторное проверение

Конкретные коды обратной связи приведены ниже. Основные шаги демонстрационной стратегии - наблюдать за ценовым соотношением двух криптовалют (IOTA и ZIL) и осуществлять сделки в соответствии с изменениями этого соотношения. Конкретные шаги:

  1. Инициализация

    • Определение транзакционной пары ((pair_a = IOTA, pair_b = ZIL) ).
    • Создание объекта биржиeНачальный баланс составляет 10000 долларов США, а комиссионные на транзакцию составляют 0,02%;
    • Расчет первоначального соотношения средних ценavg
    • Установка первоначальной стоимости сделкиvalue = 1000
  2. Индерическая обработка данных о ценах

    • Ценовые данные в любой точке времениdf_close
    • Расчет отклонения текущего соотношения цен от среднегоdiff
    • Целевая стоимость сделок, рассчитанная на основе отклоненияaim_valueЗа каждое отклонение 0.01 торгуется одно значение. На основе текущего состояния аккаунта и цены принимается решение о покупке и продаже.
    • Если отклонение слишком большое, продавайте.pair_aи покупатьpair_bОперация.
    • Если отклонения слишком малы, выполните покупку.pair_aи продатьpair_bОперация.
  3. Корректировка среднего

    • Обновление соотношения средних ценavgНапример, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае и в Китае.
  4. Обновление учетных записей и записей

    • Обновление информации о состоянии и балансе счетов на биржах.
    • Записывает состояние счета на каждом этапе (общие активы, удерживаемые активы, расходы на сделки, многоличные и пустые позиции) доres_list
  5. Результаты

    • Это будетres_listПреобразование в фреймresВ частности, в частности, по поводу того, что мы не знаем, что происходит с этими людьми.
pair_a = 'IOTA'
pair_b = "ZIL"
e = Exchange([pair_a,pair_b], fee=0.0002, initial_balance=10000) #Exchange定义放在评论区
res_list = []
index_list = []
avg = df_close[pair_a][0] / df_close[pair_b][0]
value = 1000
for idx, row in df_close.iterrows():
    diff = (row[pair_a] / row[pair_b] - avg)/avg
    aim_value = -value * diff / 0.01
    if -aim_value + e.account[pair_a]['amount']*row[pair_a] > 0.5*value:
        e.Sell(pair_a,row[pair_a],(-aim_value + e.account[pair_a]['amount']*row[pair_a])/row[pair_a])
        e.Buy(pair_b,row[pair_b],(-aim_value - e.account[pair_b]['amount']*row[pair_b])/row[pair_b])
    if -aim_value + e.account[pair_a]['amount']*row[pair_a]  < -0.5*value:
        e.Buy(pair_a, row[pair_a],(aim_value - e.account[pair_a]['amount']*row[pair_a])/row[pair_a])
        e.Sell(pair_b, row[pair_b],(aim_value + e.account[pair_b]['amount']*row[pair_b])/row[pair_b])
    avg = 0.99*avg + 0.01*row[pair_a] / row[pair_b]
    index_list.append(idx)
    e.Update(row)
    res_list.append([e.account['USDT']['total'],e.account['USDT']['hold'],
                         e.account['USDT']['fee'],e.account['USDT']['long'],e.account['USDT']['short']])
res = pd.DataFrame(data=res_list, columns=['total','hold', 'fee', 'long', 'short'],index = index_list)
res['total'].plot(grid=True);

Всего было проведено повторное тестирование 4 групп валют, и результаты были идеальными. Расчет текущей корреляции использовался с использованием будущих данных, поэтому не был очень точным. В статье также разделены данные на две части, в соответствии с первым расчетом корреляции, последующим повторным тестированием.

img

Потенциальные риски и пути улучшения

Несмотря на то, что параллельные торговые стратегии теоретически приносят прибыль, в практической эксплуатации существуют некоторые риски: взаимосвязь между валютами может меняться с течением времени, что может привести к неэффективности стратегии; в экстремальных рыночных условиях ценовые отклонения могут усилиться и привести к большим потерям; низкая ликвидность некоторых валют может привести к затруднению или увеличению затрат на выполнение сделок; процедурные сборы, возникающие из-за частых сделок, могут разрушить прибыль.

Для снижения риска и повышения стабильности стратегии можно рассмотреть следующие улучшения: регулярно пересчитывать взаимосвязь между валютами, своевременно корректировать торговые пары; устанавливать стоп-лосс и стоп-фокусы, контролирующие максимальные потери на одной сделке; одновременно торговать несколькими валютными парами, распределяя риск.

Выводы

Стратегия торговли криптовалютной парой, которая использует взаимосвязь между ценами валют, чтобы получить прибыль, используя прибыльные операции при отклонении цены. Эта стратегия имеет высокую теоретическую целесообразность. Затем будет выпущен простой реальный код стратегии, основанный на этой стратегии.


Больше

77924998Это заслуживает изучения.

Бобы 888Чан Чжун работает сверхурочно - ха-ха!