A, in this paper,
Before the rise of electronic trading, it was hard to understand how volume was distributed on the K-line. Nowadays, the development of science and technology has brought us an unprecedented way of market analysis. Most software has supported the Order Book method to provide investors with price and volume data, so as to understand the reasons behind the price rise or fall. This article, the first in the CTA policy OrderFlow OrderFlow strategy series, focuses on the OrderFlow OrderFlow in detail.
2. Introduction to OrderFlow
In the secondary market, the factors affecting price changes are numerous and complex, and each factor has a different weight on price changes, so that it is difficult to deduce price behavior from the traditional technical analysis graph, because compared with price and volume, technical analysis graph is relatively abstract and lagging. The advent of the OrderFlow OrderFlow tool makes the market more transparent. The OrderFlow OrderFlow has many categories, including: depth of market (L2 data), volume distribution (VP), Footprint Chart, Sales Details, etc., as shown below:
1. Market depth (L2 data)
2. Volume Distribution (VP)
3. Footprint Chart
4. Sales Details
The principle of OrderFlow
The market is full of all kinds of information, good and bad, true and false. These information is like thorns, so it is difficult to understand and deduce the news with correct logic. For example, the good news comes out, but the price does not change much. Another example is the spectacular rise in prices, often amid skepticism; Bull markets tend to end when everyone is bullish and so on. So we need to stand on the shoulders of giants to analyze this market, cut through the thorns to extract the real reason for price fluctuations.
In the secondary market is composed of investment since, whether investors use fundamental analysis, technical analysis, news, every investor in trade, in fact, are to vote for their own ideas, so we see price fluctuations, in fact is the result of investors compete, if the long and short close, both sides equal power, regardless of high and low, Then the price will not go up or down; If the bulls are stronger than the bears, prices will rise. If the shorts outnumber the bulls, prices will fall. If the long is regarded as the buyer and the short as the seller, then the imbalance between the demand and supply of the long and the short is the main cause of price fluctuations, and all of this can be seen in the volume of the long and the short.
Delta structure data in order flow
The traditional Japanese candlelight chart (K line) has four prices: opening price, high price, low price and close price. The K line only represents the price change within this period of time. For example, the hour line represents the price change within an hour. The Delta structure data is based on Tick data, which provides specific details of what happens in the period of K line, including the long and short trading volume of each price of K line, and can clearly see the long-short orders. As shown below:
In the Delta data structure above, each root K line has an independent Delta data structure, data in the Delta structure in the box, the top is the total volume of this K line, the bottom of this K line all long volume and short volume is poor, is this K line between each price long volume and short volume data. As you can see, Delta structured data breaks down the K-line into more detailed visualizations to help investors understand the mechanics of price movements.
5. Strategy implementation
/*backtest
start: 2020-03-10 00:00:00
end: 2020-03-10 23:59:00
period: 1h
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
mode: 1
*/
var NewFuturesTradeFilter = function(period) {
var self = {} // 创建一个对象
self.c = Chart({ // 创建Chart图表
chart: {
zoomType: 'x', // 缩放
backgroundColor: '#272822',
borderRadius: 5,
panKey: 'shift',
animation: false,
},
plotOptions: {
candlestick: {
color: '#00F0F0',
lineColor: '#00F0F0',
upColor: '#272822',
upLineColor: '#FF3C3C'
},
},
tooltip: {
xDateFormat: '%Y-%m-%d %H:%M:%S, %A',
pointFormat: '{point.tips}',
borderColor: 'rgb(58, 68, 83)',
borderRadius: 0,
},
series: [{
name: exchange.GetName(),
type: 'candlestick',
data: []
}],
yAxis: {
gridLineColor: 'red',
gridLineDashStyle: 'Dot',
labels: {
style: {
color: 'rgb(204, 214, 235)'
}
}
},
rangeSelector: {
enabled: false
},
navigation: {
buttonOptions: {
height: 28,
width: 33,
symbolSize: 18,
symbolX: 17,
symbolY: 14,
symbolStrokeWidth: 2,
}
}
})
self.c.reset() // 清空图表数据
self.pre = null // 用于记录上一个数据
self.records = []
self.feed = function(ticker, contractCode) {
if (!self.pre) { // 如果上一个数据不为真
self.pre = ticker // 赋值为最新数据
}
var action = '' // 标记为空字符串
if (ticker.Last >= self.pre.Sell) { // 如果最新数据的最后价格大于等于上一个数据的卖价
action = 'buy' // 标记为buy
} else if (ticker.Last <= self.pre.Buy) { // 如果最新数据的最后价格小于等于上一个数据的买价
action = 'sell' // 标记为sell
} else {
if (ticker.Last >= ticker.Sell) { // 如果最新数据的最后价格大于等于最新数据的卖价
action = 'buy' // 标记为buy
} else if (ticker.Last <= ticker.Buy) { // 如果最新数据的最后价格小于等于最新数据的买价
action = 'sell' // 标记为sell
} else {
action = 'both' // 标记为both
}
}
// reset volume
if (ticker.Volume < self.pre.Volume) { // 如果最新数据的成交量小于上一个数据的成交量
self.pre.Volume = 0 // 把上一个数据的成交量赋值为0
}
var amount = ticker.Volume - self.pre.Volume // 最新数据的成交量减去上一个数据的成交量
if (action != '' && amount > 0) { // 如果标记不为空字符串,并且action大于0
var epoch = parseInt(ticker.Time / period) * period // 计算K线时间戳并取整
var bar = null
var pos = undefined
if (
self.records.length == 0 || // 如果K线长度为0或者最后一根K线时间戳小于epoch
self.records[self.records.length - 1].time < epoch
) {
bar = {
time: epoch,
data: {},
open: ticker.Last,
high: ticker.Last,
low: ticker.Last,
close: ticker.Last
} // 把最新的数据赋值给bar
self.records.push(bar) // 把bar添加到records数组中
} else { // 重新给bar赋值
bar = self.records[self.records.length - 1] // 上一个数据最后一根K线
bar.high = Math.max(bar.high, ticker.Last) // 上一个数据最后一根K线的最高价与最新数据最后价格的最大值
bar.low = Math.min(bar.low, ticker.Last) // 上一个数据最后一根K线的最低价与最新数据最后价格的最小值
bar.close = ticker.Last // 最新数据的最后价格
pos = -1
}
if (typeof bar.data[ticker.Last] === 'undefined') { // 如果数据为空
bar.data[ticker.Last] = { // 重新赋值
buy: 0,
sell: 0
}
}
if (action == 'both') { // 如果标记等于both
bar.data[ticker.Last]['buy'] += amount // buy累加
bar.data[ticker.Last]['sell'] += amount // sell累加
} else {
bar.data[ticker.Last][action] += amount // 标记累加
}
var initiativeBuy = 0
var initiativeSell = 0
var sellLongMax = 0
var buyLongMax = 0
var sellVol = 0
var buyVol = 0
for (var i in bar.data) {
sellLong = bar.data[i].sell.toString().length
buyLong = bar.data[i].buy.toString().length
if (sellLong > sellLongMax) {
sellLongMax = sellLong
}
if (buyLong > buyLongMax) {
buyLongMax = buyLong
}
sellVol += bar.data[i].sell
buyVol += bar.data[i].buy
}
// var date = new Date(bar.time);
// var Y = date.getFullYear() + '-';
// var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
// var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
// var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
// var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + '<br>';
// var tips = Y + M + D + h + m
tips = '<b>◉ ' + (sellVol + buyVol) + '</b>'
Object.keys(bar.data) // 将对象里的键放到一个数组中
.sort() // 排序
.reverse() // 颠倒数组中的顺序
.forEach(function(p) { // 遍历数组
pSell = bar.data[p].sell
pBuy = bar.data[p].buy
if (pSell > pBuy) {
arrow = ' ▼ '
} else if (pSell < pBuy) {
arrow = ' ▲ '
} else {
arrow = ' ♦ '
}
initiativeSell += pSell
initiativeBuy += pBuy
sellLongDiff = sellLongMax - pSell.toString().length
buyLongDiff = buyLongMax - pBuy.toString().length
if (sellLongDiff == 1) {
pSell = '0' + pSell
}
if (sellLongDiff == 2) {
pSell = '00' + pSell
}
if (sellLongDiff == 3) {
pSell = '000' + pSell
}
if (sellLongDiff == 4) {
pSell = '0000' + pSell
}
if (sellLongDiff == 5) {
pSell = '00000' + pSell
}
if (buyLongDiff == 1) {
pBuy = '0' + pBuy
}
if (buyLongDiff == 2) {
pBuy = '00' + pBuy
}
if (buyLongDiff == 3) {
pBuy = '000' + pBuy
}
if (buyLongDiff == 4) {
pBuy = '0000' + pBuy
}
if (buyLongDiff == 5) {
pBuy = '00000' + pBuy
}
code = contractCode.match(/[a-zA-Z]+|[0-9]+/g)[0]
if (code == 'IF' || code == 'j' || code == 'IC' || code == 'i' || code == 'ZC' || code == 'sc' || code == 'IH' || code == 'jm' || code == 'fb') {
p = parseFloat(p).toFixed(1)
} else if (code == 'au') {
p = parseFloat(p).toFixed(2)
} else if (code == 'T' || code == 'TF' || code == 'TS') {
p = parseFloat(p).toFixed(3)
} else {
p = parseInt(p)
}
tips += '<br>' + p + ' → ' + pSell + arrow + pBuy
})
tips += '<br>' + '<b>⊗ ' + (initiativeBuy - initiativeSell) + '</b>'
self.c.add( // 添加数据
0, {
x: bar.time,
open: bar.open,
high: bar.high,
low: bar.low,
close: bar.close,
tips: tips
},
pos
)
}
self.pre = ticker // 重新赋值
}
return self // 返回对象
}
function main() {
if (exchange.GetName().indexOf('CTP') == -1) {
throw "只支持商品期货CTP";
}
SetErrorFilter("login|timeout|GetTicker|ready|流控|连接失败|初始|Timeout");
while (!exchange.IO("status")) {
Sleep(3000);
LogStatus("正在等待与交易服务器连接, " + _D());
}
symbolDetail = _C(exchange.SetContractType, contractCode) // 订阅数据
Log('交割日期:', symbolDetail['StartDelivDate'])
Log('最小下单量:', symbolDetail['MaxLimitOrderVolume'])
Log('最小价差:', symbolDetail['PriceTick'])
Log('一手:', symbolDetail["VolumeMultiple"], '份')
Log('合约代码:', symbolDetail['InstrumentID'])
var filt = NewFuturesTradeFilter(60000) // 创建一个对象
while (true) { // 进入循环模式
while (!exchange.IO("status")) {
Sleep(3000);
LogStatus("正在等待与交易服务器连接, " + _D());
}
LogStatus("行情和交易服务器连接成功, " + _D());
var ticker = exchange.GetTicker() // 获取交易所Tick数据
if (ticker) { // 如果成功获取到Tick数据
filt.feed(ticker, contractCode) // 开始处理数据
}
}
}
Copy the code
Attached above is the complete policy code and the configuration of the firm offer, you can also click the link below to copy the complete policy code:
www.fmz.com/strategy/29…
Six, solid disk operation
Seven,
This paper describes in detail the basics of OrderFlow’s OrderFlow strategy and implements a Footprint Chart strategy using inventor’s quantitative trading platform, which can be directly applied to a commodity futures firm offer account. In the following sections, we will delve into OrderFlow OrderFlow data to develop a series of trading strategies based on OrderFlow OrderFlow data.