Type/to search
0
Follow
20
Followers
Realization of Fisher Indicator in JavaScript & Plotting on FMZ
Help
Created 2022-04-07 16:04:22  
 0
 876

Realization of Fisher Indicator in JavaScript & Plotting on FMZ

During the technical analysis in trading, traders all take stock price data as normally distributed data to analyze and study. However, the stock price data distribution does not conform to the standard normal distribution. Fisher Transformation is a method that can transform price data into something similar to a normal distribution. Fisher Transformation smoothes the market data and removes some sharp small periodic vibrations. Trading signals can be sent using the interleaving of today's and previous day's indicators.

There are so many references about Fisher Transformation on Baidu and Zhihu, which will not be explained here in details.

Indicator Algorithm:

  • Today's median price:

    mid=(low + high) / 2

  • Confirm the calculation period; you can use 10 days a period. Calculate the highest price and the lowest price in the period:

    lowestLow = the lowest price in the periodhighestHigh = the highest price in the period.

  • Define price change parameter (in which ratio is a constant from 0 to 1; for example, you can choose 0.5 or 0.33):(

    img

  • Apply Fisher transformation to the price change parameter x, and the Fisher indicator can be obtained:

    img

Use JavaScript to Realize the Algorithm

According to the indicator algorithm, realize it step by step. It should be noted that this algorithm is an iterative algorithm, and for preX, preFish, they are initially set to 0. Math.log is the logarithm based on the natural constant e In addition, the modification of x is not mentioned in the above algorithm, and I almost ignored this problem during writing:

Modify the value of x; if the value is over 0.99, forcibly set to 0.999; if it is less than -0.99, set to -0.999.

javascript
if (x > 0.99) { x = 0.999 } else if (x < -0.99) { x = -0.999 }

This is the first time I see the algorithm and the indicator, after porting it according to the algorithm. I have not verified the implementation, and students who are interested in research can verify whether there are any errors. Thanks a lot for pointing out errors, if there are any.

Source code of Fisher Transform indicator algorithm:

javascript
function getHighest(arr, period) { if (arr.length == 0 || arr.length - period < 0) { return null } var beginIndex = arr.length - period var ret = arr[beginIndex].High for (var i = 0 ; i < arr.length - 1 ; i++) { if (arr[i + 1].High > ret) { ret = arr[i + 1].High } } return ret } function getLowest(arr, period) { if (arr.length == 0 || arr.length - period < 0) { return null } var beginIndex = arr.length - period var ret = arr[beginIndex].Low for (var i = 0 ; i < arr.length - 1 ; i++) { if (arr[i + 1].Low < ret) { ret = arr[i + 1].Low } } return ret } function calcFisher(records, ratio, period) { var preFish = 0 var preX = 0 var arrFish = [] // when the K-line length is not long enough to meet the K-line period if (records.length < period) { for (var i = 0 ; i < records.length ; i++) { arrFish.push(0) } return arrFish } // traverse K-lines for (var i = 0 ; i < records.length ; i++) { var fish = 0 var x = 0 var bar = records[i] var mid = (bar.High + bar.Low) / 2 // when the current BAR is not enough for period to calculate if (i < period - 1) { fish = 0 preFish = 0 arrFish.push(fish) continue } // calculate the highest price and the lowest price in the period var bars = [] for (var j = 0 ; j <= i ; j++) { bars.push(records[j]) } var lowestLow = getLowest(bars, period) var highestHigh = getHighest(bars, period) // price change parameter x x = ratio * 2 * ((mid - lowestLow) / (highestHigh - lowestLow) - 0.5) + (1 - ratio) * preX if (x > 0.99) { x = 0.999 } else if (x < -0.99) { x = -0.999 } preX = x fish = 0.5 * Math.log((1 + x) / (1 - x)) + 0.5 * preFish preFish = fish arrFish.push(fish) } return arrFish }

Plot

It is very easy to plot on FMZ; you can refer to a lot of examples in the strategy square: https://www.fmz.com/square, and you can also search for the strategies you need.

javascript
var cfg = { // used to initially configure the chart objects (namely chart settings) plotOptions: { candlestick: { color: '#d75442', // color value upColor: '#6ba583' // color vlaue } }, title: { text: 'Fisher Transform'}, //title subtitle: {text: ''}, //subtitle plotOptions: { candlestick: { tooltip: { pointFormat: '<span style="color:{point.color}">\u25CF</span> <b> {series.name}</b><br/>' + 'open: {point.open}<br/>' + 'highest: {point.high}<br/>' + 'lowest: {point.low}<br/>' + 'close: {point.close}<br/>' } } }, yAxis: [{ title: { text: 'K-line market quote' }, height: '70%', lineWidth: 1 }, { title: { text: 'Fisher Transform' }, top: '75%', height: '30%', offset: 0, lineWidth: 1 }], series: [//series { type: 'candlestick', yAxis: 0, name: 'K-line', id: 'KLine', // control the candlestick color of fall color: 'green', lineColor: 'green', // control the candlestick color of rise upColor: 'red', upLineColor: 'red', data: [] },{ type: 'line', // set the type of the current data series as: line yAxis: 1, // the y axis for use is the y axis with index 0 (in highcharts, there can be multiple y axis, and here it indicates the y axis with index 0) showInLegend: true, // name: 'fish', // set according the parameter label passed by the function lineWidth: 1, data: [], // data item of the data series tooltip: { // tip for tool valueDecimals: 2 // the decimals of the value reserve 5 } },{ type: 'line', // set the type of the current data series as: line yAxis: 1, // the y axis for use is the y axis with index 0 (in highcharts, there can be multiple y axis, and here it indicates the y axis with index 0) showInLegend: true, // name: 'preFish', // set according the parameter label passed by the function lineWidth: 1, data: [], // data item of the data series tooltip: { // tip for tool valueDecimals: 2 // the decimals of the value reserve 5 } } ] } var chart = Chart(cfg) function main() { var ts = 0 chart.reset() while (true) { var r = exchange.GetRecords() var fisher = calcFisher(r, 0.33, 10) if (!r || !fisher) { Sleep(500) continue } for (var i = 0; i < r.length; i++){ if (ts == r[i].Time) { chart.add([0,[r[i].Time, r[i].Open, r[i].High, r[i].Low, r[i].Close], -1]) chart.add([1,[r[i].Time, fisher[i]], -1]) if (i - 1 >= 0) { chart.add([2,[r[i].Time, fisher[i - 1]], -1]) } }else if (ts < r[i].Time) { chart.add([0,[r[i].Time, r[i].Open, r[i].High, r[i].Low, r[i].Close]]) chart.add([1,[r[i].Time, fisher[i]]]) if (i - 1 >= 0) { chart.add([2,[r[i].Time, fisher[i - 1]]]) } ts = r[i].Time } } } }

img

Therefore, it is very convenient to study data, chart display and strategy design on FMZ.
Here I start the discussion for more ideas, so welcome teachers and students here to leave comments.

Comment
All comments (0)
No data
No data
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)