
Khi thực hiện phân tích kỹ thuật trong giao dịch, các nhà giao dịch phân tích và nghiên cứu dữ liệu giá cổ phiếu như dữ liệu phân phối chuẩn. Tuy nhiên, sự phân phối dữ liệu giá cổ phiếu không tuân theo phân phối chuẩn.Fisher TransformationĐây là phương pháp có thể chuyển đổi dữ liệu giá thành phân phối chuẩn.Fisher TransformationLàm mịn dữ liệu thị trường và loại bỏ một số dao động đột ngột trong chu kỳ nhỏ. Tín hiệu giao dịch có thể được tạo ra bằng cách sử dụng sự giao nhau của các chỉ báo cho ngày hiện tại và ngày trước đó.
VềFisher TransformCó rất nhiều thông tin trên Baidu và Zhihu nên tôi sẽ không đi sâu vào chi tiết ở đây.
mid=(low + high) / 2
lowestLow = 周期内最低价,highestHigh = 周期内最高价。
ratiolà hằng số giữa 0 và 1, ví dụ: 0,5 hoặc 0,33):
xsử dụngFisherBiến đổi, nhận đượcFishermục lục:
Thực hiện từng bước theo thuật toán chỉ báo. Cần lưu ý rằng thuật toán này là thuật toán lặp.preX,preFishBan đầu được đặt thành 0. vìMath.logTức là tìm logarit với hằng số tự nhiên e làm cơ số. Ngoài ra, thuật toán trên không đề cập đến việc hiệu chỉnh x và tôi gần như đã bỏ qua vấn đề này khi viết nó:
Sửa giá trị của x. Nếu lớn hơn 0,99, nó sẽ bị buộc thành 0,999. Tương tự nếu giá trị này nhỏ hơn -0,99.
if (x > 0.99) {
x = 0.999
} else if (x < -0.99) {
x = -0.999
}
Lần đầu tiên tôi xem xét thuật toán và các chỉ số này, tôi đã cấy ghép chúng theo thuật toán. Tôi chưa xác minh việc triển khai này. Các sinh viên quan tâm đến nghiên cứu có thể xác minh xem có lỗi nào không. Cảm ơn bạn rất nhiều vì đã chỉ ra lỗi.
Fisher TransformMã nguồn thuật toán chỉ báo:
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 = []
// 当K线长度不足,不满足周期时
if (records.length < period) {
for (var i = 0 ; i < records.length ; i++) {
arrFish.push(0)
}
return arrFish
}
// 遍历K线
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
// 当前BAR不足period计算时
if (i < period - 1) {
fish = 0
preFish = 0
arrFish.push(fish)
continue
}
// 计算周期内最高价和最低价
var bars = []
for (var j = 0 ; j <= i ; j++) {
bars.push(records[j])
}
var lowestLow = getLowest(bars, period)
var highestHigh = getHighest(bars, period)
// 价变参数
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
}
Vẽ trên FMZ rất đơn giản, Strategy Square:https://www.fmz.com/squareCó rất nhiều ví dụ ở trên để tham khảo hoặc tìm kiếm.
Do bài viết khá dài nên mã kiểm tra bản vẽ sau đây cần phải thêm hàm calcFisher ở trên trước khi có thể chạy.
var cfg = { // 用来初始化设置图表的对象(即图表设置)
plotOptions: {
candlestick: {
color: '#d75442', // 颜色值
upColor: '#6ba583' // 颜色值
}
},
title: { text: 'Fisher Transform'}, //标题
subtitle: {text: ''}, //副标题
plotOptions: {
candlestick: {
tooltip: {
pointFormat:
'<span style="color:{point.color}">\u25CF</span> <b> {series.name}</b><br/>' +
'开盘: {point.open}<br/>' +
'最高: {point.high}<br/>' +
'最低: {point.low}<br/>' +
'收盘: {point.close}<br/>'
}
}
},
yAxis: [{
title: {
text: 'K线行情'
},
height: '70%',
lineWidth: 1
}, {
title: {
text: 'Fisher Transform'
},
top: '75%',
height: '30%',
offset: 0,
lineWidth: 1
}],
series: [//系列
{
type: 'candlestick',
yAxis: 0,
name: 'K线',
id: 'KLine',
// 控制走势为跌的蜡烛颜色
color: 'green',
lineColor: 'green',
// 控制走势为涨的蜡烛颜色
upColor: 'red',
upLineColor: 'red',
data: []
},{
type: 'line', // 设置当前的数据序列 类型为: 线
yAxis: 1, // 使用的y轴 为索引为 0 的y轴(highcharts 图表 可以有 多个 y 坐标轴,这里指定索引0的y轴)
showInLegend: true, //
name: 'fish', // 根据 函数传入的 参数 label 设置
lineWidth: 1,
data: [], // 数据序列的数据项
tooltip: { // 工具提示
valueDecimals: 2 // 值的小数点 保留5位
}
},{
type: 'line', // 设置当前的数据序列 类型为: 线
yAxis: 1, // 使用的y轴 为索引为 0 的y轴(highcharts 图表 可以有 多个 y 坐标轴,这里指定索引0的y轴)
showInLegend: true, //
name: 'preFish', // 根据 函数传入的 参数 label 设置
lineWidth: 1,
data: [], // 数据序列的数据项
tooltip: { // 工具提示
valueDecimals: 2 // 值的小数点 保留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
}
}
}
}

Do đó, việc nghiên cứu dữ liệu, hiển thị đồ họa và thiết kế chiến lược trên FMZ rất thuận tiện. Đây chỉ là điểm khởi đầu, giáo viên và học sinh có thể để lại bình luận.