Un facteur alpha à haute fréquence de flux d'ordres au niveau de l'entrée peut être utilisé comme référence pour la stratégie de négociation. Les signaux sont classés en [-1, 1], la tendance 1 indique le marché des acheteurs, la tendance -1 est le marché des vendeurs, la stratégie trace en temps réel la valeur du facteur et le prix final de la transaction. La stratégie utilise l'interface OKX et le websocket de Bitcoin pour effectuer des calculs, les résultats indiqués ci-dessous montrent une certaine efficacité et sont ouverts aux amateurs de quantification à haute fréquence.
let _chart = Chart({ subtitle: { text: "Market Status", }, yAxis: [{ height: "60%", lineWidth: 1, title: { text: 'Close', }, opposite: true, labels: { align: "right", x: -3, } }, { title: { text: 'Alpha', }, top: "60%", height: "20%", offset: 0, lineWidth: 1 }, { title: { text: 'Vol', }, top: "80%", height: "20%", offset: 0, lineWidth: 1 }], series: [{ name: 'Last', lineWidth: 1, data: [], id: 'primary', tooltip: { xDateFormat: '%Y-%m-%d %H:%M:%S' }, yAxis: 0 }, { type: 'column', lineWidth: 2, name: 'Alpha', data: [], yAxis: 1, color: 'green', zones: [{ value: 0, color: 'red' }] }, { lineWidth: 1, type: 'area', color: '#257ed4', name: 'Vol', data: [], yAxis: 2 }], }) function calc_alpha(trades) { let tick_sell_vol = 0 let tick_buy_vol = 0 let last_buy_vol = 0 let last_sell_vol = 0 let rightPos = Math.ceil(trades.length * 0.382) trades.forEach(function(trade, idx) { if (trade.side == 'buy') { if (idx >= rightPos) { last_buy_vol += trade.qty } tick_buy_vol += trade.qty } else { if (idx >= rightPos) { last_sell_vol += trade.qty } tick_sell_vol += trade.qty } }) let tanh = function(x) { // return [-1, 1] return (Math.exp(x) - Math.exp(-x)) / (Math.exp(x) + Math.exp(-x)) } let positive_ratio = last_buy_vol / tick_sell_vol let negative_ratio = last_sell_vol / tick_buy_vol let trade_ratio = 0 if (positive_ratio > negative_ratio) { trade_ratio = tanh(positive_ratio) } else { trade_ratio = tanh(-negative_ratio) } return _N(trade_ratio, 3) } let _trades = [] let _vol = 0 function onTick(ctx, event) { if (event.trades) { event.trades.forEach(function(trade) { _vol += trade.qty _trades.push(trade) if (_trades.length > QSize) { _trades.shift() } }) if (_trades.length >= QSize) { let val = calc_alpha(_trades) _chart.add(0, [event.ts, _trades[_trades.length-1].price]) _chart.add(1, [event.ts, val]) _chart.add(2, [event.ts, _vol]) _vol = 0 } } } function main() { _chart.reset() let ct = exchange.SetContractType("swap") let debug = false let useMargin = false let okxAccessKey = "" let okxPhrase = "" let ctx = $.NewWSS(exchange, function(ws, e) { let msg = null if (e.GetName() == 'Futures_OKCoin') { msg = { op: "subscribe", args: [] } let instId = ct.InstrumentID msg.args.push({ channel: "books5", instId: instId }) msg.args.push({ channel: "trades", instId: instId }) } else { msg = { method: "SUBSCRIBE", params: [], id: "1" } let symbol = e.GetCurrency().replace('_', '').toLowerCase() msg.params.push(symbol + "@aggTrade") msg.params.push(symbol + "@depth20@100ms") } ws.write(JSON.stringify(msg)) Log("subscribe", msg, "channel") LogStatus("Ready") }, onTick, debug, useMargin, okxAccessKey, okxPhrase) while (true) { ctx.poll() EventLoop(1000) } }
mztcoinJe vais essayer.