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

Исследования фьючерсной стратегии хеджирования в нескольких валютах Binance Часть 1

Автор:Доброта, Создано: 2020-05-09 11:14:50, Обновлено: 2023-11-04 19:49:01

img

Исследования фьючерсной стратегии хеджирования в нескольких валютах Binance Часть 1

Нажмите на кнопку поиска на странице панели управления, а затем нажмите на стрелку для ввода. Откройте загруженный файл суффикса.pynb и нажмите Shift + Enter, чтобы запустить строку за строкой. В руководстве по использованию исследовательской среды есть основные руководства.

img

Причины стратегии

Binance зарегистрировала множество альткоинов на месте. Хотя краткосрочные колебания неопределенны, если вы посмотрите на ежедневную линию в течение длительного времени, вы обнаружите, что они в основном упали более чем на 90%, а некоторые даже имеют только доли наивысшей части цены. Однако для спота не существует универсального метода короткой продажи, и нет специальной рекомендации, кроме того, чтобы не прикасаться к альткоину. За последние два месяца Binance Futures запустила более 20 вечных контрактов, большинство из которых являются основными валютами, а некоторые неизвестны. Это дает нам средства для короткого использования этих комбинаций альткоинов. Использование коэффициента корреляции между альткоинами и BTC будет эффективным методом анализа, можно разработать две стратегии.

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

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

Вторая стратегия: шортинг валют с ценой выше индекса цен альткоина-биткоина, и лонггинг с валютами ниже индекса, чем больше отклонение, тем больше позиция. В то же время хеджирование необеспеченных позиций с BTC (или нет).

# Libraries to import
import pandas as pd
import requests
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
%matplotlib inline

Просмотр требуемой валюты

В настоящее время в вечном контракте Binance перечислены валюты, которые можно получить с помощью интерфейса API, в общей сложности 23 (без учета BTC).

#Info = requests.get('https://fapi.binance.com/fapi/v1/exchangeInfo')
#symbols = [symbol_info['baseAsset'] for symbol_info in Info.json()['symbols']]
symbols = ['ETH', 'BCH', 'XRP', 'EOS', 'LTC', 'TRX', 'ETC', 'LINK', 'XLM', 'ADA', 'XMR', 'DASH', 'ZEC', 'XTZ', 'BNB', 'ATOM', 'ONT', 'IOTA', 'BAT', 'VET', 'NEO', 'QTUM', 'IOST']

Я загрузил данные заранее и разместил их на форуме, который может быть прямо цитирован в исследовательской среде.

price_btc = pd.read_csv('https://www.fmz.com/upload/asset/1ef1af8ec28a75a2dcb.csv', index_col = 0)
price_btc.index = pd.to_datetime(price_btc.index,unit='ms') #Index date
price_btc.tail()

Результаты:

img img

5 строк × 23 столбца

Сначала нарисуйте цены этих валют, чтобы увидеть тенденцию, данные должны быть нормализованы.

price_btc_norm = price_btc/price_btc.fillna(method='bfill').iloc[0,]
price_btc_norm.plot(figsize=(16,6),grid = True,legend=False);

img

Сортируя последние изменения цены, вы можете найти несколько монет, которые явно отличаются, а именно LINK, XTZ, BCH, ETH. Объясните, что они часто могут иметь свой собственный тренд, и их короткое продажа имеет более высокий риск и должна быть исключена из стратегии.

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

price_btc_norm.iloc[-1,].sort_values()[-5:]

Результаты:

ETH     0.600417
ETC     0.661616
BCH     1.141961
XTZ     2.512195
LINK    2.764495
Name: 2020-03-25 00:00:00, dtype: float64
trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH'])) # Remaining currencies
plt.subplots(figsize=(12, 12)) # Set the screen size
sns.heatmap(price_btc[trade_symbols].corr(), annot=True, vmax=1, square=True, cmap="Blues");

img

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

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

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH', 'ETC','ATOM','BNB','EOS','LTC'])) # You can set the remaining currencies, which you want to subtract.
1-price_btc_norm[trade_symbols].iloc[-1,].mean()

Результаты:

0.6714306758250285
price_btc_norm[trade_symbols].mean(axis=1).plot(figsize=(16,6),grid = True,legend=False);

img

Данные по устойчивости Binance

Аналогичным образом, данные по устойчивости Binance были собраны, вы также можете прямо цитировать их в своей тетради, данные - это 1h рынок K-линия с 28 января по 31 марта 2020 года, потому что большинство вечных контрактов Binance были обедены всего два месяца, поэтому данных достаточно для бэкстеста.

price_usdt = pd.read_csv('https://www.fmz.com/upload/asset/20227de6c1d10cb9dd1.csv ', index_col = 0)
price_usdt.index = pd.to_datetime(price_usdt.index)
price_usdt.tail()

Результаты:

img img

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

price_usdt_norm = price_usdt/price_usdt.fillna(method='bfill').iloc[0,]
price_usdt_norm.plot(figsize=(16,6),grid = True,legend=False);

img

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

price_usdt_btc = price_usdt.divide(price_usdt['BTC'],axis=0)
price_usdt_btc_norm = price_usdt_btc/price_usdt_btc.fillna(method='bfill').iloc[0,]
price_usdt_btc_norm[trade_symbols].mean(axis=1).plot(figsize=(16,6),grid = True);
#price_usdt_btc_norm.mean(axis=1).plot(figsize=(16,6),grid = True,legend=False);

img

Задним испытанием двигателя

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

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

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

  • trade_symbols: список валют, с которыми следует торговать
  • рычаг кредитования: рычаг кредитования, эффектная маржа,
  • комиссионная: комиссионная за транзакцию, по умолчанию 0,00005
  • initial_balance: первоначальный актив, оценка в USDT
  • log: необходимо ли печатать записи транзакций
class Exchange:
    
    def __init__(self, trade_symbols, leverage=20, commission=0.00005,  initial_balance=10000, log=False):
        self.initial_balance = initial_balance # Initial asset
        self.commission = commission
        self.leverage = leverage
        self.trade_symbols = trade_symbols
        self.date = ''
        self.log = log
        self.df = pd.DataFrame(columns=['margin','total','leverage','realised_profit','unrealised_profit'])
        self.account = {'USDT':{'realised_profit':0, 'margin':0, 'unrealised_profit':0, 'total':initial_balance, 'leverage':0}}
        for symbol in trade_symbols:
            self.account[symbol] = {'amount':0, 'hold_price':0, 'value':0, 'price':0, 'realised_profit':0, 'margin':0, 'unrealised_profit':0}
            
    def Trade(self, symbol, direction, price, amount, msg=''):
        if self.date and self.log:
            print('%-20s%-5s%-5s%-10.8s%-8.6s %s'%(str(self.date), symbol, 'buy' if direction == 1 else 'sell', price, amount, msg))
            
        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.commission # Minus transaction fee
        
        if cover_amount > 0: # close position first
            self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount  # profit
            self.account['USDT']['margin'] -= cover_amount*self.account[symbol]['hold_price']/self.leverage # Free the margin
            
            self.account[symbol]['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount
            self.account[symbol]['amount'] -= -direction*cover_amount
            self.account[symbol]['margin'] -=  cover_amount*self.account[symbol]['hold_price']/self.leverage
            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['USDT']['margin'] +=  open_amount*price/self.leverage            
            self.account[symbol]['hold_price'] = total_cost/total_amount
            self.account[symbol]['amount'] += direction*open_amount
            self.account[symbol]['margin'] +=  open_amount*price/self.leverage
            
        self.account[symbol]['unrealised_profit'] = (price - self.account[symbol]['hold_price'])*self.account[symbol]['amount']
        self.account[symbol]['price'] = price
        self.account[symbol]['value'] = abs(self.account[symbol]['amount'])*price
        
        return True
    
    def Buy(self, symbol, price, amount, msg=''):
        self.Trade(symbol, 1, price, amount, msg)
        
    def Sell(self, symbol, price, amount, msg=''):
        self.Trade(symbol, -1, price, amount, msg)
        
    def Update(self, date, close_price): # Update assets
        self.date = date
        self.close = close_price
        self.account['USDT']['unrealised_profit'] = 0
        for symbol in self.trade_symbols:
            if np.isnan(close_price[symbol]):
                continue
            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'] = abs(self.account[symbol]['amount'])*close_price[symbol]
            self.account['USDT']['unrealised_profit'] += self.account[symbol]['unrealised_profit']
            if self.date.hour in [0,8,16]:
                pass
                self.account['USDT']['realised_profit'] += -self.account[symbol]['amount']*close_price[symbol]*0.01/100
        
        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']['margin']/self.account['USDT']['total'],4)*self.leverage
        self.df.loc[self.date] = [self.account['USDT']['margin'],self.account['USDT']['total'],self.account['USDT']['leverage'],self.account['USDT']['realised_profit'],self.account['USDT']['unrealised_profit']]
# First test the backtest engine
e = Exchange(['BTC','XRP'],initial_balance=10000,commission=0,log=True)

e.Buy('BTC',100, 5)
e.Sell('XRP',10, 50)

e.Sell('BTC',105,e.account['BTC']['amount'])
e.Buy('XRP',9,-e.account['XRP']['amount'])

round(e.account['USDT']['realised_profit'],4)
75.0

Первый код стратегии

Логика стратегии:

  • Проверьте цену валюты, если не nan, вы можете торговать
  • Проверьте стоимость контракта альткоина. Если она меньше целевой стоимости trade_value, соответствующая разница будет продана в коротком объеме, а если она больше, соответствующая сумма будет куплена для закрытия позиции.
  • Добавьте короткую стоимость всех альткоинов и скорректируйте позицию BTC, чтобы защититься от нее.

Позиция short trade_value определяет размер позиции.

# Need to hedge with BTC
trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH', 'ETC','ATOM','BNB','EOS','LTC'])) # Remaining currencies
e = Exchange(trade_symbols+['BTC'],initial_balance=10000,commission=0.0005,log=False)
trade_value = 2000
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        if e.account[symbol]['value'] - trade_value  < -20 :
            e.Sell(symbol, price, round((trade_value-e.account[symbol]['value'])/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if e.account[symbol]['value'] - trade_value > 20 :
            e.Buy(symbol, price, round((e.account[symbol]['value']-trade_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        empty_value += e.account[symbol]['value']
    price = row[1]['BTC']
    if e.account['BTC']['value'] - empty_value < -20:
        e.Buy('BTC', price, round((empty_value-e.account['BTC']['value'])/price,6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
    if e.account['BTC']['value'] - empty_value > 20:
        e.Sell('BTC', price, round((e.account['BTC']['value']-empty_value)/price,6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
stragey_1 = e

Окончательная прибыль каждой валюты составляет следующее:

pd.DataFrame(stragey_1.account).T.apply(lambda x:round(x,3))

img

На двух графиках ниже показаны кривая чистого состояния и используемый кредитный рычаг.

Желтый цвет в кривой чистой стоимости - это эффект 1x рычага, уменьшающего индекс альткоина. Можно видеть, что стратегия в основном усиливает колебания индекса, что соответствует ожиданиям. Окончательная двухмесячная доходность составляет 60%, максимальный ретрекшен - 20%, а максимальный рычаг составляет около 8 раз. Большую часть времени он составляет менее 6 раз. Он все еще безопасен. Самое главное, полная хеджировка привела к тому, что стратегия потеряла мало в падении 12 марта.

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

Но риски также были упомянуты ранее, альткоины, скорее всего, будут иметь свой собственный тренд, и могут сильно расти с нижнего уровня. Это зависит от того, как вы его используете. Если вы оптимистичны по отношению к альткоину и думаете, что он достиг дна, вы можете работать в этом направлении и покупать длинный этот индекс. Или если вы оптимистичны по отношению к определенным валютам, вы можете хеджировать их.

(stragey_1.df['total']/stragey_1.initial_balance).plot(figsize=(18,6),grid = True); # Net worth curve
#(2-price_usdt_btc_norm[trade_symbols].mean(axis=1)).plot(figsize=(18,6),grid = True);

img

# Strategy leverage
stragey_1.df['leverage'].plot(figsize=(18,6),grid = True);

img

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

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH', 'ETC','ATOM','BNB','EOS','LTC'])) # Remaining currencies
e = Exchange(trade_symbols+['BTC'],initial_balance=10000,commission=0.0005,log=False)
trade_value = 2000
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        if e.account[symbol]['value'] - trade_value  < -20 :
            e.Sell(symbol, price, round((trade_value-e.account[symbol]['value'])/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if e.account[symbol]['value'] - trade_value > 20 :
            pass
            #e.Buy(symbol, price, round((e.account[symbol]['value']-trade_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        empty_value += e.account[symbol]['value']
stragey_1b = e
(stragey_1b.df['total']/stragey_1.initial_balance).plot(figsize=(18,6),grid = True); # Net worth curve
(2-price_usdt_btc_norm[trade_symbols].mean(axis=1)).plot(figsize=(18,6),grid = True);

img

Второй код стратегии

Логика стратегии:

  • Проверьте, есть ли цена или есть цена для торговли
  • Проверьте отклонение курса валюты от индекса
  • Идите длинный и короткий на основе отклонения суждения, и судить о позиции в соответствии с размером отклонения
  • Расчет необеспеченных позиций и хеджирование BTC

Trade_value также контролирует размер открытых позиций.

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH'])) # Remaining currencies
price_usdt_btc_norm_mean = price_usdt_btc_norm[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols+['BTC'],initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,0)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        empty_value += now_value
        if aim_value - now_value > 50:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -50:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
    price = row[1]['BTC']
    aim_value = -empty_value
    now_value = e.account['BTC']['value']*np.sign(e.account['BTC']['amount'])
    if aim_value - now_value > 50:
        e.Buy('BTC', price, round((aim_value - now_value)/price, 6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
    if aim_value - now_value < -50:
        e.Sell('BTC', price, -round((aim_value - now_value)/price, 6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
stragey_2 = e

Возврат второй стратегии намного лучше первой стратегии. За последние два месяца он имеет 100%-ную доходность, но все еще имеет 20%-ную ретрасценцию. За последнюю неделю из-за небольших колебаний на рынке доходность не очевидна. Общий рычаг не большой. Эта стратегия стоит попробовать. В зависимости от степени отклонения, было открыто не более 7800 позиций USDT.

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

(stragey_2.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True);

img

# Summary results by currency
pd.DataFrame(e.account).T.apply(lambda x:round(x,3))

img

e.df['leverage'].plot(figsize=(18,6),grid = True);

img

Если результат не хеджирования будет следующим, разница на самом деле не большая, потому что длинные и короткие позиции в основном сбалансированы.

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH'])) # Remaining currencies
price_usdt_btc_norm_mean = price_usdt_btc_norm[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        empty_value += now_value
        if aim_value - now_value > 20:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -20:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2b = e
(stragey_2b.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True);
#(stragey_2.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True); # Can be stacked together

img

Если вы обратитесь к регрессии цен на USDT, эффект будет намного хуже

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH']))+['BTC'] #Remaining currencies
price_usdt_norm_mean = price_usdt_norm[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols+['BTC']:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_norm.loc[row[0],symbol] - price_usdt_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        empty_value += now_value
        if aim_value - now_value > 20:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -20:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2c = e
(stragey_2c.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True);
(stragey_2b.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True);

img

Если вы ограничите максимальное значение позиции, производительность будет хуже

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH'])) #Remaining currencies
price_usdt_btc_norm_mean = price_usdt_btc_norm[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols+['BTC'],initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        empty_value += now_value
        if aim_value - now_value > 20 and abs(aim_value)<3000:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -20 and abs(aim_value)<3000:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
    price = row[1]['BTC']
    aim_value = -empty_value
    now_value = e.account['BTC']['value']*np.sign(e.account['BTC']['amount'])
    if aim_value - now_value > 20:
        e.Buy('BTC', price, round((aim_value - now_value)/price, 6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
    if aim_value - now_value < -20:
        e.Sell('BTC', price, -round((aim_value - now_value)/price, 6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
stragey_2d = e
(stragey_2d.df['total']/stragey_2.initial_balance).plot(figsize=(17,6),grid = True);

img

Резюме и риск

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

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

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

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


Связанные

Больше