Треугольное хеджирование.ipynb
В [1]:
var fmz = require("fmz") // Import the talib, TA, and plot libraries automatically after import.
var task = fmz.VCtx({
start: '2019-04-09 17:49:00',
end: '2019-04-09 18:00:00',
period: '1m',
exchanges: [{"eid":"Huobi","currency":"ETH_BTC", "balance":1, "stocks":10},{"eid":"OKEX","currency":"ETH_USDT","balance":10000,"stocks":1}, {"eid":"OKEX","currency":"BTC_USDT","balance":10000,"stocks":1}]
})
Отображение первоначальной информации об обменном счете:
В [2]:
var accA = exchanges[0].GetAccount()
accA
Выход[2]: { Баланс: 1, FrozenBalance: 0, Запасы: 10, FrozenStocks: 0 }
В [3]:
var accB = exchanges[1].GetAccount()
accB
Выход[3]: { Баланс: 10000, FrozenBalance: 0, Запасы: 1, FrozenStocks: 0 }
В [4]:
var accC = exchanges[2].GetAccount()
accC
Выход[4]: { Баланс: 10000, FrozenBalance: 0, Запасы: 1, FrozenStocks: 0 }
В [5]:
var initSumBTC = accA.Balance + accC.Stocks
initSumBTC
Выход[5]: 2.
В [6]:
var initSumETH = accA.Stocks + accB.Stocks
initSumETH
Выход[6]: 11.
В [7]:
var initSumUSDT = accB.Balance + accC.Balance
initSumUSDT
Выход[7]: 20000
Можно увидеть, что начальное общее количество BTC составляет 2, общее количество ETH составляет 11, а общее количество USDT составляет 20000.
В [8]:
var tickerA = exchanges[0].GetTicker()
tickerA
Вне[8]: { Время: 1554831960000, Высокий: 0,03396501, Низкий уровень: 0.03396499, Продай: 0.03396501, Купить: 0.03396499, Последнее: 0.033965, Объем: 4696,555, Открытый интерес:
В [9]:
var tickerB = exchanges[1].GetTicker()
tickerB
Выход[9]: { Время: 1554831960000, Высота: 175.08000001, Низкий показатель: 175,07999999, Продать: 175.08000001, Купить: 175.07999999, Последнее: 175,08, Объем: 20730.37, Открытый интерес:
В [10]:
var tickerC = exchanges[2].GetTicker()
tickerC
Выход[10]: Время: 1554831960000, Высокий: 5161,90000001, Низкий уровень: 5161,89999999, Продать: 5161.90000001, Купить: 5161.89999999, Последнее: 5161.9, Объем: 2109.9292, Открытый интерес:
Можно видеть, что предметом обмена A, Exchange B и транзакции является ETH, то есть, обмен A / B может проводить косвенные операции хеджирования, но они не могут прямым образом хеджироваться, потому что валюты ценообразования различны.
Предположим, что биржа А выполняет операцию покупкиexchanges[0].Buy(price, amount)
, и цена, проданная контрагентом, используется в качестве цены заказа при покупке, то естьtickerA.Sell
Биржа B выполняет операцию продажи для хеджирования, т.е.exchanges[1].Sell(price, amount)
, и цена, которую контрагент хочет купить, используется в качестве цены ордера при продаже, то естьtickerB.Buy
Потому что обмен A потребляетBTC
при покупке, и обмен B полученных USDT при продаже, обмен A нуждается в заменеUSDT
с BTC, чтобы компенсировать BTC, потребляемый биржей A, то есть, биржа C выполняетexchanges[2].Buy(price, amount)
, и обменUSDT
сBTC
Чтобы купить, биржа C должна увидеть цену продажи контрагента, то естьtickerC.Sell
. Покупная цена биржи A должна быть ниже продажной цены биржи B, тогда Exchange C может выкупить BTC, потребляемые Exchange A, с меньшим количеством USDT. Вы заработаете разницу в сумме USDT.
Так вот как:
В [11]:
var diffB2A = tickerA.Sell - tickerB.Buy / tickerC.Sell // diffB2A means that Exchange B sells ETH coins and Exchange A buys ETH coins, which is logically equivalent to the transfer of ETH from Exchange B to Exchange A.
diffB2A
Выход[11]: 0,000047266535449966285
Очевидно, что цена покупки биржи А выше, чем цена покупки биржи В и C, и хеджирование, очевидно, приносит убытки. Второе направление хеджирования то же самое. Биржа A выполняет операцию продажи ETH, Биржа B выполняет операцию покупки ETH, а Биржа C продает BTC за USDT. Достижение валюты всегда сбалансировано, и только USDT увеличивается или уменьшается (т.е. заработанная разница).
В [12]:
var diffA2B = tickerA.Buy - tickerB.Sell / tickerC.Buy
diffA2B
Выход[12]: 0,000047246531444007644
Давайте выполнимtickerA.Buy - tickerB.Sell / tickerC.Buy
операция хеджирования, чтобы узнать, как меняется каждая из ценностей.
В [13]:
var idA = exchanges[0].Sell(tickerA.Buy, 1)
var nowAccA = exchanges[0].GetAccount()
nowAccA // We can see that the fee is deducted from the BTC.
Выход[13]: { Остаток: 1,03389706, Замороженный баланс: 0, Запасы: 9, ФрозенСтокс: 0 }
В [14]:
var orderA = exchanges[0].GetOrder(idA)
orderA
Выход[14]:
{ Идентификатор: 1,
Цена: 0.03396499,
Сумма: 1,
Сумма сделки: 1,
Средняя цена: 0.03396499,
Тип: 1,
Сдвиг: 0,
Статус: 1,
Контракт тип:
В [15]:
var feeRatioA = 0.002 // The default fee for backtesting is 0.2%, i.e. 0.002.
var feeA = orderA.DealAmount * orderA.AvgPrice * feeRatioA // Exchange A trading fees, BTC denominated.
feeA
Выход[15]: 0,00006792998000000001
В [16]:
var idB = exchanges[1].Buy(tickerB.Sell, 1)
var nowAccB = exchanges[1].GetAccount()
nowAccB
Выход[16]: { Остаток: 9824.56983998, Замороженный баланс: 0, Запасы: 2, ФрозенСтокс: 0 }
В [17]:
var orderB = exchanges[1].GetOrder(idB)
orderB // We can see that the fee is deducted from the USDT.
Выход[17]:
{ Идентификатор: 1,
Цена: 175,08000001,
Сумма: 1,
Сумма сделки: 1,
Средняя цена: 175,08000001,
Тип: 0,
Сдвиг: 0,
Статус: 1,
ContractType:
В [18]:
var feeRatioB = 0.002
var feeB = orderB.DealAmount * orderB.AvgPrice * feeRatioB / tickerC.Last // B exchange fees, converted to BTC denomination.
feeB
Выход[18]: 0,00006783548693698057
В [19]:
var idC = exchanges[2].Sell(tickerC.Buy, nowAccA.Balance - accA.Balance)
var nowAccC = exchanges[2].GetAccount()
nowAccC
Выход[19]: { Остаток: 10174.12327555, Замороженный баланс: 0, Запасы: 0,9662, ФрозенСтокс: 0 }
В [20]:
var orderC = exchanges[2].GetOrder(idC)
orderC // We can see that the fee is deducted from the USDT.
Выход[20]:
{ Идентификатор: 1,
Цена: 5161.89999999,
Сумма: 0,0338,
Сумма сделки: 0,0338,
Средняя цена: 5161,89999999,
Тип: 1,
Сдвиг: 0,
Статус: 1,
Контракт тип:
В [21]:
var feeRatioC = 0.002
var feeC = orderC.DealAmount * orderC.AvgPrice * feeRatioC / tickerC.Last // Fees for C exchange transactions, BTC denominated.
feeC
Выход[21]: 0,00006759999999986903
Расчет общей информации об активах после хеджирования:
В [22]:
var nowSumBTC = nowAccA.Balance + nowAccC.Stocks
nowSumBTC
Выход[22]: 2.00009706
В [23]:
var nowSumETH = nowAccA.Stocks + nowAccB.Stocks
nowSumETH
Выход[23]: 11.
В [24]:
var nowSumUSDT = nowAccB.Balance + nowAccC.Balance
nowSumUSDT
Выход[24]: 19998.69311553
В [25]:
nowSumBTC - initSumBTC
Выход[25]: 0,00009705999999987114
В [26]:
tickerC.Buy * (nowSumBTC - initSumBTC) // Excess BTC converted to USDT
Выход[26]: 0,5010140139983642
В [27]:
nowSumUSDT + tickerC.Buy * (nowSumBTC - initSumBTC) - initSumUSDT // Profit and loss are calculated based on the movement of the account assets and both are denominated in USDT.
Выход[27]: - 0,8058704560025944 - 0,8058704560025944 - 0,8058704560025944 - 0,8058704560025944 - 0,805870454560025944 - 0,8058704545
В [28]:
(diffA2B - (feeA + feeB + feeC)) * tickerC.Buy // Profit and loss based on price difference, denominated in USDT.
Выход[28]: - 0,8058703331189396
Как мы видим, разница в цене при хеджировании равна диффА2Б: 0,000047246531444007644. Сборы за три хеджирования, конвертированные в BTC: feeA + feeB + feeC.
В [29]:
feeA + feeB + feeC
Выход[29]: 0,0002033654669368496
Можно заметить, что для такого треугольного хеджирования разница в ценах должна быть больше, чемfeeA+feeB+feeC
По крайней мере, это означает, что нет потерь, нет прибыли, и чтобы получить прибыль, она должна быть больше разницы в ценах.
В настоящее время, по сравнению с расчетами по счетам и расчетам разницы в ценах, это убыток.
Я изменил версию, так что сборы за обработку, рассчитанные с помощью параметра сборов за обработку, точно равны прибыли от разницы в ценах на рынке, испытанном этой моделью для сравнительного наблюдения.
Из этого следует, что при условии, что по умолчанию сборы за обработку (2 ‰ по умолчанию), когда разница хеджирования составляет 0,000047246531444007644 BTC, хеджирование является убытком, а убыток составляет около -0,8058704560025944.
Треугольное хеджирование (корректировка сборов за обработку).ipynb
В [1]:
var fmz = require("fmz") // Import talib, TA, plot libraries automatically after introduction.
var task = fmz.VCtx({
start: '2019-04-09 17:49:00',
end: '2019-04-09 18:00:00',
period: '1m',
exchanges: [{"eid":"Huobi","currency":"ETH_BTC", "balance":1, "stocks":10,"fee":[0.04,0.04]},{"eid":"OKEX","currency":"ETH_USDT","balance":10000,"stocks":1,"fee":[0.04,0.04]}, {"eid":"OKEX","currency":"BTC_USDT","balance":10000,"stocks":1,"fee":[0.04,0.04]}]
})
Отображение первоначальной информации об обменном счете и тикер:
В [2]:
var accA = exchanges[0].GetAccount()
accA
Выход[2]: { Баланс: 1, FrozenBalance: 0, Запасы: 10, FrozenStocks: 0 }
В [3]:
var accB = exchanges[1].GetAccount()
accB
Выход[3]: { Баланс: 10000, FrozenBalance: 0, Запасы: 1, FrozenStocks: 0 }
В [4]:
var accC = exchanges[2].GetAccount()
accC
Выход[4]: { Баланс: 10000, FrozenBalance: 0, Запасы: 1, FrozenStocks: 0 }
В [5]:
var initSumBTC = accA.Balance + accC.Stocks
initSumBTC
Выход[5]: 2.
В [6]:
var initSumETH = accA.Stocks + accB.Stocks
initSumETH
Выход[6]: 11.
В [7]:
var initSumUSDT = accB.Balance + accC.Balance
initSumUSDT
Выход[7]: 20000
Можно увидеть, что начальное общее количество BTC составляет 2, общее количество ETH составляет 11, а общее количество USDT составляет 20000.
В [8]:
var tickerA = exchanges[0].GetTicker()
tickerA
Вне[8]: { Время: 1554831960000, Высокий: 0,03396501, Низкий уровень: 0.03396499, Продай: 0.03396501, Купить: 0.03396499, Последнее: 0.033965, Объем: 4696,555, Открытый интерес:
В [9]:
var tickerB = exchanges[1].GetTicker()
tickerB
Выход[9]: { Время: 1554831960000, Высота: 175.08000001, Низкий показатель: 175,07999999, Продать: 175.08000001, Купить: 175.07999999, Последнее: 175,08, Объем: 20730.37, Открытый интерес:
В [10]:
var tickerC = exchanges[2].GetTicker()
tickerC
Выход[10]: Время: 1554831960000, Высокий: 5161,90000001, Низкий уровень: 5161,89999999, Продать: 5161.90000001, Купить: 5161.89999999, Последнее: 5161.9, Объем: 2109.9292, Открытый интерес:
Можно видеть, что предметом обмена A, Exchange B и транзакции является ETH, то есть, обмен A / B может проводить косвенные операции хеджирования, но они не могут прямым образом хеджироваться, потому что валюты ценообразования различны.
Предположим, что биржа А выполняет операцию покупкиexchanges[0].Buy(price, amount)
, и цена, проданная контрагентом, используется в качестве цены заказа при покупке, то естьtickerA.Sell
Биржа B выполняет операцию продажи для хеджирования, т.е.exchanges[1].Sell(price, amount)
, и цена, которую контрагент хочет купить, используется в качестве цены ордера при продаже, то естьtickerB.Buy
Потому что обмен A потребляетBTC
при покупке, и обмен B полученных USDT при продаже, обмен A нуждается в заменеUSDT
с BTC, чтобы компенсировать BTC, потребляемый биржей A, то есть, биржа C выполняетexchanges[2].Buy(price, amount)
, и обменUSDT
сBTC
Чтобы купить, биржа C должна увидеть цену продажи контрагента, то естьtickerC.Sell
. Покупная цена биржи A должна быть ниже продажной цены биржи B, тогда Exchange C может выкупить BTC, потребляемые Exchange A, с меньшим количеством USDT. Вы заработаете разницу в сумме USDT.
Так вот как:
В [11]:
var diffB2A = tickerA.Sell - tickerB.Buy / tickerC.Sell // DiffB2A means that Exchange B sells ETH coins and Exchange A buys ETH coins, which is logically equivalent to the transfer of ETH from Exchange B to Exchange A.
diffB2A
Выход[11]: 0,000047266535449966285
Очевидно, что цена покупки биржи А выше, чем цена покупки биржи В и C, и хеджирование, очевидно, приносит убытки. Второе направление хеджирования то же самое. Биржа A выполняет операцию продажи ETH, Биржа B выполняет операцию покупки ETH, а Биржа C продает BTC за USDT. Достижение валюты всегда сбалансировано, и только USDT увеличивается или уменьшается (т.е. заработанная разница).
В [12]:
var diffA2B = tickerA.Buy - tickerB.Sell / tickerC.Buy
diffA2B
Выход[12]: 0,000047246531444007644
Давайте выполнимtickerA.Buy - tickerB.Sell / tickerC.Buy
операция хеджирования, чтобы узнать, как меняется каждая из ценностей.
В [13]:
var idA = exchanges[0].Sell(tickerA.Buy, 1)
var nowAccA = exchanges[0].GetAccount()
nowAccA // We can see that the handling fee is deducted from the BTC.
Выход[13]: { Сальдо: 1,0339514, Замороженный баланс: 0, Запасы: 9, ФрозенСтокс: 0 }
В [14]:
var orderA = exchanges[0].GetOrder(idA)
orderA
Выход[14]:
{ Идентификатор: 1,
Цена: 0.03396499,
Сумма: 1,
Сумма сделки: 1,
Средняя цена: 0.03396499,
Тип: 1,
Сдвиг: 0,
Статус: 1,
Контракт тип:
В [15]:
var feeRatioA = 0.0004 // The default handling fee for backtesting is 0.2%, i.e. 0.002.
var feeA = orderA.DealAmount * orderA.AvgPrice * feeRatioA // Exchange A trading handling fees, BTC denominated.
feeA
Выход[15]: 0,000013585996
В [16]:
var idB = exchanges[1].Buy(tickerB.Sell, 1)
var nowAccB = exchanges[1].GetAccount()
nowAccB
Выход[16]: { Остаток: 9824.84996798, Замороженный баланс: 0, Запасы: 2, ФрозенСтокс: 0 }
В [17]:
var orderB = exchanges[1].GetOrder(idB)
orderB // We can see that the handling fee is deducted from the USDT.
Выход[17]:
{ Идентификатор: 1,
Цена: 175,08000001,
Сумма: 1,
Сумма сделки: 1,
Средняя цена: 175,08000001,
Тип: 0,
Сдвиг: 0,
Статус: 1,
ContractType:
В [18]:
var feeRatioB = 0.0004
var feeB = orderB.DealAmount * orderB.AvgPrice * feeRatioB / tickerC.Last // Exchange B handling fees, converted to BTC denomination.
feeB
Выход[18]: 0,000013567097387396117
В [19]:
var idC = exchanges[2].Sell(tickerC.Buy, nowAccA.Balance - accA.Balance)
var nowAccC = exchanges[2].GetAccount()
nowAccC
Выход[19]: { Остаток: 10174.91841463, Замороженный баланс: 0, Запасы: 0,9661. ФрозенСтокс: 0 }
В [20]:
var orderC = exchanges[2].GetOrder(idC)
orderC // We can see that the handling fee is deducted from the USDT.
Выход[20]:
{ Идентификатор: 1,
Цена: 5161.89999999,
Сумма: 0,0339,
Сумма сделки: 0,0339,
Средняя цена: 5161,89999999,
Тип: 1,
Сдвиг: 0,
Статус: 1,
Контракт тип:
В [21]:
var feeRatioC = 0.0004
var feeC = orderC.DealAmount * orderC.AvgPrice * feeRatioC / tickerC.Last // Exchange C trading handling fees, BTC denominated.
feeC
Выход[21]: 0,000013559999999973732
Расчет общей информации об активах после хеджирования.
В [22]:
var nowSumBTC = nowAccA.Balance + nowAccC.Stocks
nowSumBTC
Выход[22]: 2.0000514000000003
В [23]:
var nowSumETH = nowAccA.Stocks + nowAccB.Stocks
nowSumETH
Выход[23]: 11.
В [24]:
var nowSumUSDT = nowAccB.Balance + nowAccC.Balance
nowSumUSDT
Выход[24]: 19999.76838261
В [25]:
nowSumBTC - initSumBTC
Выход[25]: 0,000051400000000256796
В [26]:
tickerC.Buy * (nowSumBTC - initSumBTC) // The extra BTC is converted to USDT.
Выход[26]: 0,26532166000081153
В [27]:
nowSumUSDT + tickerC.Buy * (nowSumBTC - initSumBTC) - initSumUSDT // Profit and loss is calculated based on the changes of the account assets and is denominated in USDT.
Выход[27]: 0.0337042700011807
В [28]:
(diffA2B - (feeA + feeB + feeC)) * tickerC.Buy // Profit and loss based on price difference, denominated in USDT.
Выход[28]: 0.03372495390449328
Можно заметить, что разница в цене при хеджированииdiffA2B
: 0,000047246531444007644.
Плата за обработку трех хеджировок конвертируется в BTC как:feeA+feeB+feeC
.
В [29]:
feeA + feeB + feeC
Выход[29]: 0,00004071309338736985
Можно увидеть, что в конфигурации обратного теста плата за обработку изменяется на"fee":[0.04,0.04]
, то есть 0,04%.feeA+feeB+feeC
В конце концов, рассчитанная прибыль и убытки очень малы, всего 0,03372495390449328, а прибыль и убытки, рассчитанные через изменение счета, в основном такие же, как и рассчитанные через ценовую разницу. Этот исследовательский документ можно использовать для расчета того, сколько разницы можно хеджировать для треугольного хеджирования.