Type/to search
3
Follow
1507
Followers
Stratégie d'équilibre perpétuel pour acheter au plus bas d'un marché baissier
Discussions
Created 2022-06-02 10:00:04  Updated 2024-12-02 21:36:36
 7
 6499

img

Dans le passé, FMZ a officiellement publié une stratégie de grille perpétuelle, qui était très populaire parmi les utilisateurs, et le trading en temps réel de TRX a généré beaucoup de bénéfices au cours de l'année écoulée avec des risques contrôlables. La stratégie du réseau unique durable présente également certains problèmes :

  1. Il est nécessaire de définir des paramètres tels que le prix initial, l'espacement de la grille, la valeur de la grille, les modes long et court, etc. Les paramètres sont assez compliqués, ont un impact plus important sur les rendements et sont difficiles à définir pour les novices.
  2. Le risque de vente à découvert de la stratégie de grille perpétuelle est très élevé, tandis que le risque de vente à long terme est relativement faible. Même si la valeur de la grille est fixée à un niveau très bas, l'impact sur le prix de liquidation de la vente à découvert n'est pas significatif.
  3. La grille de contrats perpétuels peut choisir d'aller uniquement à l'achat pour éviter les risques de vente à découvert, ce qui semble être acceptable pour le moment. Cependant, il existe un problème : le prix actuel dépasse le prix initial, ce qui entraîne une position vide et le prix initial doit être réinitialisé.

J'ai déjà écrit un article sur les principes de la stratégie d'équilibre et sa comparaison avec la stratégie de grille, qui peut encore être référencé maintenant : https://www.fmz.com/digest-topic/5930. La stratégie équilibrée maintient toujours une position sur un ratio ou une valeur fixe. Elle vend une partie de la valeur lorsqu'elle monte et en achète une autre lorsqu'elle baisse. Elle peut être facilement mise en place et exécutée. Même si le prix de la monnaie augmente beaucoup, il n’y a aucun risque de passer à côté. Le problème avec la stratégie d’équilibrage au comptant est que l’utilisation du capital est faible et qu’il n’existe aucun moyen simple d’ajouter un effet de levier. Le contrat perpétuel peut résoudre le problème. Si le capital total est de 1 000, vous pouvez détenir 2 000 en montant fixe, ce qui dépasse le capital initial et améliore le taux d'utilisation des fonds. Il existe également un paramètre permettant d'ajuster le ratio, qui contrôle dans quelle mesure il faut augmenter ou diminuer les positions lorsque le prix augmente ou baisse. Par exemple, s'il est défini sur 0,01, cela signifie qu'il faut réduire les positions une fois lorsque le prix augmente de 1 %. et d'augmenter les positions une fois que le prix baisse de 1 %.

Pour les débutants, la stratégie d'équilibre est fortement recommandée. Elle est facile à utiliser et ne nécessite que de définir un paramètre de ratio de détention ou de valeur de détention, et vous pouvez l'exécuter sans vous soucier de la hausse des prix. Ceux qui ont une certaine expérience peuvent choisir la stratégie de grille, décider des limites supérieures et inférieures des fluctuations et des fonds pour chaque grille, améliorer l'utilisation du capital et rechercher un rendement maximal.

Afin de faciliter le backtesting de davantage de paires de trading, ce document montrera le processus complet de backtesting et les utilisateurs pourront ajuster différents paramètres et paires de trading à des fins de comparaison. (La version est Python3, et un agent est nécessaire pour télécharger le marché. Les utilisateurs peuvent télécharger Anancoda3 eux-mêmes ou l'exécuter via le colab de Google)

python
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
python
## 当前交易对 Info = requests.get('https://fapi.binance.com/fapi/v1/exchangeInfo') symbols = [s['symbol'] for s in Info.json()['symbols']] symbols = list(set(filter(lambda x: x[-4:] == 'USDT', [s.split('_')[0] for s in symbols]))- set(['1000SHIBUSDT','1000XECUSDT','BTCDOMUSDT','DEFIUSDT','BTCSTUSDT'])) + ['SHIBUSDT','XECUSDT'] print(symbols)
['FLMUSDT', 'ICPUSDT', 'CHZUSDT', 'APEUSDT', 'DARUSDT', 'TLMUSDT', 'ETHUSDT', 'STMXUSDT', 'ENJUSDT', 'LINKUSDT', 'OGNUSDT', 'RSRUSDT', 'QTUMUSDT', 'UNIUSDT', 'BNBUSDT', 'XLMUSDT', 'ATOMUSDT', 'LPTUSDT', 'UNFIUSDT', 'DASHUSDT', 'BTCUSDT', 'NEOUSDT', 'AAVEUSDT', 'DUSKUSDT', 'XRPUSDT', 'IOTXUSDT', 'CVCUSDT', 'SANDUSDT', 'XTZUSDT', 'IOTAUSDT', 'BELUSDT', 'MANAUSDT', 'IOSTUSDT', 'IMXUSDT', 'THETAUSDT', 'SCUSDT', 'DOGEUSDT', 'CELOUSDT', 'BNXUSDT', 'SNXUSDT', 'ZRXUSDT', 'HBARUSDT', 'DOTUSDT', 'ANKRUSDT', 'CELRUSDT', 'BAKEUSDT', 'GALUSDT', 'ICXUSDT', 'LRCUSDT', 'AVAXUSDT', 'C98USDT', 'MTLUSDT', 'FTTUSDT', 'MASKUSDT', 'RLCUSDT', 'MATICUSDT', 'COMPUSDT', 'BLZUSDT', 'CRVUSDT', 'ZECUSDT', 'RUNEUSDT', 'LITUSDT', 'ONEUSDT', 'ADAUSDT', 'NKNUSDT', 'LTCUSDT', 'ATAUSDT', 'GALAUSDT', 'BALUSDT', 'ROSEUSDT', 'EOSUSDT', 'YFIUSDT', 'SKLUSDT', 'BANDUSDT', 'ALGOUSDT', 'NEARUSDT', 'AXSUSDT', 'KSMUSDT', 'AUDIOUSDT', 'SRMUSDT', 'HNTUSDT', 'MKRUSDT', 'KLAYUSDT', 'FLOWUSDT', 'STORJUSDT', 'BCHUSDT', 'DYDXUSDT', 'ARUSDT', 'GMTUSDT', 'CHRUSDT', 'API3USDT', 'VETUSDT', 'KAVAUSDT', 'WAVESUSDT', 'EGLDUSDT', 'SFPUSDT', 'RENUSDT', 'SUSHIUSDT', 'SOLUSDT', 'RVNUSDT', 'ONTUSDT', 'BTSUSDT', 'ZILUSDT', 'GTCUSDT', 'ZENUSDT', 'ALICEUSDT', 'ETCUSDT', 'TRXUSDT', 'TOMOUSDT', 'FILUSDT', 'ARPAUSDT', 'CTKUSDT', 'BATUSDT', 'SXPUSDT', '1INCHUSDT', 'HOTUSDT', 'WOOUSDT', 'LINAUSDT', 'REEFUSDT', 'GRTUSDT', 'RAYUSDT', 'COTIUSDT', 'XMRUSDT', 'PEOPLEUSDT', 'OCEANUSDT', 'JASMYUSDT', 'TRBUSDT', 'ANTUSDT', 'XEMUSDT', 'DGBUSDT', 'ENSUSDT', 'OMGUSDT', 'ALPHAUSDT', 'FTMUSDT', 'DENTUSDT', 'KNCUSDT', 'CTSIUSDT', 'SHIBUSDT', 'XECUSDT']
python
#获取任意周期K线的函数 def GetKlines(symbol='BTCUSDT',start='2020-8-10',end='2021-8-10',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: 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) #print(url) 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

En téléchargeant les cours de clôture de toutes les paires de trading de 2021 à ce jour, nous pouvons observer l'évolution de l'indice global du marché : 2021 à 2022 est sans aucun doute un marché haussier, et l'indice a augmenté de 14 fois à un moment donné. On peut dire que Il y a de l'or partout. La valeur de certaines pièces a augmenté de plusieurs centaines de fois. Cependant, en 2022, un marché baissier a commencé et a duré six mois. L'indice a chuté de 80 % et des dizaines de crypto-monnaies ont reculé de plus de 90 %. Ces hausses et baisses brutales reflètent les énormes risques liés aux stratégies de réseau.

L'indice actuel se situe autour de 3, ce qui représente toujours une augmentation de 200 % par rapport au début de 2021. Compte tenu de l'évolution du marché, il devrait s'agir d'un plancher relatif à l'heure actuelle.

Le prix le plus élevé de la monnaie a augmenté de plus de 10 fois par rapport au début de l'année :

'MKRUSDT': 10.294, 'CRVUSDT': 10.513, 'STORJUSDT': 10.674, 'SKLUSDT': 11.009, 'CVCUSDT': 11.026, 'SRMUSDT': 11.031, 'QTUMUSDT': 12.066, 'ALPHAUSDT': 12.103, 'ZENUSDT': 12.631, 'VETUSDT': 13.296, 'ROSEUSDT': 13.429, 'FTTUSDT': 13.705, 'IOSTUSDT': 13.786, 'COTIUSDT': 13.958, 'NEARUSDT': 14.855, 'HBARUSDT': 15.312, 'RLCUSDT': 15.432, 'SCUSDT': 15.6, 'GALAUSDT': 15.722, 'RUNEUSDT': 15.795, 'ADAUSDT': 16.94, 'MTLUSDT': 17.18, 'BNBUSDT': 17.899, 'RVNUSDT': 18.169, 'EGLDUSDT': 18.879, 'LRCUSDT': 19.499, 'ANKRUSDT': 21.398, 'ETCUSDT': 23.51, 'DUSKUSDT': 23.55, 'AUDIOUSDT': 25.306, 'OGNUSDT': 25.524, 'GMTUSDT': 28.83, 'ENJUSDT': 33.073, 'STMXUSDT': 33.18, 'IOTXUSDT': 35.866, 'AVAXUSDT': 36.946, 'CHZUSDT': 37.128, 'CELRUSDT': 37.273, 'HNTUSDT': 38.779, 'CTSIUSDT': 41.108, 'HOTUSDT': 46.466, 'CHRUSDT': 61.091, 'MANAUSDT': 62.143, 'NKNUSDT': 70.636, 'ONEUSDT': 84.132, 'DENTUSDT': 99.973, 'DOGEUSDT': 121.447, 'SOLUSDT': 140.296, 'MATICUSDT': 161.846, 'FTMUSDT': 192.507, 'SANDUSDT': 203.219, 'AXSUSDT': 270.41

Le retracement actuel est supérieur à 80 % du point le plus haut :

ICPUSDT': 0.022, 'FILUSDT': 0.043, 'BAKEUSDT': 0.046, 'TLMUSDT': 0.05, 'LITUSDT': 0.053, 'LINAUSDT': 0.054, 'JASMYUSDT': 0.056, 'ALPHAUSDT': 0.062, 'RAYUSDT': 0.062, 'GRTUSDT': 0.067, 'DENTUSDT': 0.068, 'RSRUSDT': 0.068, 'XEMUSDT': 0.068, 'UNFIUSDT': 0.072, 'DYDXUSDT': 0.074, 'SUSHIUSDT': 0.074, 'OGNUSDT': 0.074, 'COMPUSDT': 0.074, 'NKNUSDT': 0.078, 'SKLUSDT': 0.08, 'DGBUSDT': 0.081, 'RLCUSDT': 0.085, 'REEFUSDT': 0.086, 'BANDUSDT': 0.086, 'HOTUSDT': 0.092, 'SRMUSDT': 0.092, 'RENUSDT': 0.092, 'BTSUSDT': 0.093, 'THETAUSDT': 0.094, 'FLMUSDT': 0.094, 'EOSUSDT': 0.095, 'TRBUSDT': 0.095, 'SXPUSDT': 0.095, 'ATAUSDT': 0.096, 'NEOUSDT': 0.096, 'FLOWUSDT': 0.097, 'YFIUSDT': 0.101, 'BALUSDT': 0.106, 'MASKUSDT': 0.106, 'ONTUSDT': 0.108, 'CELRUSDT': 0.108, 'AUDIOUSDT': 0.108, 'SCUSDT': 0.11, 'GALAUSDT': 0.113, 'GTCUSDT': 0.117, 'CTSIUSDT': 0.117, 'STMXUSDT': 0.118, 'DARUSDT': 0.118, 'ALICEUSDT': 0.119, 'SNXUSDT': 0.124, 'FTMUSDT': 0.126, 'BCHUSDT': 0.127, 'SFPUSDT': 0.127, 'ROSEUSDT': 0.128, 'DOGEUSDT': 0.128, 'RVNUSDT': 0.129, 'OCEANUSDT': 0.129, 'VETUSDT': 0.13, 'KSMUSDT': 0.131, 'ICXUSDT': 0.131, 'UNIUSDT': 0.131, 'ONEUSDT': 0.131, '1INCHUSDT': 0.134, 'IOTAUSDT': 0.139, 'C98USDT': 0.139, 'WAVESUSDT': 0.14, 'DUSKUSDT': 0.141, 'LINKUSDT': 0.143, 'DASHUSDT': 0.143, 'OMGUSDT': 0.143, 'PEOPLEUSDT': 0.143, 'AXSUSDT': 0.15, 'ENJUSDT': 0.15, 'QTUMUSDT': 0.152, 'SHIBUSDT': 0.154, 'ZENUSDT': 0.154, 'BLZUSDT': 0.154, 'ANTUSDT': 0.155, 'XECUSDT': 0.155, 'CHZUSDT': 0.158, 'RUNEUSDT': 0.163, 'ENSUSDT': 0.165, 'LRCUSDT': 0.167, 'CHRUSDT': 0.168, 'IOTXUSDT': 0.174, 'TOMOUSDT': 0.176, 'ALGOUSDT': 0.177, 'EGLDUSDT': 0.177, 'ARUSDT': 0.178, 'LTCUSDT': 0.178, 'HNTUSDT': 0.18, 'LPTUSDT': 0.181, 'SOLUSDT': 0.183, 'ARPAUSDT': 0.184, 'BELUSDT': 0.184, 'ETCUSDT': 0.186, 'ZRXUSDT': 0.187, 'AAVEUSDT': 0.187, 'CVCUSDT': 0.188, 'STORJUSDT': 0.189, 'COTIUSDT': 0.19, 'CELOUSDT': 0.191, 'SANDUSDT': 0.191, 'ADAUSDT': 0.192, 'HBARUSDT': 0.194, 'DOTUSDT': 0.195, 'XLMUSDT': 0.195

python
#下载所有交易对的收盘价 start_date = '2021-1-1' end_date = '2022-05-30' period = '1d' df_all = pd.DataFrame(index=pd.date_range(start=start_date, end=end_date, freq=period),columns=symbols) for i in range(len(symbols)): #print(symbols[i]) symbol = symbols[i] df_s = GetKlines(symbol=symbol,start=start_date,end=end_date,period=period,base='api',v='v3') df_all[symbol] = df_s[~df_s.index.duplicated(keep='first')].close
python
#指数变化 df_norm = df_all/df_all.fillna(method='bfill').iloc[0] #归一化 df_norm.mean(axis=1).plot(figsize=(15,6),grid=True);

png

python
#比年初的最高涨幅 max_up = df_all.max()/df_all.fillna(method='bfill').iloc[0] print(max_up.map(lambda x:round(x,3)).sort_values().to_dict())
{'JASMYUSDT': 1.0, 'ICPUSDT': 1.0, 'LINAUSDT': 1.0, 'WOOUSDT': 1.0, 'GALUSDT': 1.0, 'PEOPLEUSDT': 1.0, 'XECUSDT': 1.026, 'ENSUSDT': 1.032, 'TLMUSDT': 1.039, 'IMXUSDT': 1.099, 'FLOWUSDT': 1.155, 'ATAUSDT': 1.216, 'DARUSDT': 1.261, 'ALICEUSDT': 1.312, 'BNXUSDT': 1.522, 'API3USDT': 1.732, 'GTCUSDT': 1.833, 'KLAYUSDT': 1.891, 'BAKEUSDT': 1.892, 'DYDXUSDT': 2.062, 'SHIBUSDT': 2.281, 'BTCUSDT': 2.302, 'MASKUSDT': 2.396, 'SFPUSDT': 2.74, 'LPTUSDT': 2.75, 'APEUSDT': 2.783, 'ARUSDT': 2.928, 'CELOUSDT': 2.951, 'ZILUSDT': 2.999, 'LTCUSDT': 3.072, 'SNXUSDT': 3.266, 'XEMUSDT': 3.555, 'XMRUSDT': 3.564, 'YFIUSDT': 3.794, 'BANDUSDT': 3.812, 'RAYUSDT': 3.924, 'REEFUSDT': 4.184, 'ANTUSDT': 4.205, 'XTZUSDT': 4.339, 'CTKUSDT': 4.352, 'LITUSDT': 4.38, 'RSRUSDT': 4.407, 'LINKUSDT': 4.412, 'BCHUSDT': 4.527, 'DASHUSDT': 5.037, 'BALUSDT': 5.172, 'OCEANUSDT': 5.277, 'EOSUSDT': 5.503, 'RENUSDT': 5.538, 'XLMUSDT': 5.563, 'TOMOUSDT': 5.567, 'ZECUSDT': 5.654, 'COMPUSDT': 5.87, 'DGBUSDT': 5.948, 'ALGOUSDT': 5.981, 'ONTUSDT': 5.997, 'BELUSDT': 6.101, 'TRXUSDT': 6.116, 'ZRXUSDT': 6.135, 'GRTUSDT': 6.45, '1INCHUSDT': 6.479, 'DOTUSDT': 6.502, 'ETHUSDT': 6.596, 'KAVAUSDT': 6.687, 'ICXUSDT': 6.74, 'SUSHIUSDT': 6.848, 'AAVEUSDT': 6.931, 'BTSUSDT': 6.961, 'KNCUSDT': 6.966, 'C98USDT': 7.091, 'THETAUSDT': 7.222, 'ATOMUSDT': 7.553, 'OMGUSDT': 7.556, 'SXPUSDT': 7.681, 'UNFIUSDT': 7.696, 'XRPUSDT': 7.726, 'TRBUSDT': 8.241, 'BLZUSDT': 8.434, 'NEOUSDT': 8.491, 'FLMUSDT': 8.506, 'KSMUSDT': 8.571, 'FILUSDT': 8.591, 'IOTAUSDT': 8.616, 'BATUSDT': 8.647, 'ARPAUSDT': 9.055, 'UNIUSDT': 9.104, 'WAVESUSDT': 9.106, 'MKRUSDT': 10.294, 'CRVUSDT': 10.513, 'STORJUSDT': 10.674, 'SKLUSDT': 11.009, 'CVCUSDT': 11.026, 'SRMUSDT': 11.031, 'QTUMUSDT': 12.066, 'ALPHAUSDT': 12.103, 'ZENUSDT': 12.631, 'VETUSDT': 13.296, 'ROSEUSDT': 13.429, 'FTTUSDT': 13.705, 'IOSTUSDT': 13.786, 'COTIUSDT': 13.958, 'NEARUSDT': 14.855, 'HBARUSDT': 15.312, 'RLCUSDT': 15.432, 'SCUSDT': 15.6, 'GALAUSDT': 15.722, 'RUNEUSDT': 15.795, 'ADAUSDT': 16.94, 'MTLUSDT': 17.18, 'BNBUSDT': 17.899, 'RVNUSDT': 18.169, 'EGLDUSDT': 18.879, 'LRCUSDT': 19.499, 'ANKRUSDT': 21.398, 'ETCUSDT': 23.51, 'DUSKUSDT': 23.55, 'AUDIOUSDT': 25.306, 'OGNUSDT': 25.524, 'GMTUSDT': 28.83, 'ENJUSDT': 33.073, 'STMXUSDT': 33.18, 'IOTXUSDT': 35.866, 'AVAXUSDT': 36.946, 'CHZUSDT': 37.128, 'CELRUSDT': 37.273, 'HNTUSDT': 38.779, 'CTSIUSDT': 41.108, 'HOTUSDT': 46.466, 'CHRUSDT': 61.091, 'MANAUSDT': 62.143, 'NKNUSDT': 70.636, 'ONEUSDT': 84.132, 'DENTUSDT': 99.973, 'DOGEUSDT': 121.447, 'SOLUSDT': 140.296, 'MATICUSDT': 161.846, 'FTMUSDT': 192.507, 'SANDUSDT': 203.219, 'AXSUSDT': 270.41}
python
#当前最大回测 draw_down = df_all.iloc[-1]/df_all.max() print(draw_down.map(lambda x:round(x,3)).sort_values().to_dict())
{'ICPUSDT': 0.022, 'FILUSDT': 0.043, 'BAKEUSDT': 0.046, 'TLMUSDT': 0.05, 'LITUSDT': 0.053, 'LINAUSDT': 0.054, 'JASMYUSDT': 0.056, 'ALPHAUSDT': 0.062, 'RAYUSDT': 0.062, 'GRTUSDT': 0.067, 'DENTUSDT': 0.068, 'RSRUSDT': 0.068, 'XEMUSDT': 0.068, 'UNFIUSDT': 0.072, 'DYDXUSDT': 0.074, 'SUSHIUSDT': 0.074, 'OGNUSDT': 0.074, 'COMPUSDT': 0.074, 'NKNUSDT': 0.078, 'SKLUSDT': 0.08, 'DGBUSDT': 0.081, 'RLCUSDT': 0.085, 'REEFUSDT': 0.086, 'BANDUSDT': 0.086, 'HOTUSDT': 0.092, 'SRMUSDT': 0.092, 'RENUSDT': 0.092, 'BTSUSDT': 0.093, 'THETAUSDT': 0.094, 'FLMUSDT': 0.094, 'EOSUSDT': 0.095, 'TRBUSDT': 0.095, 'SXPUSDT': 0.095, 'ATAUSDT': 0.096, 'NEOUSDT': 0.096, 'FLOWUSDT': 0.097, 'YFIUSDT': 0.101, 'BALUSDT': 0.106, 'MASKUSDT': 0.106, 'ONTUSDT': 0.108, 'CELRUSDT': 0.108, 'AUDIOUSDT': 0.108, 'SCUSDT': 0.11, 'GALAUSDT': 0.113, 'GTCUSDT': 0.117, 'CTSIUSDT': 0.117, 'STMXUSDT': 0.118, 'DARUSDT': 0.118, 'ALICEUSDT': 0.119, 'SNXUSDT': 0.124, 'FTMUSDT': 0.126, 'BCHUSDT': 0.127, 'SFPUSDT': 0.127, 'ROSEUSDT': 0.128, 'DOGEUSDT': 0.128, 'RVNUSDT': 0.129, 'OCEANUSDT': 0.129, 'VETUSDT': 0.13, 'KSMUSDT': 0.131, 'ICXUSDT': 0.131, 'UNIUSDT': 0.131, 'ONEUSDT': 0.131, '1INCHUSDT': 0.134, 'IOTAUSDT': 0.139, 'C98USDT': 0.139, 'WAVESUSDT': 0.14, 'DUSKUSDT': 0.141, 'LINKUSDT': 0.143, 'DASHUSDT': 0.143, 'OMGUSDT': 0.143, 'PEOPLEUSDT': 0.143, 'AXSUSDT': 0.15, 'ENJUSDT': 0.15, 'QTUMUSDT': 0.152, 'SHIBUSDT': 0.154, 'ZENUSDT': 0.154, 'BLZUSDT': 0.154, 'ANTUSDT': 0.155, 'XECUSDT': 0.155, 'CHZUSDT': 0.158, 'RUNEUSDT': 0.163, 'ENSUSDT': 0.165, 'LRCUSDT': 0.167, 'CHRUSDT': 0.168, 'IOTXUSDT': 0.174, 'TOMOUSDT': 0.176, 'ALGOUSDT': 0.177, 'EGLDUSDT': 0.177, 'ARUSDT': 0.178, 'LTCUSDT': 0.178, 'HNTUSDT': 0.18, 'LPTUSDT': 0.181, 'SOLUSDT': 0.183, 'ARPAUSDT': 0.184, 'BELUSDT': 0.184, 'ETCUSDT': 0.186, 'ZRXUSDT': 0.187, 'AAVEUSDT': 0.187, 'CVCUSDT': 0.188, 'STORJUSDT': 0.189, 'COTIUSDT': 0.19, 'CELOUSDT': 0.191, 'SANDUSDT': 0.191, 'ADAUSDT': 0.192, 'HBARUSDT': 0.194, 'DOTUSDT': 0.195, 'XLMUSDT': 0.195, 'AVAXUSDT': 0.206, 'ANKRUSDT': 0.207, 'MTLUSDT': 0.208, 'MANAUSDT': 0.209, 'CRVUSDT': 0.213, 'API3USDT': 0.221, 'IOSTUSDT': 0.227, 'XRPUSDT': 0.228, 'BATUSDT': 0.228, 'MKRUSDT': 0.229, 'MATICUSDT': 0.229, 'CTKUSDT': 0.233, 'ZILUSDT': 0.233, 'WOOUSDT': 0.234, 'ATOMUSDT': 0.237, 'KLAYUSDT': 0.239, 'XTZUSDT': 0.245, 'IMXUSDT': 0.278, 'NEARUSDT': 0.285, 'GALUSDT': 0.299, 'APEUSDT': 0.305, 'ZECUSDT': 0.309, 'KAVAUSDT': 0.31, 'GMTUSDT': 0.327, 'FTTUSDT': 0.366, 'KNCUSDT': 0.401, 'ETHUSDT': 0.416, 'XMRUSDT': 0.422, 'BTCUSDT': 0.47, 'BNBUSDT': 0.476, 'TRXUSDT': 0.507, 'BNXUSDT': 0.64}

Tout d’abord, nous utilisons le code le plus simple pour simuler une tendance à la baisse et voir les prix de liquidation de différentes valeurs de position. Étant donné que la stratégie maintient toujours des positions longues, il n’y a aucun risque de hausse. Le capital initial est de 1 000, le prix de la devise est de 1 et le taux d'ajustement est de 0,01. Les résultats sont les suivants. On peut constater que le risque de liquidation des positions longues n'est pas faible. Avec un effet de levier de 1,5 fois, il peut résister à une baisse de 50 %. Compte tenu de la situation actuelle, il s’agit d’un risque acceptable.

Valeur de positionPrix ​​de liquidation long
3000.035
5000.133
8000.285
10000.362
15000.51
20000.599
30000.711
50000.81
100000.904
python
for Hold_value in [300,500,800,1000,1500,2000,3000,5000,10000]: amount = Hold_value/1 hold_price = 1 margin = 1000 Pct = 0.01 i = 0 while margin > 0: i += 1 if i>500: break buy_price = (1-Pct)*Hold_value/amount buy_amount = Hold_value*Pct/buy_price hold_price = (amount * hold_price + buy_amount * buy_price) / (buy_amount + amount) amount += buy_amount margin = 1000 + amount * (buy_price - hold_price) print(Hold_value, round(buy_price,3))
300 0.035 500 0.133 800 0.285 1000 0.362 1500 0.51 2000 0.599 3000 0.711 5000 0.81 10000 0.904
python
#还是用原来的回测引擎 class Exchange: def __init__(self, trade_symbols, fee=0.0004, 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}} 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 for symbol in self.trade_symbols: 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)

Tout d’abord, nous testons rétrospectivement les performances de la stratégie d’équilibrage TRX. Le drawdown maximum de TRX dans cette phase de marché baissier est relativement faible, il présente donc certaines caractéristiques particulières. Les données sélectionnées sont la ligne K de 5 minutes de 2021 à ce jour, avec un capital initial de 1 000, un ratio d'ajustement de 0,01, une valeur de détention de 2 000 et des frais de traitement de 0,0002.

Le prix initial du TRX était de 0,02676 U, et le prix le plus élevé au cours de la période a atteint 0,18 U. Il se situe actuellement autour de 0,08 U, avec des fluctuations très violentes. Si vous exécutez la stratégie de grille long-short dès le début, vous vous retrouverez inévitablement avec une liquidation de position courte. Une stratégie équilibrée n’est pas un gros problème.

Le rendement final du backtest est de 4524U, ce qui est très proche du rendement de TRX à 0,18. L'effet de levier est inférieur à 2 fois au début et inférieur à 0,4 à la fin. La possibilité de liquidation est de plus en plus faible. Pendant cette période, la valeur des avoirs peut être augmentée. Chance. Mais les revenus inférieurs à 2000U restent inchangés. C’est aussi l’un des inconvénients de la stratégie équilibrée.

python
symbol = 'TRXUSDT' df_trx = GetKlines(symbol=symbol,start='2021-1-1',end='2022-5-30',period='5m')
python
df_trx.close.plot(figsize=(15,6),grid=True);

png

python
#TRX平衡策略回测 hold_value = 2000 pct = 0.01 e = Exchange([symbol], fee=0.0002, initial_balance=1000) init_price = df_trx.iloc[0].open res_list = [] #用于储存中间结果 e.Buy(symbol,init_price,hold_value/init_price) e.Update({symbol:init_price}) for row in df_trx.itertuples(): buy_price = (1-pct)*hold_value/e.account[symbol]['amount'] sell_price = (1+pct)*hold_value/e.account[symbol]['amount'] while row.low < buy_price: e.Buy(symbol,buy_price,pct*hold_value/buy_price) e.Update({symbol:row.close}) buy_price = (1-pct)*hold_value/e.account[symbol]['amount'] sell_price = (1+pct)*hold_value/e.account[symbol]['amount'] while row.high > sell_price: e.Sell(symbol,sell_price,pct*hold_value/sell_price) e.Update({symbol:row.close}) buy_price = (1-pct)*hold_value/e.account[symbol]['amount'] sell_price = (1+pct)*hold_value/e.account[symbol]['amount'] if int(row.time)%(60*60*1000) == 0: e.Update({symbol:row.close}) res_list.append([row.time, row.close, e.account[symbol]['amount'],e.account[symbol]['amount']*row.close, e.account['USDT']['total']-e.initial_balance]) res_trx = pd.DataFrame(data=res_list, columns=['time','price','amount','value','profit']) res_trx.index = pd.to_datetime(res_trx.time,unit='ms') print(pct,e.account['USDT']['realised_profit']+e.account['USDT']['unrealised_profit'] ,round(e.account['USDT']['fee'],0))
0.01 4524.226998288555 91.0
python
#收益 res_trx.profit.plot(figsize=(15,6),grid=True);

png

python
#实际占用杠杆 (res_trx.value/(res_trx.profit+1000)).plot(figsize=(15,6),grid=True);

png

Testons à nouveau WAVES. Cette cryptomonnaie est assez spéciale. Elle est passée de 6U au début à un sommet de 60U, pour finalement retomber au niveau actuel de 8U. Le bénéfice final est de 4945, ce qui est bien supérieur au bénéfice réalisé en détenant les pièces.

python
symbol = 'WAVESUSDT' df_waves = GetKlines(symbol=symbol,start='2021-1-1',end='2022-5-30',period='5m')
python
df_waves.close.plot(figsize=(15,6),grid=True);

png

python
#TWAVES平衡策略回测 hold_value = 2000 pct = 0.01 e = Exchange([symbol], fee=0.0002, initial_balance=1000) init_price = df_waves.iloc[0].open res_list = [] #用于储存中间结果 e.Buy(symbol,init_price,hold_value/init_price) e.Update({symbol:init_price}) for row in df_waves.itertuples(): buy_price = (1-pct)*hold_value/e.account[symbol]['amount'] sell_price = (1+pct)*hold_value/e.account[symbol]['amount'] while row.low < buy_price: e.Buy(symbol,buy_price,pct*hold_value/buy_price) e.Update({symbol:row.close}) buy_price = (1-pct)*hold_value/e.account[symbol]['amount'] sell_price = (1+pct)*hold_value/e.account[symbol]['amount'] while row.high > sell_price: e.Sell(symbol,sell_price,pct*hold_value/sell_price) e.Update({symbol:row.close}) buy_price = (1-pct)*hold_value/e.account[symbol]['amount'] sell_price = (1+pct)*hold_value/e.account[symbol]['amount'] if int(row.time)%(60*60*1000) == 0: e.Update({symbol:row.close}) res_list.append([row.time, row.close, e.account[symbol]['amount'],e.account[symbol]['amount']*row.close, e.account['USDT']['total']-e.initial_balance]) res_waves = pd.DataFrame(data=res_list, columns=['time','price','amount','value','profit']) res_waves.index = pd.to_datetime(res_waves.time,unit='ms') print(pct,e.account['USDT']['realised_profit']+e.account['USDT']['unrealised_profit'] ,round(e.account['USDT']['fee'],0))
0.01 4945.149323437233 178.0
python
df_waves.profit.plot(figsize=(15,6),grid=True);

png

Au fait, testons à nouveau les performances de la stratégie de grille. L'espacement de la grille est de 0,01 et la valeur de la grille est de 10. Avec une augmentation de près de 10 fois, WAVES et TRX ont tous deux connu d'énormes reculs, WAVES reculant de 5 000 U et TRX de plus de 3 000 U. Si le capital initial est faible, la position sera essentiellement liquidée.

python
#网格策略 pct = 0.01 value = 10*pct/0.01 e = Exchange([symbol], fee=0.0002, initial_balance=1000) init_price = df_waves.iloc[0].open res_list = [] #用于储存中间结果 for row in df_waves.itertuples(): buy_price = (value / pct - value) / (value / (pct * init_price) + e.account[symbol]['amount']) sell_price = (value / pct + value) / (value / (pct *init_price) + e.account[symbol]['amount']) while row.low < buy_price: e.Buy(symbol,buy_price,value/buy_price) e.Update({symbol:row.close}) buy_price = (value / pct - value) / (value / (pct * init_price) + e.account[symbol]['amount']) #买单价格,由于是挂单成交,也是最终的撮合价格= while row.high > sell_price: e.Sell(symbol,sell_price,value/sell_price) e.Update({symbol:row.close}) sell_price = (value / pct + value) / (value / (pct *init_price) + e.account[symbol]['amount']) if int(row.time)%(60*60*1000) == 0: e.Update({symbol:row.close}) res_list.append([row.time, row.close, e.account[symbol]['amount'],e.account[symbol]['amount']*row.close, e.account['USDT']['total']-e.initial_balance]) res_waves_net = pd.DataFrame(data=res_list, columns=['time','price','amount','value','profit']) res_waves_net.index = pd.to_datetime(res_waves_net.time,unit='ms') print(pct,e.account['USDT']['realised_profit']+e.account['USDT']['unrealised_profit'] ,round(e.account['USDT']['fee'],0))
0.01 1678.0516101975015 70.0
python
res_waves_net.profit.plot(figsize=(15,6),grid=True);

png

python
#网格策略 pct = 0.01 value = 10*pct/0.01 e = Exchange([symbol], fee=0.0002, initial_balance=1000) init_price = df_trx.iloc[0].open res_list = [] #用于储存中间结果 for row in df_trx.itertuples(): buy_price = (value / pct - value) / (value / (pct * init_price) + e.account[symbol]['amount']) sell_price = (value / pct + value) / (value / (pct *init_price) + e.account[symbol]['amount']) while row.low < buy_price: e.Buy(symbol,buy_price,value/buy_price) e.Update({symbol:row.close}) buy_price = (value / pct - value) / (value / (pct * init_price) + e.account[symbol]['amount']) while row.high > sell_price: e.Sell(symbol,sell_price,value/sell_price) e.Update({symbol:row.close}) sell_price = (value / pct + value) / (value / (pct *init_price) + e.account[symbol]['amount']) if int(row.time)%(60*60*1000) == 0: e.Update({symbol:row.close}) res_list.append([row.time, row.close, e.account[symbol]['amount'],e.account[symbol]['amount']*row.close, e.account['USDT']['total']-e.initial_balance]) res_trx_net = pd.DataFrame(data=res_list, columns=['time','price','amount','value','profit']) res_trx_net.index = pd.to_datetime(res_trx_net.time,unit='ms') print(pct,e.account['USDT']['realised_profit']+e.account['USDT']['unrealised_profit'] ,round(e.account['USDT']['fee'],0))
0.01 -161.06952570521656 37.0
python
res_trx_net.profit.plot(figsize=(15,6),grid=True);

png

Résumer

Cette analyse de backtest a utilisé une ligne K de 5 minutes et les fluctuations au milieu n'ont pas été entièrement simulées, de sorte que le rendement réel devrait être légèrement supérieur. En général, la stratégie équilibrée comporte des risques relativement faibles, n'a pas peur de monter en flèche, ne nécessite pas de réglage des paramètres, est relativement pratique à utiliser et convient aux utilisateurs novices. La stratégie de grille est très sensible à la fixation du prix initial et nécessite une certaine appréciation des conditions de marché. À long terme, le risque de vente à découvert est très élevé. Cette vague de marché baissier est restée stable au plus bas pendant un certain temps. De nombreuses pièces ont chuté de plus de 90 % par rapport à leurs sommets. Si vous êtes optimiste à propos de certaines pièces, c'est le bon moment pour entrer sur le marché. Vous souhaiterez peut-être Commencez une stratégie équilibrée pour acheter au plus bas. Ajoutez un peu d'effet de levier pour profiter de la volatilité et des hausses de prix.
Cette guerre des mille groupes Binance offrira une utilisation gratuite de la stratégie d'équilibre perpétuel, et tout le monde est invité à en faire l'expérience.

Related Recommendations
Comment
All comments (7)

    使用策略一定比持币不动更优吗?

    4 years ago

    每种策略都是在特定场景下有效,平衡策略是逆趋势策略,持币不动约等于不加仓不补仓杠杆为本金的顺趋势策略

    4 years ago

    怎么加入你们的千团大战?又如何使用你们的这个策略?

    4 years ago

    币安千团大战的策略在哪里呀?

    4 years ago

    美元加息缩表大背景下,加密货币市场还会处于熊市状态一段时间吧,这样的话最近半年内,像TRX、ETH这种是不是继续用网格收益率会高一些呢?

    4 years ago

    本文的缺点是没办法计算资费,长期持有的情况下,资费影响巨大!牛是资费通常为正,也就是说持有多仓会缴费,而且缴很多!而熊市反之。

    4 years ago

    牛逼

    4 years ago
  • 1
Forums
PINE Language
Get the app
iPhone Download
© 2015 - ∞ INVENTOR PTE LTD (SG)