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% на высокочастотных и среднечастотных торгах, на долгосроке можно указать число и больше, каждый трейдер выбирает сам в зависимости от пары, опыта, фундаментального и технического анализа и т.п.


Реклама


Заключение

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


Это статья из цикла "Популярно о бирже"
Все статьи цикла:

Последнее изменение:

Не забудьте рассказать друзьям об этой статье.
Чтобы поддержать ресурс Bablofil достаточно просто поделиться с друзьями этой статьей в социальных сетях. Каждый репост - это самая высокая оценка качества материала. Спасибо, что читаете этот блог.



Комментарии
16.12.2018 03:19:20
Доброго времени суток, Андрей. У меня тут возникли два вопроса но уже не по предмету "программирование" как таковому, а по стратегии торговли:
1) А имеет ли вообще смысл выставления в сделках stop-loss`а если рынок подвержен таким колебаниям и проскальзываниям? и
2) Как реализовать в высокочастотной торговле механизм запрета сделок если скажем достигнут пик роста? Через количество минусовых сделок?
Проголосовать Проголосовать
0 0
16.12.2018 06:41:20
Добрый день,
На мой взгляд, стоп-лоссы в чистом виде - это кормушка для брокеров, и особого смысла в них нет.
Но именно плавающий стоп это немного другое, тут трейдер шансы в свою сторону тянет, и это может дать плоды в определенных ситуациях. Главное, понимать в каком случае использовать ту а в каком эту, но это вопрос опыта наверное.
И это неплохо с точки зрения автоматизации, если бот видит сигнал к пампу, например, то он может по быстрому закупить и постараться продать. Если сразу выставлять 0.5% прибыли, например, и стоп-лосс на 0.5% убытка, то бот будет получать от 0 до 0.5% в среднем (если сигналы качественные). Если использовать трейлинг, то бот сможет получать в несколько раз больше, и скидывать, когда отток денег превысил указанную черту..
На второй вопрос сложно ответить, если бы люди знали, что это пик, а это дно, биржа не была бы биржей. Вы навряд ли узнаете, убыточная ли чужая сделка, или нет. Но можете повысить свой шанс на распознавание пика с помощью комбинаций всевозможных индикаторов, или быть готовым скинуть с убытком что бы войти ниже, при грамотном матожидании это может оказаться прибыльной стратегией.
Проголосовать Проголосовать
0 0
15.01.2019 03:18:31
Привет.
Воспользовался Вашим ботом для binance - понравилось. Сейчас мучаю стоп-лосс и появились вопросы.
Если бот останавливается, то это не есть хорошо, т.к. продолжать надо торги. В связи с чем попытался написать продолжение скрипта на тему: если купил (по лонгу), то выставь купленное по цене покупки + профит. И так все по кругу.
Но я не программист и мне не хватает силенок это сделать. Нет ли у Вас желание довести скрипт до моего предложения?
Кстати, в процессе работы обнаружилась ошибка, при дешевом коине происходит закупка большого количества монет и по разным ордерам, в итоге идет некое несоответствие выделенной суммы на покупку и бот зацикливается с сообщением {'code': -2010, 'msg': 'Account has insufficient balance for requested action.'}. Попытался поставить условие на это сообщение, но не разобрался каким методом вызвать.
С наилучшими пожеланиями...
Проголосовать Проголосовать
0 0
17.01.2019 08:04:15
Добрый день!
Не совсем понял, какого скрипта?
Вы хотите, что бы скрипт из статьи покупал и продавал? Тогда адаптируйте бота, то он примерно так и работает - покупает и продает с наценкой.
Насчет ошибки - такое может быть, если комиссия у вас не в BNB, или в BNB но монеты BNB на балансе кончились, и биржа списывает комиссию с монет, которыми торгуете.
В этом случае рекомендую закупить BNB с запасом.
Проголосовать Проголосовать
0 0
24.01.2019 00:06:59
Доброй ночи. Опять всю ночь работал и криво выразился :)
Я хотел сказать, что бот для Binance мой первый бот, которым я воспользовался. И он мне открыл путь в мир ботов так сказать :)
Затем я попробовал trailing stop, и тоже он мне понравился, но моих знаний в программировании не хватает, чтобы после покупки trailing-stop'ом выставить на продажу купленное...
P.S. спасибо за Ваши выкладки. Они очень сильно помогают начинающим начать разбираться в этой "кухне" :)
Проголосовать Проголосовать
0 0
17.01.2019 14:02:39
Здравствуйте. Не могли бы вы написать эту функцию к боту для полоникса?
Проголосовать Проголосовать
0 0
14.04.2019 20:08:49
а в паре BNBBTC или BTCUSDT, при стратегии "Long" что за чем указывать??? у меня BNB не сработало, в ручную перепродал.
Проголосовать Проголосовать
0 0
14.04.2019 20:27:28
похоже разобрался, для разной цены % должен быть разным, но вопрос все равно в силе... правильно ли я расположил данные пары?
Проголосовать Проголосовать
0 0
15.04.2019 13:28:00
простите, а можно ещё пожелание???... можно ли оформить редактирование валютной пары, % и сумма купли\продажи в отдельный текстовый файл... проблематично в спешке искать нужные строчки и нужные позиции печати в спешка, когда это необходимо сделать быстро... что бы программа сама считывала из этого файла необходимые для работы значения... наверно будет удобнее размещать значения построчно, что бы путаницы не было и было наглядно... в таком де формате, валютная пара, %, цена... как вы относитесь к такому предложению?
Проголосовать Проголосовать
0 0
15.04.2019 13:29:02
упа...* не цена, конечно, а количество.
Проголосовать Проголосовать
0 0
18.04.2019 10:36:18
Здравствуйте,
Пары нужно писать так, как требует Binance, бот просто транслирует их, самому колдовать и переставлять не требуется.
Насчет текстового файла можно конечно, но вам все равно придется перезапускать бота после изменений, или переписывать код.
Если вам неудобно искать в редакторе, вы можете открывать код бота в Notepad++ например, править и искать там, это же обычный текстовый файл, который питон в дальнейшем разбирает и выполняет указанные в нём команды
Проголосовать Проголосовать
0 0
21.04.2019 17:54:53
ок... я извратился и сделал оболочку на делфи, делфи генерирует готовый питоновский файл с забитыми в делфи необходимыми данными и далее запускает файл питона, несколько дней тестил, всё работает...))) ну, через попу, но работает...
Проголосовать Проголосовать
1 0
07.07.2019 16:32:30
Здравствуйте, Андрей. Подскажите как исправить ошибку? В момент когда пора продавать, бот пишет что несовпадение времени сервера на 1000 мс.
Проголосовать Проголосовать
0 0
07.07.2019 17:29:50
timestamp for this request was 1000ms ahead of the server's time
Проголосовать Проголосовать
0 0
23.07.2019 10:38:41
День добрый.
А можно ли это всё запустить на Linux. В частности на VPS?
Проголосовать Проголосовать
0 0
Пожалуйста, авторизуйтесь, что бы оставить свой комментарий
Крипто-кошельки для помощи и благодарности проекту:

Bitcoin адрес проекта: [[address]]

Перевод на сумму [[value]] BTC получен. Спасибо!.
[[error]]

Ethereum адрес проекта: [[address]]