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

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

Автор:Доброта, Создано: 2020-05-14 15:18:56, Обновлено: 2023-11-04 19:51:33

img

Недавний обзор стратегии хеджирования фьючерсов Binance в нескольких валютах и результаты обратного теста на уровне минуты K-линии

Были опубликованы три исследовательских доклада о стратегии хеджирования в нескольких валютах Binance, вот четвертый.

Исследование стратегии хеджирования в нескольких валютах Binance Futures Часть 1:https://www.fmz.com/digest-topic/5584

Исследование стратегии хеджирования в нескольких валютах Binance Futures Часть 2:https://www.fmz.com/digest-topic/5588

Исследование стратегии хеджирования в нескольких валютах Binance Futures Часть 3:https://www.fmz.com/digest-topic/5605

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

# Libraries to import
import pandas as pd
import requests
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
%matplotlib inline
symbols = ['BTC','ETH', 'BCH', 'XRP', 'EOS', 'LTC', 'TRX', 'ETC', 'LINK', 'XLM', 'ADA', 'XMR', 'DASH', 'ZEC', 'XTZ', 'BNB', 'ATOM', 'ONT', 'IOTA', 'BAT', 'VET', 'NEO', 'QTUM', 'IOST']

Данные по строке K на уровне минут

Данные с 21 февраля по 15 апреля в два часа дня, в общей сложности 77160 * 24, что значительно снизило нашу скорость бэкстеста, двигатель бэкстеста недостаточно эффективен, вы можете оптимизировать его самостоятельно.

price_usdt = pd.read_csv('https://www.fmz.com/upload/asset/2b1fa7ab641385067ad.csv',index_col = 0)
price_usdt.shape
(77160, 24)
price_usdt.index = pd.to_datetime(price_usdt.index,unit='ms')
price_usdt_norm = price_usdt/price_usdt.fillna(method='bfill').iloc[0,]
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,]
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, 'fee':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,'fee':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 handling fee
        self.account['USDT']['fee'] += price*amount*self.commission
        self.account[symbol]['fee'] += price*amount*self.commission
        
        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 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']
        
        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']]

Обзор прошлой недели

Код стратегии был выпущен в группе WeChat 10 апреля. В начале группа людей запустила стратегию 2 ((короткий перевыполнение и длинный перевыполнение). В первые три дня доходность была очень хорошей, а ретракцион был очень низким. В последующие дни некоторые трейдеры увеличили рычаг, некоторые даже используют всю сумму своих средств для операции, и прибыль достигла 10% за один день. Strategy Square также выпустила много реальных рыночных стратегий, многие люди стали недовольны консервативными рекомендуемыми параметрами и усилили объем транзакций. После 13 апреля из-за независимой тенденции BNB прибыль начала отступать и отступать в сторону. Если вы посмотрите на 3% trade_value, она, вероятно, отступила на 1%. Однако из-за расширенных параметров дефолта многие трейдеры зарабатывают и теряют гораздо меньше.

img

Давайте посмотрим на полный валютный бэкстест Стратегии 2. Здесь, поскольку это обновление на минутном уровне, параметр Альфа должен быть скорректирован. С точки зрения реального рынка тенденция кривой последовательна, что указывает на то, что наш бэкстест может использоваться в качестве сильного ориентира. Чистая стоимость достигла пика чистой стоимости с 4.13 и далее и находится в фазе ретрассирования и боковой.

Alpha = 0.001
#price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.rolling(20).mean() # Ordinary moving average
price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() # Here is consistent with the strategy, using EMA
trade_symbols = list(set(symbols))
price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.00075,log=False)
trade_value = 300
for row in price_usdt.iloc[-7500:].iterrows():
    e.Update(row[0], row[1])
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm2.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'])
        if aim_value - now_value > 0.5*trade_value:
            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 < -0.5*trade_value:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2a = e
(stragey_2a.df['total']/stragey_2d.initial_balance).plot(figsize=(17,6),grid = True);

img

Стратегия 1, стратегия коротких альткоинов достигает положительной доходности

trade_symbols = list(set(symbols)-set(['LINK','BTC','XTZ','BCH', 'ETH'])) # Selling short currencies
e = Exchange(trade_symbols+['BTC'],initial_balance=10000,commission=0.00075,log=False)
trade_value = 2000
for row in price_usdt.iloc[-7500:].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  < -120 :
            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 > 120 :
            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 < -120:
        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 > 120:
        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
(stragey_1.df['total']/stragey_1.initial_balance).plot(figsize=(17,6),grid = True);

img

Стратегия 2 Покупка длинного превышения прибыли и продажа короткого превышения прибыли

Напечатанная информация о окончательном счете показывает, что большинство валют принесли прибыль, а BNB понесла наибольшее количество потерь.

pd.DataFrame(stragey_2a.account).T.apply(lambda x:round(x,3)).sort_values(by='realised_profit')

img

# BNB deviation
(price_usdt_btc_norm2.iloc[-7500:].BNB-price_usdt_btc_norm_mean[-7500:]).plot(figsize=(17,6),grid = True);
#price_usdt_btc_norm_mean[-7500:].plot(figsize=(17,6),grid = True);

img

Если BNB и ATOM будут удалены, результат будет лучше, но стратегия будет еще на стадии ретраксемента в последнее время.

Alpha = 0.001
price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() # Here is consistent with the strategy, using EMA
trade_symbols = list(set(symbols)-set(['BNB','ATOM']))
price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.00075,log=False)
trade_value = 300
for row in price_usdt.iloc[-7500:].iterrows():
    e.Update(row[0], row[1])
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm2.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'])
        if aim_value - now_value > 0.5*trade_value:
            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 < -0.5*trade_value:
            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_2b.initial_balance).plot(figsize=(17,6),grid = True);

img

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

Следует отметить, что только основная валюта не так хороша, как полная валюта в более длительное время обратного теста, и есть больше ретрассов.

Alpha = 0.001
price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() # Here is consistent with the strategy, using EMA
trade_symbols = ['ETH','LTC','EOS','XRP','BCH']
price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.00075,log=False)
trade_value = 1200
for row in price_usdt.iloc[-7500:].iterrows():
    e.Update(row[0], row[1])
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm2.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'])
        if aim_value - now_value > 0.5*trade_value:
            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 < -0.5*trade_value:
            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']/e.initial_balance).plot(figsize=(17,6),grid = True);

img

Анализ платежей за обработку и параметров стратегии

Поскольку первые несколько отчетов использовали часовой уровень k линии, и фактические параметры очень отличаются от реальных рыночных ситуаций, теперь с минуты уровня k линии, вы можете увидеть, как установить некоторые параметры.

  • Альфа = 0.03 Альфа-параметр экспоненциальной скользящей средней. Чем больше настройка, тем более чувствительным будет отслеживание цены эталонного показателя и тем меньше транзакций.

  • Update_base_price_time_interval = 30 * 60 Как часто обновлять базовую цену, в секундах, в связи с параметром Альфа, чем меньше настройка Альфа, тем меньше интервал может быть установлен

  • Trade_value: Каждый 1% цены альткоина (в BTC) отклоняется от стоимости хранения индекса, которая должна определяться в соответствии с общим объемом инвестированных средств и предпочтениями риска. Рекомендуется установить 3-10% от общего объема средств. Вы можете посмотреть на размер рычага через бэкстест исследовательской среды. Trade_value может быть меньше Adjust_value, например, половины Adjust_value, что эквивалентно стоимости хранения 2% от индекса.

  • Adjust_value: стоимость контракта (оценка в USDT) корректирует значение отклонения. Когда индекс отклоняется от * Trade_value-current position> Adjust_value, то есть разница между целевой позицией и текущей позицией превышает это значение, начинается торговля. Слишком большие корректировки медленны, слишком малые транзакции часто и не могут быть меньше 10, иначе минимальная транзакция не будет достигнута, рекомендуется установить ее более чем на 40% от Trade_value.

Излишне говорить, что Trade_value напрямую связан с нашими прибылями и рисками.

Поскольку на этот раз Альфа имеет более высокие частотные данные, очевидно, более разумно обновлять их каждые 1 минуту. Естественно, это меньше, чем первоначальное. Конкретное число можно определить путем обратного теста.

Adjust_value всегда рекомендует более 40% от Trade_value. Оригинальное настройка линии 1h K имеет мало эффекта. Некоторые люди хотят настроить его очень низко, чтобы он мог быть ближе к целевой позиции. Здесь мы проанализируем, почему это не следует делать.

Сначала проанализируйте проблему оплаты

Можно увидеть, что при ставке по умолчанию 0,00075 комиссионная за обработку составляет 293 и прибыль составляет 270, что является очень высокой пропорцией.

stragey_2a.account['USDT']
{'fee': 293.85972778530453,
 'leverage': 0.45999999999999996,
 'margin': 236.23559736312995,
 'realised_profit': 281.77464608744435,
 'total': 10271.146238,
 'unrealised_profit': -10.628408369648495}
Alpha = 0.001
#price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.rolling(20).mean() # Ordinary moving average
price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() # Here is consistent with the strategy, using EMA
trade_symbols = list(set(symbols))
price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0,log=False)
trade_value = 300
for row in price_usdt.iloc[-7500:].iterrows():
    e.Update(row[0], row[1])
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm2.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'])
        if aim_value - now_value > 10:
            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 < 10:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2d = e
(stragey_2d.df['total']/e.initial_balance).plot(figsize=(17,6),grid = True);

img

Результат - прямая линия вверх, BNB приносит только небольшие повороты, более низкое значение Adjust_value улавливает любую колебание.

Что делать, если adjustment_value небольшой, если есть небольшая сумма оплаты за обработку?

Alpha = 0.001
#price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.rolling(20).mean() # Ordinary moving average
price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() # Here is consistent with the strategy, using EMA
trade_symbols = list(set(symbols))
price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.00075,log=False)
trade_value = 300
for row in price_usdt.iloc[-7500:].iterrows():
    e.Update(row[0], row[1])
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm2.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'])
        if aim_value - now_value > 10:
            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 < 10:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2e = e
(stragey_2e.df['total']/e.initial_balance).plot(figsize=(17,6),grid = True);

img

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

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

Проблемы с настройками Альфа

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

for Alpha in [0.0001, 0.0003, 0.0006, 0.001, 0.0015, 0.002, 0.004, 0.01, 0.02]:
#price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.rolling(20).mean() # Ordinary moving average
    price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() #Here is consistent with the strategy, using EMA
    trade_symbols = list(set(symbols))
    price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
    e = Exchange(trade_symbols,initial_balance=10000,commission=0.00075,log=False)
    trade_value = 300
    for row in price_usdt.iloc[-7500:].iterrows():
        e.Update(row[0], row[1])
        for symbol in trade_symbols:
            price = row[1][symbol]
            if np.isnan(price):
                continue
            diff = price_usdt_btc_norm2.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'])
            if aim_value - now_value > 0.5*trade_value:
                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 < -0.5*trade_value:
                e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
    print(Alpha, e.account['USDT']['unrealised_profit']+e.account['USDT']['realised_profit'])
0.0001 -77.80281760941007
0.0003 179.38803796199724
0.0006 218.12579924541367
0.001 271.1462377177959
0.0015 250.0014065973528
0.002 207.38692166891275
0.004 129.08021828803027
0.01 65.12410041648158
0.02 58.62356792410955

Результаты обратных испытаний минутной линии за последние два месяца

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

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

Где мы находимся в двухмесячном периоде обратного тестирования?

img

Alpha = 0.001
#price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.rolling(20).mean() # Ordinary moving average
price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() # Here is consistent with the strategy, using EMA
trade_symbols = list(set(symbols))
price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.00075,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm2.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'])
        if aim_value - now_value > 0.5*trade_value:
            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 < -0.5*trade_value:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2f = e
(stragey_2f.df['total']/stragey_2e.initial_balance).plot(figsize=(17,6),grid = True);

img

(stragey_2f.df['leverage']/stragey_2e.initial_balance).plot(figsize=(17,6),grid = True);

img


Связанные

Больше