Trailing stop своими руками

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

Что такое trailing stop?

Глагол trail переводится с английского как «выслеживать», «идти по следу», «следовать за». В нашем случае, это словосочетание можно перевести как «плавающий стоп», термин обозначает процесс подтягивания стоп-лосса к растущему тренду (не реагируя на проседания курса). Рассмотрим процесс на примере.

Допустим, мы купили каких-то монет по курсу 98, и хотим продать их с прибылью. Сейчас курс 100, и мы могли бы уже получить прибыль, но мы рассчитываем получить больше. При этом, если курс вдруг начнет падать и упадет на 98 и ниже, мы немедленно продадим купленное, чтобы минимизировать убытки.

98 – текущая нижняя граница (stop loss). Мы будем её повышать каждый раз, когда разница текущего курса и нижней границы составит 5% *.

Так, при курсе 100 и курсе 103 разница с 98 составляет менее 5%, поэтому мы ничего не продаем и не повышаем. Как только цена превысит 104, мы подтягиваем нижнюю границу. Т.к. курс сейчас скакнул до 107 (см рисунок ниже), то нижняя граница составит уже 101.65. Текущий курс 107, но если упадет до 101.65, то мы продадим (но будем уже в плюсе). Разница между 107 и 101.65 составляет 5%, если курс вырастет выше, мы снова повысим.

Следующий шаг графика – курс 106. Цена упала, но нижнюю границу мы не двигаем на падении, меняем только на росте, stop loss остается 101.65. Цена скакнула до 110 – stop loss подтянулся до 104.5. Поднялась до 120  - stop loss стал 114. Упала до 115 – stop loss по прежнему 114, и т.п.

На графике ниже наглядно отображен график, синим отмечено движение цены, желтым – выбранный stop loss.

Да, изначально мы рассчитывали продать по 105, а продали по 116.85. Это выгодно, хотя выгоднее было бы продать по 123, максимальной цене на графике. Но если обратите внимание, то 123 после вычета выбранных 5% составит как раз 116.85, мы продали по максимальной цене за вычетом процента слежения.

Мы могли бы поставить скажем, 2%, но тогда мы не добрались бы до курса 123, т.к. курс колебался более чем на эти 2% вначале, например, когда со 120 упал до 115, и мы продали бы там, на первом резком падении.

Для игры на понижение та же ситуация применяется зеркально, при падении мы следуем за ним, при росте замораживаем. Стараемся купить как можно дешевле.

Все это хорошо в теории, но как применять на практике?

Бот для trailing stop (на примере Binance)

Что ж, такую стратегию можно применять руками –смотреть за курсом и продавать если он упадет низко. Если растет – держать кулачки. Но можно и запилить несложного бота, алгоритм-то простецкий. Вот такой:

Нам понадобится установленный питон версии 3.6 и выше, и установленный модуль requests (pip install requests в командной строке). Ниже я укажу ссылку на архив, в котором будет лежать код из статьи.

Код будет не сильно отличаться от картинки выше, вот он:

import sqlite3
import logging
import time
import os
import math

from datetime import datetime

Реклама:


from binance_api import Binance bot = Binance( API_KEY='', API_SECRET='' ) settings = dict( symbol='EOSBTC', # Пара для отслеживания strategy="Short", # Стратегия - Long (повышение), Short (понижение) stop_loss_perc = 0.5, # % оставания от цены stop_loss_fixed = 0, # Изначальный stop-loss, можно установить руками нужную сумму, потом бот подтянет. # Можно указать 0, тогда бот высчитает, возьмет текущую цену и применит к ней процент amount = 0.0015 # Кол-во монет, которое планируем продать (в случае Long) или купить (в случае Short) # Если указываем Long, то альты для продажи (Например, продать 0.1 ETH в паре ETHBTC) # Если Short, то кол-во, на которое покупать, например купить на 0.1 BTC по паре ETHBTC ) multiplier = -1 if settings['strategy'] == "Long" else 1 print("Получаем настройки пар с биржи") symbols = bot.exchangeInfo()['symbols'] step_sizes = {symbol['symbol']:symbol for symbol in symbols} for symbol in symbols: for f in symbol['filters']: if f['filterType'] == 'LOT_SIZE': step_sizes[symbol['symbol']] = float(f['stepSize']) while True: try: print('Проверяю пару {pair}, стратегия {strategy}'.format(pair=settings['symbol'], strategy=settings['strategy'])) # Получаем текущие курсы по паре current_rates = bot.depth(symbol=settings['symbol'], limit=5) bid=float(current_rates['bids'][0][0]) ask=float(current_rates['asks'][0][0]) # Если играем на повышение, то ориентируемся на цены, по которым продают, иначе на цены, по которым покупают curr_rate = bid if settings['strategy'] == "Long" else ask if settings['stop_loss_fixed'] == 0: settings['stop_loss_fixed'] = (curr_rate/100) * (settings['stop_loss_perc']*multiplier+100) print("Текущие курсы bid {bid:0.8f}, ask {ask:0.8f}, выбрана {cr:0.8f} stop_loss {sl:0.8f}".format( bid=bid, ask=ask, cr=curr_rate, sl=settings['stop_loss_fixed'] )) # Считаем, каким был бы stop-loss, если применить к нему % curr_rate_applied = (curr_rate/100) * (settings['stop_loss_perc']*multiplier+100) if settings['strategy'] == "Long": # Выбрана стратегия Long, пытаемся продать монеты как можно выгоднее if curr_rate > settings['stop_loss_fixed']: print("Текущая цена выше цены Stop-Loss") if curr_rate_applied > settings['stop_loss_fixed']: print("Пора изменять stop-loss, новое значение {sl:0.8f}".format(sl=curr_rate_applied)) settings['stop_loss_fixed'] = curr_rate_applied else: # Текущая цена ниже или равна stop loss, продажа по рынку res = bot.createOrder( symbol=settings['symbol'], recvWindow=15000, side='SELL', type='MARKET', quantity=settings['amount'] ) print('Результат создания ордера', res) if 'orderId' in res: # Создание ордера прошло успешно, выход break else: # Выбрана стратегия Short, пытаемся купить монеты как можно выгоднее if curr_rate < settings['stop_loss_fixed']: print("Текущая цена ниже stop-loss") if curr_rate_applied < settings['stop_loss_fixed']: print("Пора изменять stop-loss, новое значение {sl:0.8f}".format(sl=curr_rate_applied)) settings['stop_loss_fixed'] = curr_rate_applied else: # Цена поднялась выше Stop-Loss, Покупка по рынку quantity = math.floor((settings['amount']/curr_rate)*(1/step_sizes[settings['symbol']]))/(1/step_sizes[settings['symbol']]) print("Цена поднялась выше Stop-Loss, Покупка по рынку, кол-во монет {quantity:0.8f}".format(quantity=quantity)) # math.Floor(coins*(1/stepSize)) / (1 / stepSize) res = bot.createOrder( symbol=settings['symbol'], recvWindow=15000, side='BUY', type='MARKET', quantity=quantity ) print('Результат создания ордера', res) if 'orderId' in res: # Создание ордера прошло успешно, выход break except Exception as e: print(e) time.sleep(1) #print(bot.myTrades(symbol='PPTETH'))

Он использует файл binance_api.py из статьи «Работа с API Binance», он так же будет в прикрепленном архиве. Расскажу о настройках:

В случае игры на повышение, когда у вас есть купленные монеты, например EOS, и вы хотите продать его как можно выгоднее, нужно указать что то похожее:

 

symbol – пара, по которой будете играть. В данном случае, я бы хотел продать EOS так, что бы выручить BTC.

strategy – “Long” обозначает, что я хочу роста курса, и стоп-лосс будет всегда немного ниже его. “Short” – наоборот, я рассчитываю что курс будет падать и хочу купить как можно выгоднее.

stop_loss_perc – процент, на который StopLoss будет отставать от курса. Указывается как есть, например 5 – это 5%.

stop_loss_fixed – изначальный stop_loss, к которому будем привязываться. Вы можете там указать сразу цену, при достижении которой бот продаст монеты, если цена не будет расти, а будет изначально падать. Если укажете 0, то бот возьмет текущую цену, отнимет от неё процент, и будет ориентироваться на неё.

amount – кол-во монет для торгов. В случае стратегии Long указываете кол-во альтов для продажи, в случае Short – кол-во BTC, BNB, ETH или USDT, которое готовы потратить на покупку. В примере выше, я рассчитываю продать 2.67 EOS.

В примере выше бот будет пытаться продать 2.67 EOS, если цена будет расти то бот будет подтягивать нижнюю границу, если упадет ниже дозволенного, продаст монеты.

Вот другой пример:

Тут на 0.0015 BTC я рассчитываю купить столько EOS, сколько получится, если цена будет падать, бот будет следовать за ней, при росте цены сверх указанного произойдет покупка.

В любом случае после того, как ордер сработал, бот завершает работу.

Итак, порядок действий:

1. Установить python версии 3.6 или выше с официального сайта. Важно - при установке установите все флаги. Так же выберите режим customized и установите все "галочки" там.

2. Скачайте архив с ботом.  Распакуйте в любую папку.

3. Запустите там файл setup.bat. Установятся нужные модули.

4. Откройте в блокноте или другом текстовом редакторе файл "binance_tp.py", впишите свои API ключи в соответствующие поля. Если не знаете, как получить API ключи на Binance, читайте эту статью.

5. Выставьте настройки нужной пары и запустите run.bat - бот будет работать, пока не купит или не продаст.


* Примечание: число 5% выбрано для наглядности на графике, в жизни часто берут 1-2% на высокочастотных и среднечастотных торгах, на долгосроке можно указать число и больше, каждый трейдер выбирает сам в зависимости от пары, опыта, фундаментального и технического анализа и т.п.

Заключение

Подобный бот поможет немного разгрузить вас во время торговли. Различного рода идеи и предложения можем обсудить тут или в комментариях ниже. Удачной вам торговли )

Тэги: