Новички в количественной торговле в криптовалютных кругах, пожалуйста, ознакомьтесь с этим - Приближаемся к количественной торговле в криптовалютных кругах (часть 7)

Создано: 2021-06-09 14:30:43, Обновлено: 2023-09-19 21:45:29
comments   3
hits   2230

Новички в количественной торговле в криптовалютных кругах, пожалуйста, ознакомьтесь с этим - Приближаемся к количественной торговле в криптовалютных кругах (часть 7)

Новички в количественной торговле в криптовалютных кругах, пожалуйста, ознакомьтесь с этим - Приближаемся к количественной торговле в криптовалютных кругах (часть 7)

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

Кросс-периодное хеджирование

Кросс-периодное хеджирование просто означает открытие длинной позиции по одному контракту, короткой — по другому контракту и ожидание одновременного закрытия позиций наступления следующих трех ситуаций:

  • Вы зарабатываете деньги, когда вы идете в лонг и теряете деньги, когда вы идете в шорт. Когда прибыль (как говорится) больше, чем убыток (как говорится), закройте позицию. После того, как прибыли и убытки компенсируют друг друга, есть будет некоторая прибыль.
  • Те, кто играет на длинную позицию, теряют деньги, те, кто играет на короткую, зарабатывают деньги, и вы закрываете свою позицию, когда прибыль с одной стороны больше, чем убыток с другой стороны… (то же самое, что и выше).
  • Те, кто играет на повышение, зарабатывают деньги, и те, кто играет на понижение, тоже зарабатывают деньги, так о чем еще тут думать! Закройте позицию!

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

设A1为合约A在1时刻的价格,设B1为合约B在1时刻的价格,此时做空A合约,做空价格A1,做多B合约,做多价格B1。
设A2为合约A在2时刻的价格,设B2为合约B在2时刻的价格,此时平仓A合约(平空),平空价格A2,平仓B合约(平多),平多价格B2。

1时刻的差价:A1 - B1 = X 
2时刻的差价:A2 - B2 = Y 
X - Y = A1 - B1 - (A2 - B2)
X - Y = A1 - B1 - A2 + B2
X - Y = A1 - A2 + B2 - B1

可以看到,A1 - A2 就是A合约平仓的盈利差价。
B2 - B1就是B合约平仓的盈利差价。只要这两个平仓总体是正数,即:A1 - A2 + B2 - B1 > 0 就是盈利的。也就是说只要X - Y > 0。
因为:X - Y = A1 - A2 + B2 - B1

得出结论,只要开仓时的差价X大于平仓时的差价Y就是盈利的(注意是做空A,做多B开仓,搞反了就是相反的了),当然这个是理论上的,实际上还要考虑手续费、滑点等因素。

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

Давайте разомнемся, сделав многовариантную статистику разницы цен.

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

Мы основаны наКонтракты OKEXДля проектирования, рисование на FMZ очень просто, вы можете легко рисовать, используя упакованные функции, библиотека диаграмм естьHighcharts. Описание функции рисования в документации API: https://www.fmz.com/api#chart...

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

var arrSwapContractType = ["BTC-USDT-SWAP", "LTC-USDT-SWAP", "ETH-USDT-SWAP", "ETC-USDT-SWAP"]   // 永续合约
var arrDeliveryContractType = ["BTC-USDT-210924", "LTC-USDT-210924", "ETH-USDT-210924", "ETC-USDT-210924"]  // 交割合约

Инициализируйте конфигурацию диаграммы в соответствии с установленным здесь кодом контракта. Эта конфигурация диаграммы не должна быть жестко запрограммирована, поскольку вы не знаете, какой продукт производить или сколько продуктов производить (они определяются значениями arrDeliveryContractType и arrSwapContractType), поэтому конфигурация диаграммы возвращается функцией .

function createCfg(symbol) {
    var cfg = {
        extension: {
            // 不参于分组,单独显示,默认为分组 'group'
            layout: 'single', 
            // 指定高度,可以设置为字符串,"300px",设置数值300会自动替换为"300px"
            height: 300,      
            // 指定宽度占的单元值,总值为12
            col: 6
        },
        title: {
            text: symbol
        },
        xAxis: {
            type: 'datetime'
        },
        series: [{
            name: 'plus',
            data: []
        }]
    }

    return cfg
}

function main() {
    // 声明arrCfg
    var arrCfg = []                                    // 声明一个数组,用来存放图表配置信息
    _.each(arrSwapContractType, function(ct) {         // 迭代记录永续合约代码的数组,用合约名称XXX-USDT部分作为参数传给createCfg函数,构造图表配置信息,返回
        arrCfg.push(createCfg(formatSymbol(ct)[0]))    // createCfg返回的图表配置信息push进arrCfg数组
    })
    var objCharts = Chart(arrCfg)                      // 调用FMZ平台的图表函数Chart,创建图表控制对象objCharts
    objCharts.reset()                                  // 初始化图表内容
    
    // 以下省略.....
}

Далее подготовим данные. Используем агрегированный рыночный интерфейс контрактов OKEX:

Бессрочный контракт USDT:

https://www.okex.com/api/v5/market/tickers?instType=SWAP

Контракт поставки USDT:

https://www.okex.com/api/v5/market/tickers?instType=FUTURES

Мы пишем функцию для обработки вызовов этих двух интерфейсов и преобразуем данные в формат:

function getTickers(url) {
    var ret = []
    try {
        var arr = JSON.parse(HttpQuery(url)).data
        _.each(arr, function(ele) {
            ret.push({
                bid1: parseFloat(ele.bidPx),             // 买一价
                bid1Vol: parseFloat(ele.bidSz),          // 买一价的量
                ask1: parseFloat(ele.askPx),             // 卖一价
                ask1Vol: parseFloat(ele.askSz),          // 卖一价的量
                symbol: formatSymbol(ele.instId)[0],     // 格式成交易对
                type: "Futures",                         // 类型
                originalSymbol: ele.instId               // 原始合约代码
            })
        })
    } catch (e) {
        return null 
    }
    return ret 
}

Напишите еще одну функцию для обработки кода контракта.

function formatSymbol(originalSymbol) {
    var arr = originalSymbol.split("-")
    return [arr[0] + "_" + arr[1], arr[0], arr[1]]
}

Остается итеративно сопоставить полученные данные, рассчитать разницу в ценах, вывести график и т. д. Здесь проверяется разница в цене между следующим квартальным контрактом 210924 и бессрочным контрактом. Полный код:

// 临时参数
var arrSwapContractType = ["BTC-USDT-SWAP", "LTC-USDT-SWAP", "ETH-USDT-SWAP", "ETC-USDT-SWAP"]
var arrDeliveryContractType = ["BTC-USDT-210924", "LTC-USDT-210924", "ETH-USDT-210924", "ETC-USDT-210924"]
var interval = 2000

function createCfg(symbol) {
    var cfg = {
        extension: {
            // 不参于分组,单独显示,默认为分组 'group'
            layout: 'single', 
            // 指定高度,可以设置为字符串,"300px",设置数值300会自动替换为"300px"
            height: 300,      
            // 指定宽度占的单元值,总值为12
            col: 6
        },
        title: {
            text: symbol
        },
        xAxis: {
            type: 'datetime'
        },
        series: [{
            name: 'plus',
            data: []
        }]
    }

    return cfg
}

function formatSymbol(originalSymbol) {
    var arr = originalSymbol.split("-")
    return [arr[0] + "_" + arr[1], arr[0], arr[1]]
}

function getTickers(url) {
    var ret = []
    try {
        var arr = JSON.parse(HttpQuery(url)).data
        _.each(arr, function(ele) {
            ret.push({
                bid1: parseFloat(ele.bidPx), 
                bid1Vol: parseFloat(ele.bidSz), 
                ask1: parseFloat(ele.askPx), 
                ask1Vol: parseFloat(ele.askSz), 
                symbol: formatSymbol(ele.instId)[0], 
                type: "Futures", 
                originalSymbol: ele.instId
            })
        })
    } catch (e) {
        return null 
    }
    return ret 
}

function main() {
    // 声明arrCfg
    var arrCfg = []
    _.each(arrSwapContractType, function(ct) {
        arrCfg.push(createCfg(formatSymbol(ct)[0]))
    })
    var objCharts = Chart(arrCfg)
    objCharts.reset()
    
    while (true) {
        // 获取行情数据        
        var deliveryTickers = getTickers("https://www.okex.com/api/v5/market/tickers?instType=FUTURES")
        var swapTickers = getTickers("https://www.okex.com/api/v5/market/tickers?instType=SWAP")
        if (!deliveryTickers || !swapTickers) {
            Sleep(2000)
            continue
        }

        var tbl = {
            type : "table",
            title : "交割-永续差价",
            cols : ["交易对", "交割", "永续", "正对冲", "反对冲"],
            rows : []
        }
        
        var subscribeDeliveryTickers = []
        var subscribeSwapTickers = []
        _.each(deliveryTickers, function(deliveryTicker) {
            _.each(arrDeliveryContractType, function(symbol) {
                if (deliveryTicker.originalSymbol == symbol) {
                    subscribeDeliveryTickers.push(deliveryTicker)
                }
            })
        })
        _.each(swapTickers, function(swapTicker) {
            _.each(arrSwapContractType, function(symbol) {
                if (swapTicker.originalSymbol == symbol) {
                    subscribeSwapTickers.push(swapTicker)
                }
            })
        })
        
        var pairs = []
        var ts = new Date().getTime()
        _.each(subscribeDeliveryTickers, function(deliveryTicker) {
            _.each(subscribeSwapTickers, function(swapTicker) {
                if (deliveryTicker.symbol == swapTicker.symbol) {
                    var pair = {symbol: swapTicker.symbol, swapTicker: swapTicker, deliveryTicker: deliveryTicker, plusDiff: deliveryTicker.bid1 - swapTicker.ask1, minusDiff: deliveryTicker.ask1 - swapTicker.bid1}
                    pairs.push(pair)
                    tbl.rows.push([pair.symbol, deliveryTicker.originalSymbol, swapTicker.originalSymbol, pair.plusDiff, pair.minusDiff])
                    for (var i = 0 ; i < arrCfg.length ; i++) {
                        if (arrCfg[i].title.text == pair.symbol) {
                            objCharts.add([i, [ts, pair.plusDiff]])
                        }                        
                    }                    
                }
            })
        })

        LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`")        
        Sleep(interval)
    }
}

Работа в реальном времени

Новички в количественной торговле в криптовалютных кругах, пожалуйста, ознакомьтесь с этим - Приближаемся к количественной торговле в криптовалютных кругах (часть 7)

Беги немного~

Новички в количественной торговле в криптовалютных кругах, пожалуйста, ознакомьтесь с этим - Приближаемся к количественной торговле в криптовалютных кругах (часть 7)

Сначала обратите внимание на разницу в цене! /загрузить/asset/16a9cc6330dfc9c7fb21.jpg