Reviewing 2017

I never understood why publications release their end-of-the-year lists in early December. There’s still a whole month left of the year for things to make your list or, at least, there’s some time…

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




Hedging strategy of cryptocurrency manual futures and spots

In view of the fact that the hedging frequency of the futures and spots hedging strategy is not high, it is actually possible to operate manually. However, if you do it manually, it is very inconvenient to switch pages of various exchanges, observe prices, and calculate the difference, and sometimes you may want to see more varieties, and it is not necessary to set up several monitors to display the market. Is it possible to achieve this goal of manual operation with a semi-automatic strategy? It is better to have multi-species, oh! Yes, it is best to open and close positions with one-click. Oh! Yes, there is also a position display…

When there is a need, do it now!

### Design a hedging strategy of cryptocurrency manual futures and spots

The writing is rather long-winded, with less than 600 lines of code.

```
function createManager(fuEx, spEx, symbolPairs, cmdHedgeAmount, fuMarginLevel, fuMarginReservedRatio) {
var self = {}
self.fuEx = fuEx
self.spEx = spEx
self.symbolPairs = symbolPairs
self.pairs = []
self.fuExTickers = null
self.spExTickers = null
self.tickerUpdateTS = 0
self.fuMarginLevel = fuMarginLevel
self.fuMarginReservedRatio = fuMarginReservedRatio
self.cmdHedgeAmount = cmdHedgeAmount
self.preUpdateAccTS = 0
self.accAndPosUpdateCount = 0
self.profit = []
self.allPairs = []

self.updateTickers = function() {
self.fuEx.goGetTickers()
self.spEx.goGetTickers()
var fuExTickers = self.fuEx.getTickers()
var spExTickers = self.spEx.getTickers()

if (!fuExTickers || !spExTickers) {
return null
}
self.fuExTickers = fuExTickers
self.spExTickers = spExTickers
self.tickerUpdateTS = new Date().getTime()
return true
}

self.hedge = function(index, fuSymbol, spSymbol, tradeType, amount) {
var fe = self.fuEx
var se = self.spEx
var pair = self.pairs[index]
var timeStamp = new Date().getTime()

var fuDirection = null
var spDirection = null
var fuPrice = null
var spPrice = null

fe.goGetAcc(fuSymbol, timeStamp)
se.goGetAcc(spSymbol, timeStamp)
var nowFuAcc = fe.getAcc(fuSymbol, timeStamp)
var nowSpAcc = se.getAcc(spSymbol, timeStamp)
if (!nowFuAcc || !nowSpAcc) {
Log(fuSymbol, spSymbol, “, failed to get account data”)
return
}
pair.nowFuAcc = nowFuAcc
pair.nowSpAcc = nowSpAcc

var nowFuPos = fe.getFuPos(fuSymbol, timeStamp)
var nowSpPos = se.getSpPos(spSymbol, spPrice, pair.initSpAcc, pair.nowSpAcc)
if (!nowFuPos || !nowSpPos) {
Log(fuSymbol, spSymbol, “, failed to get position data”)
return
}
pair.nowFuPos = nowFuPos
pair.nowSpPos = nowSpPos

fuAmount = fe.calcAmount(fuSymbol, fuDirection, fuPrice, fuAmount)
spAmount = se.calcAmount(spSymbol, spDirection, spPrice, spAmount)
if (!fuAmount || !spAmount) {
Log(fuSymbol, spSymbol, “order quantity calculation error:”, fuAmount, spAmount)
return
} else {
fuAmount = fe.calcAmount(fuSymbol, fuDirection, fuPrice, fuAmount[1])
spAmount = se.calcAmount(spSymbol, spDirection, spPrice, Math.min(fuAmount[1], spAmount[1]))
if (!fuAmount || !spAmount) {
Log(fuSymbol, spSymbol, “order quantity calculation error:”, fuAmount, spAmount)
return
}
}
Log(“contract code:”, fuSymbol + “/” + spSymbol, “direction:”, self.arrTradeTypeDesc[tradeType], “difference:”, fuPrice — spPrice, “quantity of futures:”, fuAmount, “quantity of spots:”, spAmount, “@”)

fe.goGetTrade(fuSymbol, fuDirection, fuPrice, fuAmount[0])
se.goGetTrade(spSymbol, spDirection, spPrice, spAmount[0])

var feIdMsg = fe.getTrade()
var seIdMsg = se.getTrade()
return [feIdMsg, seIdMsg]
}

self.process = function() {
var nowTS = new Date().getTime()
if(!self.updateTickers()) {
return
}

if (nowFuPos && nowSpPos) {
pair.nowFuPos = nowFuPos
pair.nowSpPos = nowSpPos
self.keepBalance(pair)
} else {
Log(pair.fuSymbol, pair.spSymbol, “portfolio position update failed, nowFuPos:”, nowFuPos, “ nowSpPos:”, nowSpPos)
}
self.accAndPosUpdateCount++
}
})

if (nowTS — self.preUpdateAccTS > 1000 * 60 * 5) {
self.preUpdateAccTS = nowTS
self.profit = self.calcProfit()
LogProfit(self.profit[0], “futures:”, self.profit[1], “spots:”, self.profit[2], “&”) // Print the total profit curve, use the & character not to print the profit log
}

self.keepBalance = function (pair) {
var nowFuPos = pair.nowFuPos
var nowSpPos = pair.nowSpPos
var fuLongPos = self.getLongPos(nowFuPos)
var fuShortPos = self.getShortPos(nowFuPos)
var spLongPos = self.getLongPos(nowSpPos)
var spShortPos = self.getShortPos(nowSpPos)

return posTbl
}

self.init()
return self
}

while(true) {
manager.process()
Sleep(interval)
}
}

function onerror() {
if (manager) {
manager.onexit()
}
}

function onexit() {
if (manager) {
manager.onexit()
}
}
```

Since the multi-species strategy is more suitable for IO design, a template class library named ```MultiSymbolCtrlLib``` is used in the code (encapsulation, calling the exchange interface through IO). Therefore, the strategy cannot be backtested, but it can be tested with the simulated bot (although the real bot has been run for 2 months, the test and familiarization stage is still run with the simulated bot).

### Parameters

Before starting the test, let’s talk about the parameter design first.

/upload/asset/28e1e506fac99433b60fa.png

There are not many strategy parameters, the more important ones are:

Other functions are to set the analog disk, reset the data, use the OKEX V5 interface (because it is also compatible with V3) and so on, which are not particularly important.

### Testing

The first exchange object adds the futures exchange, and the second adds the spot exchange object.

Futures exchanges use OKEX’s V5 interface simulation bots, and spot exchanges use WexApp simulation bots.

Click the positive set button of the BTC combination and open the position.

/upload/asset/28e6ac609ebfa9d7053d0.png

Click to close the positive arbitrage then.

/upload/asset/28dee91157895dba9ef89.png

Lose!!! It seems that closing the position cannot cover the handling fee when the profit spread is small, it is necessary to calculate the handling fee, the approximate slippage, and plan the spread reasonably, and then close the position.

Those who are interested can use and modify it.

Add a comment

Related posts:

Install QGis on OpenSuse Tumbeweed

Qgis is a software used to analize and visualize spatial images. It is very usefull and it very used into research, so I will explain how to install on Opensuse Tumbleweed because from official…

American Birds

When I was a young boy, I used to love the sound of the birds singing in the morning. The call of the cuckoo, the cock-a-doodle-doo of the rooster, the laugh of the swan and so many more. My parents…

Systems of Participation

With the explosion of cryptocurrencies we are also seeing the advent of new methods of engagement — new ways that people can participate in ecosystems. Here we develop a simple framework for…