Investigación sobre Binance Futures estrategia de cobertura multi-moneda Parte 4

El autor:La bondad, Creado: 2020-05-14 15:18:56, Actualizado: 2023-11-04 19:51:33

img

La reciente revisión de la estrategia de cobertura de futuros multidivisa de Binance y los resultados de las pruebas de retroceso de la línea K a nivel de minutos

Se han publicado tres informes de investigación sobre la estrategia de cobertura de monedas múltiples de Binance, aquí está el cuarto. La conexión de los tres primeros artículos, debe leerlo de nuevo si no lo ha leído, puede comprender la idea de formación de la estrategia, el establecimiento de parámetros específicos y la lógica de la estrategia.

Investigación sobre la estrategia de cobertura de divisas múltiples de Binance Futures Parte 1:https://www.fmz.com/digest-topic/5584

Investigación sobre la estrategia de cobertura de divisas múltiples de Binance Futures Parte 2:https://www.fmz.com/digest-topic/5588

Investigación sobre Binance Futures estrategia de cobertura multi-moneda Parte 3:https://www.fmz.com/digest-topic/5605

Este artículo es para revisar la situación real del mercado de la semana reciente, y resumir las ganancias y pérdidas.

# 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']

Datos de línea K de nivel de minutos

Los datos del 21 de febrero al 15 de abril a las dos de la tarde, un total de 77160 * 24, lo que redujo enormemente nuestra velocidad de backtest, el motor de backtest no es lo suficientemente eficiente, puede optimizarlo usted mismo.

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']]

Revisión de la semana pasada

El código de estrategia fue lanzado en el grupo de WeChat el 10 de abril. Al principio, un grupo de personas ejecutó la estrategia 2 ((cort over-rise y long over-fall). En los primeros tres días, el rendimiento fue muy bueno, y el retracement fue muy bajo. en los días siguientes, algunos comerciantes magnificaron el apalancamiento, algunos incluso usan la totalidad de sus fondos para operar, y las ganancias alcanzaron el 10% en un día. Strategy Square también lanzó muchas estrategias de mercado reales, muchas personas comenzaron a estar insatisfechas con los parámetros recomendados conservadores, y han amplificado el volumen de transacciones. Después del 13 de abril, debido a la tendencia independiente de BNB, la ganancia comenzó a retroceder y a lados. Si miras el parámetro de trade_value del 3%, probablemente retrocedió 1%. Sin embargo, debido a los parámetros ampliados, muchos comerciantes ganan y pierden mucho menos.

img

En este caso, dado que se trata de una actualización a nivel de minuto, el parámetro Alpha debe ajustarse. Desde un punto de vista del mercado real, la tendencia de la curva es consistente, lo que indica que nuestra prueba de retroceso puede usarse como una referencia sólida. El valor neto ha alcanzado el pico del valor neto a partir de 4.13 y ha estado en la fase de retroceso y lateral.

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

Estrategia 1, la estrategia de altcoin corto alcanza rendimientos positivos

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

Estrategia 2 compra de pérdidas largas y venta de pérdidas cortas análisis de beneficios

Imprimir la información de la cuenta final muestra que la mayoría de las monedas han traído ganancias, y el BNB ha sufrido la mayoría de las pérdidas.

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

Si se eliminan BNB y ATOM, el resultado es mejor, pero la estrategia todavía estará en la etapa de retroceso recientemente.

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

En los últimos dos días, se ha vuelto popular ejecutar estrategias de divisas convencionales. Vamos a probar esta estrategia. Debido a la disminución de la variedad de divisas, el valor del comercio se incrementó apropiadamente en 4 veces para la comparación, y los resultados funcionaron bien, especialmente porque el reciente retroceso fue pequeño.

Debe tenerse en cuenta que solo la moneda principal no es tan buena como la moneda completa en el backtest de tiempo más largo, y hay más retracements.

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

Análisis de los parámetros de la tarifa de gestión y de la estrategia

Dado que los primeros informes usaron la línea de nivel de hora k, y los parámetros reales son muy diferentes con las situaciones reales del mercado, ahora con la línea de nivel de minutos k, se puede ver cómo establecer algunos parámetros.

  • Alfa = 0.03 El parámetro Alfa de la media móvil exponencial. Cuanto mayor sea la configuración, más sensible será el seguimiento del precio de referencia y menos transacciones. La posición final de mantenimiento también será menor, lo que reduce el apalancamiento, pero también reducirá el rendimiento y los retracements máximos.

  • Actualizar_base_price_time_interval = 30 * 60 Con qué frecuencia actualizar el precio base, en segundos, relacionado con el parámetro Alpha, cuanto menor sea el ajuste Alpha, más pequeño puede ser el intervalo

  • Trade_value: Cada 1% del precio de altcoin (denominado en BTC) se desvía del valor de tenencia del índice, que debe determinarse de acuerdo con los fondos totales invertidos y la preferencia de riesgo. Se recomienda establecer 3-10% de los fondos totales. Puede ver el tamaño del apalancamiento a través de la prueba de retroceso del entorno de investigación. Trade_value puede ser menor que Adjust_value, como la mitad de Adjust_value, que es equivalente al valor de tenencia del 2% del índice.

  • Adjust_value: El valor del contrato (valoración USDT) ajusta el valor de desviación. Cuando el índice se desvía de * Trade_value-position actual> Adjust_value, es decir, la diferencia entre la posición objetivo y la posición actual excede este valor, se iniciará la negociación. Los ajustes demasiado grandes son lentos, las transacciones demasiado pequeñas son frecuentes y no pueden ser menores de 10, de lo contrario no se alcanzará la transacción mínima, se recomienda establecerla en más del 40% del valor de Trade_value.

No hace falta decir que el valor del comercio está directamente relacionado con nuestras ganancias y riesgos.

Como Alpha tiene datos de frecuencia más alta esta vez, obviamente es más razonable actualizarlo cada 1 minuto. Naturalmente, es más pequeño que el original. El número específico se puede determinar mediante backtest.

Adjust_value siempre ha recomendado más del 40% de Trade_value. El ajuste original de la línea 1h K tiene poco efecto. Algunas personas quieren ajustarlo muy bajo, para que pueda estar más cerca de la posición objetivo. Aquí analizaremos por qué no se debe hacer.

Primero analizar el problema de manejo de las tarifas

Se puede ver que bajo la tasa por defecto de 0,00075, la tarifa de manejo es de 293 y la ganancia es de 270, que es una proporción muy alta.

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

El resultado es una línea recta hacia arriba, BNB sólo trae un poco de giros y vueltas, el menor valor de ajuste capta todas las fluctuaciones.

¿Qué pasa si el valor de ajuste es pequeño si hay una pequeña cantidad de tarifa de manejo?

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

Como resultado, también salió de una curva descendente lineal. Es fácil de entender si lo piensas, los ajustes frecuentes dentro de un pequeño diferencial solo perderán la tarifa de manejo.

En conjunto, cuanto más bajo sea el nivel de las comisiones, menor será el valor de ajuste que se puede establecer, más frecuente será la transacción y mayor será la ganancia.

Problemas con la configuración de Alpha

Dado que hay una línea de minuto, el precio de referencia se actualizará una vez por minuto, aquí simplemente hacemos una prueba posterior para determinar el tamaño de alfa.

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

Resultados de las pruebas de retroceso de la línea de minutos en los últimos dos meses

Finalmente, mire los resultados de una prueba de retroceso de largo tiempo. Ahora mismo, uno tras otro sube, y el patrimonio neto de hoy está en un nuevo mínimo. Déjenos dar la siguiente confianza. Debido a que la frecuencia de la línea de minutos es mayor, abrirá y cerrará posiciones dentro de la hora, por lo que la ganancia será mucho mayor.

Otro punto, siempre hemos estado utilizando un valor comercial fijo, lo que hace que la utilización de fondos en el período posterior sea insuficiente, y la tasa de rendimiento real todavía puede aumentar mucho.

¿Dónde estamos en el período de prueba de dos meses?

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


Relacionados

Más.