В процессе загрузки ресурсов... загрузка...

Система высокочастотного обратного теста на основе каждой транзакции и недостатков обратного теста K-линии

Автор:Доброта, Создано: 2020-06-16 10:30:19, Обновлено: 2023-11-01 20:26:21

img

Когда я писалИсследование стратегии хеджирования в нескольких валютах на фьючерсах Binance, Я также выпустил движок обратного теста. И первый отчет был основан на одночасовом обратном тесте K-линии, который подтвердил эффективность стратегии. Но время сна фактической стратегии с открытым исходным кодом составляет 1 секунда, что является довольно высокочастотной стратегией. Очевидно, что использование обратного теста K-линии в течение часа не может дать точных результатов. Позже были добавлены результаты обратного теста минутной линии K, и доход от обратного теста значительно улучшился, но до сих пор невозможно определить, какие параметры следует использовать в случае секундного уровня, и понимание всей стратегии не очень ясно. Основной причиной является важный недостаток обратного теста на основе K-линии.

Проблемы, основанные на обратном тесте K-линии

Прежде всего, что такое историческая линия K? Данные K-линии содержат четыре цены: высокая, открытая, низкая, близкая, первые два times и объем интервала. Большинство платформ и рамок квантования основаны на обратном тесте K-линии, а платформа FMZ также предоставляет обратный тест уровня тика. Скорость обратного теста K-линии очень быстрая, и в большинстве случаев у нее очень мало проблем, но у нее также есть очень серьезные дефекты, особенно многообразная стратегия обратного теста и стратегия высокой частоты, почти невозможно сделать правильный вывод.

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

Представьте, что вы используете линию минутового уровня K для обратного тестирования арбитража двух сортов. Разница между ними обычно составляет 10 юаней ((или долларов). Теперь, в 10:01, цена закрытия контракта А составляет 100, контракт В - 112, а разница составляет 12 юаней. Таким образом, стратегия начинает хеджироваться. В определенный момент разница в цене возвращается, и стратегия получает прибыль в размере 2 юаней.

но фактическая ситуация может быть такая, что в 10:00:45, контракт А произвел транзакцию в 100 юаней, после чего не было никакой транзакции, контракт В имел транзакцию в 112 юаней в 10:00:58, в 10:01:00 Обе цены не существуют. Какая рыночная цена в это время, и сколько может получить хеджирующая операция? Я не могу знать. Одна из возможных ситуаций: в 10:00:58, цена Buy 1 и Sell 1 ожидающего заказа контракта А101.9до102.1Это сильно обманет нашу стратегию оптимизации.

Второй - это проблема сопоставления. Реальный сопоставление - это приоритет цены и приоритет времени. Если покупатель превышает цену Продажа 1, он обычно будет напрямую торговать по цене Продажа 1, в противном случае он будет вводить ожидаемую книгу заказов и ждать.

Последний - это влияние самой стратегии на рынок. Если это бэкстест небольших сумм средств, влияние не большое. Но если объем транзакций большой, то это повлияет на рынок. Не только ценовой сдвиг будет большим, когда вы размещаете большой объем ордера, если вы покупаете длинный ордер, выполненный, этот вид действия на самом деле захватить заказы других трейдеров, которые изначально хотели купить, эффект Butterfly окажет влияние на рынок. Этот эффект не может быть количественно определен. Мы можем только сказать по опыту, что высокочастотная торговля может вместить только небольшие средства.

Обратный тест на основе глубины и тика в реальном времени

FMZ обеспечивает реальный уровень backtest, который может получить реальные исторические20 layer depth price, в режиме реального времени второго уровняTicks, Each Individual TransactionНа основе этих функций FMZ создал функцию воспроизведения транзакций в реальном времени.

Такой объем данных обратного теста очень большой, а скорость обратного теста также очень медленная, обычно можно проводить обратный тест только в течение двух дней. Для относительно высокочастотных или критических по времени стратегий необходим реальный обратный тест на уровне рынка.

В настоящее время механизм соответствия заключается в том, что если заказ на покупку больше Sell 1, он будет полностью соответствовать немедленно, не смотря на сумму, а если он меньше Sell 1, он войдет в очередь для соответствия, чтобы ждать. Такой механизм обратного теста решает первые две проблемы K-линейного обратного теста, но все еще не может решить последнюю проблему. И поскольку количество данных слишком велико, скорость обратного теста и временной диапазон ограничены.

img

Механизм обратного тестирования, основанный на потоке транзакций по каждому заказу

В K-линии слишком мало информации, и глубина цены также может быть фальшивой глубиной, но есть тип данных, которые являются реальной готовностью рынка к транзакциям, которая отражает самую реальную историю транзакций, то естьEach Individual TransactionВ этой статье будет предложена высокочастотная система обратного теста, основанная на потоке заказов, которая значительно уменьшит объем данных обратного теста на реальном рынке и в определенной степени смоделирует влияние объема торговли на рынок.

Я загрузил транзакцию последних 5 дней Binance XTZ вечный контракт (адрес загрузки:https://www.fmz.com/upload/asset/1ff487b007e1a848ead.csv), как не популярный сорт, он имеет в общей сложности 213000 данных о транзакциях, сначала давайте посмотрим на состав данных:

[['XTZ', 1590981301905, 2.905, 0.4, 'False\n'],
 ['XTZ', 1590981303044, 2.903, 3.6, 'True\n'],
 ['XTZ', 1590981303309, 2.903, 3.7, 'True\n'],
 ['XTZ', 1590981303738, 2.903, 238.1, 'True\n'],
 ['XTZ', 1590981303892, 2.904, 0.1, 'False\n'],
 ['XTZ', 1590981305250, 2.904, 0.1, 'False\n'],
 ['XTZ', 1590981305643, 2.903, 197.3, 'True\n'],

Данные представляют собой двумерный список, сортированный в хронологическом порядке. Конкретные значения следующие: название сорта, цена сделки, временная марка сделки, количество сделки, является ли это активной сделкой с продажным заказом. Существуют стороны покупки и продажи, и каждая сделка включает в себя покупателя и продавца. Если покупатель является рынкомMakerи продавец является активнымTaker, последние данныеTrue.

Во-первых, в зависимости от направления сделки вы можете достаточно точно спекулировать на Buy 1 и Sell 1 на рынке. Если это активный ордер продажи, то цена Buy 1 в это время является ценой сделки, если это активный ордер покупки, то цена Sell 1 будет ценой сделки. Если есть новая сделка, то вся цена будет обновлена и обновлена. Последний результат будет сохранен, если нет обновления и обновления. Легко представить последний момент вышеперечисленных данных, цена Buy 1 составляет 2.903, а цена Sell 1 составляет 2.904.

Согласно потоку заказов, он может быть сопоставлен следующим образом: возьмите заказ на покупку в качестве примера, ценаprice, количество заказа:amount, то купить и продать 1 в это времяbidиaskсоответственно.priceнижеaskи вышеbid, то он оценивается какmakerпервое, и приоритет может быть совпадает, чтобы сделать сделку, то все сделки с ценой сделки ниже или равнаpriceвремя существования заказа будет совпадать с этим заказом (еслиpriceменьше или равноbid, не приоритетность данной сделки.priceсовпадают с этим порядком.)

Соответствующая цена:price, а объем - объем транзакцийEach Individual Transaction, пока заказ не будет полностью завершен или пока заказ не будет отменен.ask, оно оценивается какtakerПосле этого, в течение времени, когда ордер существует, все сделки с ценой транзакции ниже или равнаpriceсовпадают с этим заказом, и цена совпадения - это цена сделкиEach Individual TransactionРазличие междуmakerиtakerДля высокочастотных стратегий необходимо учитывать эту разницу.

Это легко увидеть проблему с этим типом соответствия.taker, фактическая ситуация заключается в том, что он может быть выполнен немедленно, а не ждать, пока новый заказ будет совпадать с ним. Во-первых, мы не рассматривали объем ожидающих заказов, даже если есть некоторые данные, непосредственно судить сделка также изменила глубину цены, влияя на рынок.

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

Есть еще некоторые мелкие детали. Если цена покупки заказа равна Buy 1, все еще существует определенная вероятность того, что цена покупки будет соответствовать Buy 1, такая ситуация здесь не будет рассматриваться.

Соответствующий код

Объекты обмена могут относиться к введению в начале, в основном неизменным, только добавляя разницу междуmakerиtakerВ следующем разделе в основном будет представлен код совпадения.

 symbol = 'XTZ'
    loop_time = 0
    intervel = 1000 # The sleep time of the strategy is 1000ms
    init_price = data[0][2] # Initial price
    e = Exchange([symbol],initial_balance=1000000,maker_fee=maker_fee,taker_fee=taker_fee,log='') # Initialize the exchange
    depth = {'ask':data[0][2], 'bid':data[0][2]} # depth
    order = {'buy':{'price':0,'amount':0,'maker':False,'priority':False,'id':0},
             'sell':{'price':0,'amount':0,'maker':False,'priority':False,'id':0}} # order
    for tick in data:
        price = int(tick[2]/tick_sizes[symbol])*tick_sizes[symbol] # executed price
        trade_amount = tick[3] # executed volume
        time_stamp = tick[1] # executed timestamp
        if tick[4] == 'False\n':
            depth['ask'] = price
        else:
            depth['bid'] = price
        
        if depth['bid'] < order['buy']['price']:
            order['buy']['priority'] = True
        if depth['ask'] > order['sell']['price']:
            order['sell']['priority'] = True
        if price > order['buy']['price']:
            order['buy']['maker'] = True
        if price < order['sell']['price']:
            order['sell']['maker'] = True
        
        # Order network delay can also be used as one of the matching conditions, not considered here
        cond1 = order['buy']['priority'] and order['buy']['price'] >= price and order['buy']['amount'] > 0
        cond2 = not order['buy']['priority'] and order['buy']['price'] > price and order['buy']['amount'] > 0
        cond3 = order['sell']['priority'] and order['sell']['price'] <= price and order['sell']['amount'] > 0
        cond4 = not order['sell']['priority'] and order['sell']['price'] < price and order['sell']['amount'] > 0

        if cond1 or cond2:
            buy_price = order['buy']['price'] if order['buy']['maker'] else price
            e.Buy(symbol, buy_price, min(order['buy']['amount'],trade_amount), order['buy']['id'], order['buy']['maker'])
            order['buy']['amount'] -= min(order['buy']['amount'],trade_amount)
            e.Update(time_stamp,[symbol],{symbol:price})
        if cond3 or cond4:
            sell_price = order['sell']['price'] if order['sell']['maker'] else price
            e.Sell(symbol, sell_price, min(order['sell']['amount'],trade_amount), order['sell']['id'], order['sell']['maker'])
            order['sell']['amount'] -= min(order['sell']['amount'],trade_amount)
            e.Update(time_stamp,[symbol],{symbol:price})

        if time_stamp - loop_time > intervel:
            order = get_order(e,depth,order) # Trading logic, not given here
            loop_time += int((time_stamp - loop_time)/intervel)*intervel

Некоторые детали:

  • Когда происходит новая сделка, мы должны сначала сопоставить заказ, а затем разместить заказ по последней цене.

  • Каждый заказ имеет два атрибута: makerнезависимо от того, является ли он maker, prioritymatching priority, например, buy order, когда цена покупки меньше Sell 1, он отмечается какmaker, а когда цена покупки больше Buy 1, она отмечается какPriority matching, priorityопределяет, равна ли цена покупке или нет, а производитель определяет комиссию за транзакцию.

  • ВmakerиpriorityЕсли большая покупка была размещена и превышает рыночную емкость.maker.

  • СтратегияintervalЭто может означать задержку на рынке.

Обратная проверка стратегии сети

Наконец, это фактический этап обратного теста. Давайте проверим одну из самых классических стратегий сетки здесь, чтобы увидеть, можем ли мы достичь ожидаемых результатов. Принцип стратегии заключается в том, что каждый раз, когда цена повышается на 1%, мы держим короткий заказ определенного значения (наоборот, мы держим длинный заказ), рассчитываем заказ покупки и продажи заранее. Я не покажу вам исходный код.Grid('XTZ', 100, 0.3, 1000, maker_fee=-0.00002, taker_fee=0.0003)функция, параметры: торговая пара, цена отклоняется от стоимости хранения на 1%, плотность ожидаемых заказов составляет 0,3%, интервал снаms, отсроченные сборы за заказы и сборы за исполненные заказы.

Рыночная цена XTZ была в шоке в течение последних 5 дней, что очень подходит для сетей.

img

Сначала мы проверяем влияние различных позиций на доходность. Доходность, проверенная традиционным механизмом, определенно увеличится пропорционально увеличению позиций.

e1 = Grid('XTZ',100,0.3,1000,maker_fee=-0.00002,taker_fee=0.0003)
print(e1.account['USDT'])
e2 = Grid('XTZ',1000,0.3,1000,maker_fee=-0.00002,taker_fee=0.0003)
print(e2.account['USDT'])
e3 = Grid('XTZ',10000,0.3,1000,maker_fee=-0.00002,taker_fee=0.0003)
print(e3.account['USDT'])
e4 = Grid('XTZ',100000,0.3,1000,maker_fee=-0.00002,taker_fee=0.0003)
print(e4.account['USDT'])

В общей сложности были проведены четыре группы обратных тестов, значение позиций держания составило 100, 1000, 10000, 100 000, а общее время обратных тестов составило 1,3 с. Результаты следующие:

{'realised_profit': 28.470993031132966, 'margin': 0.7982662957624465, 'unrealised_profit': 0.0104554474048441, 'total': 10000028.481448, 'leverage': 0.0, 'fee': -0.3430967859046398, 'maker_fee': -0.36980249726699727, 'taker_fee': 0.026705711362357405}
{'realised_profit': 275.63148945320177, 'margin': 14.346335829979132, 'unrealised_profit': 4.4382117331794045e-14, 'total': 10000275.631489, 'leverage': 0.0, 'fee': -3.3102045933457784, 'maker_fee': -3.5800688964477048, 'taker_fee': 0.2698643031019274}
{'realised_profit': 2693.8701498889504, 'margin': 67.70120400534114, 'unrealised_profit': 0.5735269329348516, 'total': 10002694.443677, 'leverage': 0.0001, 'fee': -33.984021415250744, 'maker_fee': -34.879233866850974, 'taker_fee': 0.8952124516001403}
{'realised_profit': 22610.231198585603, 'margin': 983.3853688758861, 'unrealised_profit': -20.529965947304365, 'total': 10022589.701233, 'leverage': 0.002, 'fee': -200.87094000385412, 'maker_fee': -261.5849078470078, 'taker_fee': 60.71396784315319}

Можно видеть, что окончательная реализованная прибыль составляет соответственно 28,4%, 27,5%, 26,9% и 22,6% от стоимости позиции хранения. Это также соответствует фактической ситуации. Чем выше стоимость позиции хранения, чем выше стоимость ожидаемого ордера, тем больше вероятность, что произойдет частичная сделка, и чем меньше окончательная реализованная прибыль относительно суммы ожидаемого ордера.

img

Мы также можем проверить влияние различных параметров на доходы от бэкстеста, таких как плотность ожидаемых заказов, время сна, комиссия за транзакции и т. Д. Возьмем время сна в качестве примера, изменим его на 100 мс и сравним время сна с 1000 мс, чтобы увидеть прибыль.

{'realised_profit': 29.079440803790423, 'margin': 0.7982662957624695, 'unrealised_profit': 0.0104554474048441, 'total': 10000029.089896, 'leverage': 0.0, 'fee': -0.3703702128662524, 'maker_fee': -0.37938946377435134, 'taker_fee': 0.009019250908098965}

Это также иллюстрирует важность сетевой стратегии для размещения нескольких наборов заказов.

Подводя итог

Эта статья инновационно предлагает новую систему обратного теста, основанную на потоке заказов, которая может частично моделировать ситуацию совпадения ожидаемых заказов, исполняемых заказов, частично выполненных заказов, задержек и т. д., и частично отражает влияние суммы стратегии средств на доходы. Для высокочастотных и хеджирующих стратегий, У нее есть важное справочное значение. Высокоточный обратный тест указывает направление для оптимизации параметров стратегии. Он также проверен в течение длительного времени. Кроме того, количество данных, необходимых для обратного теста, хорошо контролируется, и скорость обратного теста также очень быстра.


Связанные

Больше