入力レベルのオーダーフロー高周波アルファ因子は,市場トレーダーの戦略の最適買出価格設定距離の基準として用いられる.信号は[-1, 1]に分類され,トレンド1は買い手市場,トレンド-1は売り手市場を表す.戦略は,因子値と最終取引価格をリアルタイムに図定する. 戦略はOKXとBinanceのフューチャーWebSocketのインターフェイスで受信計算を使用し,下図は指標効果であり,ある程度の有効性を示し,高周波入力の量化愛好者に公開しています.
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) } }
mztcoin試しにやってみよう