Eth_algotrader
Eth_algotrader личный блог
Сегодня в 17:21

Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)

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

Первые 90 дней торговли:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)

Следующие 20 дней:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)

Результат по этому мониторингу: 
75% прибыли (на пике 90%) с просадкой 28% (по эквити) за 112 дней

AUM до закрытия счета 56 000$:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)

Общий результат с начала торговли по этому + предыдущему мониторингу на Бинансе:
114% прибыли (на пике 133%) при макс. просадке 28% (по эквити) за 8 месяцев:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)

Но так ли он хорош по сравнению с крипто-рынком? Чтобы выяснить это, напишем скрипт на python (код в конце), который построит график PnL, в %, прибыли робота, и сравнит его с графиками PnL, тоже в %, прибыли основных крипто-монет с момента первой сделки робота. Как если бы мы сравнивали, какую прибыль принесет одна и та же сумма, вложенная в алгоритм или в крипту.

Выгрузим историю позиций из раздела copy trading ЛК Binance:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)

Сохраним в файл csv и запустим скрипт. Для начала на торгуемом активе, ETHUSD:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)
Разница в прибыли очевидна. Эфир принес убыток в 20% за тот же период. В верхней части графика также выводятся для сравнения макс. просадки (по балансу), которые тоже сильно отличаются. Чтобы сравнить с другим инструментом, изменим значение переменной ticker в строке 43:
"""качаем с йаху дневки Эфира"""
ticker='ETH-USD'
Посмотрим на Биткоин:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)
Он ведет себя уже лучше, заканчивая период с некоторой прибылью. И даже макс просадка похожа. 

Солана чуть посильнее, но и просадка выше:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)
Рассмотрим более мелкую альту, на которую многие ставили этой весной в ожидании «альтсезона». Она должна была хорошо вырасти. Polkadot не оправдал ожиданий:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)
ATOM (Cosmos) еще хуже:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)
Aptos, на который многие надеялись, смог на некоторое время переиграть стратегию, но это длилось недолго. Его тикер 'APT21794-USD'. Чтобы найти его и другие мелкие токены, ищите «APT-USD» в поиске тикеров yahoo:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)
Stark, который активно продвигался многими инфлюэнсерами и собрал большую базу инвесторов. Без комментариев:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)
Среди популярных монет есть и более сильные, например AAVE дает всего лишь в 2 раза меньшую доходность. Правда при в 2 раза большей просадке:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)
Среди популярных монет находится все же и такая, которая смогла переиграть стратегию. TON:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)
Но следует обратить внимание на существенную разность просадок. Чтобы честно сравнить результативность, следует нормировать риски, приведя все просадки к одной. Для этого раскомментируем строки 60-68, где уже подобран нужный для этого мультипликатор риска стратегии (2.8):
"""нормировка риска по бенчмарку"""
riskmult=2.8 #cr.DDmaxPercTicker.max()/br.DDmaxPerc.max()  #мультипликатор риска стратегии для равенства просадки с бенчмарком
bAdj=pd.DataFrame(index=sr.index)
bAdj['PNLcum']=riskmult*sr['PNLwFee'].cumsum()
bAdj['PNLpercStrategyAdj']=bAdj['PNLcum']*100/startbal
bAdj['Balance']=bAdj['PNLcum']+startbal
bAdj['BalanceMax']=bAdj.Balance.cummax()
bAdj['DDmax']=(bAdj.BalanceMax-bAdj.Balance).cummax()
bAdj['DDmaxPerc']=((bAdj.BalanceMax-bAdj.Balance)*100/bAdj.BalanceMax).cummax()
sr=bAdj  #если надо скорректировать риск по стратегии
И вместо строки 73 (закомментируем) воспользуемся строкой 74 (раскомментируем), чтобы вывести нормированную по риску эквити стратегии:
# cr[['PNLpercStrategy']].plot(figsize=(14, 8), lw=3, grid=True, ax=ax, color='blue')
bAdj[['PNLpercStrategyAdj']].plot(figsize=(14, 8), lw=3, grid=True, ax=ax, color='blue')    #для нормированной по риску стратегии
Вот она:
Сравниваем 8 месяцев алго на крипте с лидерами рынка (python скрипт inside)
Как видим, при равенстве просадок доходность стратегии оказалась примерно в 2 раза больше.

***

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

Торговать продолжаем на приватном счете Binance и приватном счете Bybit с вайт-листом для инвесторов. Доступ на оба счета осуществляется в частном порядке по ссылкам-приглашениям. Все подробности в ЛС.

Далее привожу полный код скрипта на python 3.12:
import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt

br=pd.read_csv('real deals 24.02-13.10.24.csv', delimiter=',')

""""преобразования типов"""
br['Entry Price']=pd.to_numeric(br['Entry Price'].str.strip(to_strip='USDT'))
br['Closing PNL']=pd.to_numeric(br['Closing PNL'].str.strip(to_strip='USDT'))
br['Max. Open Interest']=pd.to_numeric(br['Max. Open Interest'].str.strip(to_strip='ETH'))
br['Opened']=pd.to_datetime(br['Opened'])
br['Closed']=pd.to_datetime(br['Closed'])

"""считаем кривые баланса и ПнЛ"""
comiss=0.001
startbal=7411
br['Fee']=br['Entry Price']*br['Max. Open Interest']*comiss
br['PNLwFee']=br['Closing PNL']-br['Fee']
br['PNLcum']=br['PNLwFee'].cumsum()
br['PNLperc']=br['PNLcum']*100/startbal
br['Balance']=br['PNLcum']+startbal
br['BalanceMax']=br.Balance.cummax()
br['DDmax']=(br.BalanceMax-br.Balance).cummax()
br['DDmaxPerc']=((br.BalanceMax-br.Balance)*100/br.BalanceMax).cummax()

"""добавляем в начало строку со стартовыми значениями баланса и PnL"""
startrow=pd.DataFrame(data={'PNLwFee': 0, 'PNLcum': 0, 'PNLperc': 0, 'Balance': startbal, 'Closed': br.Opened[0]-pd.Timedelta('2d')}, index=[0])
sr=pd.concat([startrow, br], ignore_index=True)
sr.set_index(sr.Closed, inplace=True)

"""рисуем"""
sr.Balance.plot(figsize=(14, 8))
sr.PNLcum.plot(figsize=(14, 8))
sr.PNLperc.plot(figsize=(14, 8))

"""качаем с йаху дневки Эфира"""
ticker='ETH-USD'
eth=yf.download(ticker, start=sr.index[0], end=sr.index[sr.index.size-1])
eth.Close.plot(figsize=(14, 8))
""""PnL Эфира по дневкам"""
eth['PNLperc'+ticker]=eth.Close*100/eth.Close[0]-100
eth['PNLperc'+ticker].plot(figsize=(14, 8))
eth['CloseMax']=eth.Close.cummax()
eth['DDmaxPercTicker']=((eth.CloseMax-eth.Close)*100/eth.CloseMax).cummax()
eth[['Close', 'CloseMax', 'DDmaxPercTicker']].plot()

"""складываем PnL робота по дням и соединяем с PnL Эфира по дням"""
cr=eth.join(sr.PNLwFee.groupby(sr.index.date).sum(), how='outer')
cr.PNLwFee.fillna(0, inplace=True)
cr['PNLcum']=cr.PNLwFee.cumsum()
cr['PNLpercStrategy']=cr.PNLcum*100/startbal

"""нормировка риска по бенчмарку"""
# riskmult=2.8 #cr.DDmaxPercTicker.max()/br.DDmaxPerc.max()  #мультипликатор риска стратегии для равенства просадки с бенчмарком
# bAdj=pd.DataFrame(index=sr.index)
# bAdj['PNLcum']=riskmult*sr['PNLwFee'].cumsum()
# bAdj['PNLpercStrategyAdj']=bAdj['PNLcum']*100/startbal
# bAdj['Balance']=bAdj['PNLcum']+startbal
# bAdj['BalanceMax']=bAdj.Balance.cummax()
# bAdj['DDmax']=(bAdj.BalanceMax-bAdj.Balance).cummax()
# bAdj['DDmaxPerc']=((bAdj.BalanceMax-bAdj.Balance)*100/bAdj.BalanceMax).cummax()
# sr=bAdj  #если надо скорректировать риск по стратегии

""""рисуем Стратегия VS бенчмарк"""
fig, ax = plt.subplots()
cr[['PNLperc'+ticker]].plot(figsize=(14, 8), lw=2, grid=True, ax=ax, color='orange')
cr[['PNLpercStrategy']].plot(figsize=(14, 8), lw=3, grid=True, ax=ax, color='blue')
# bAdj[['PNLpercStrategyAdj']].plot(figsize=(14, 8), lw=3, grid=True, ax=ax, color='blue')    #для нормированной по риску стратегии
plt.text(x=cr.index[(int)(cr.index.size/3)], y=cr.PNLpercStrategy.max()-10, size=16, s='Strategy DD=%.1f%%\n' % sr.DDmaxPerc.max()+ticker+' DD=%.1f%%' % cr.DDmaxPercTicker.max())
0 Комментариев

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн