目前不清退的交易所推荐:
1、全球第二大交易所OKX欧意
国区邀请链接: https://www.myts3cards.com/cn/join/1837888 币种多,交易量大!
国际邀请链接:https://www.okx.com/join/1837888 注册简单,交易不需要实名,新用户能开合约,币种多,交易量大!
2、老牌交易所比特儿现改名叫芝麻开门 :https://www.gate.win/signup/649183
全球最大交易所币安,国区邀请链接:https://accounts.binance.com/zh-CN/register?ref=16003031 币安注册不了IP地址用香港,居住地选香港,认证照旧,邮箱推荐如gmail、outlook。支持币种多,交易安全!
买好币上KuCoin:https://www.kucoin.com/r/af/1f7w3 CoinMarketCap前五的交易所,注册友好操简单快捷!
FMZ量化交易平台邀请链接:https://www.fmz.com/
Fisher指标的JavaScript语言实现以及在FMZ上画图
交易中技术分析的时候,交易者都把股价数据作为正态分布的数据来分析、研究。不过,股价数据分布并不符合标准的正态分布。Fisher Transformation
就是一个可以把价格数据转换为类似于正态分布的方法。Fisher Transformation
将市场数据平滑,剔除一些尖锐的小周期振荡。利用当日和前一日的指标交错可以发出交易信号。
关于Fisher Transform
的资料百度、知乎很多,这里不再赘述。
指标算法:
- 今日中间价:
mid=(low + high) / 2
- 确定计算周期,可使用10日为周期。计算周期内最高价和最低价:
lowestLow = 周期内最低价
,highestHigh = 周期内最高价
。
- 定义价变参数(其中的
ratio
为0-1之间常数,例如可取0.5或0.33):
- 对价变参数
x
使用Fisher
变换,得到Fisher
指标:
使用JavaScript语言实现该算法
按照该指标算法逐步实现。需要注意的是这个算法是一个迭代算法,对于preX
,preFish
开始都置为0。对于Math.log
就是求以自然常数e为底的对数。另外在上面算法中未提及对于x的修正,我在编写时也差点忽略掉这个问题:
修正x的值,大于0.99就强制设置为0.999。小于-0.99同理。
if (x > 0.99) {
x = 0.999
} else if (x < -0.99) {
x = -0.999
}
第一次看这个算法、指标,按照算法移植出来之后。该实现我也并未验证,有兴趣研究的同学可以验证下有无错误。非常感谢指出错误。
Fisher Transform
指标算法源码:
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
}
画图
在FMZ上画图就很简单了,策略广场:https://www.fmz.com/square
上面有大把的例子可以参考,也可以搜索。
var cfg = { // 用来初始化设置图表的对象(即图表设置)
plotOptions: {
candlestick: {
color: \'#d75442\', // 颜色值
upColor: \'#6ba583\' // 颜色值
}
},
title: { text: \'Fisher Transform\'}, //标题
subtitle: {text: \'\'}, //副标题
plotOptions: {
candlestick: {
tooltip: {
pointFormat:
\'\\u25CF {series.name}
\' +
\'开盘: {point.open}
\' +
\'最高: {point.high}
\' +
\'最低: {point.low}
\' +
\'收盘: {point.close}
\'
}
}
},
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
}
}
}
}
所以在FMZ上研究数据、图形显示、设计策略是非常方便的。
这里抛砖引玉,欢迎各位老师、同学留言。
FMZ量化交易平台邀请链接:https://www.fmz.com/
全球最大交易所币安,国区邀请链接:https://accounts.binance.com/zh-CN/register?ref=16003031 币安注册不了IP地址用香港,居住地选香港,认证照旧,邮箱推荐如gmail、outlook。支持币种多,交易安全!
买好币上KuCoin:https://www.kucoin.com/r/af/1f7w3 CoinMarketCap前五的交易所,注册友好操简单快捷!
目前不清退的交易所推荐:
1、全球第二大交易所OKX欧意,邀请链接:https://www.myts3cards.com/cn/join/1837888 注册简单,交易不需要实名,新用户能开合约,币种多,交易量大!。
2、老牌交易所比特儿现改名叫芝麻开门 :https://www.gate.win/signup/649183
买好币上币库:https://www.kucoin.com/r/1f7w3
火必所有用户现在可用了,但是要重新注册账号火币:https://www.huobi.com
全球最大交易所币安,
国区邀请链接:https://accounts.suitechsui.mobi/zh-CN/register?ref=16003031 支持86手机号码,网页直接注册。
Fisher Transformation
就是一个可以把价格数据转换为类似于正态分布的方法。Fisher Transformation
将市场数据平滑,剔除一些尖锐的小周期振荡。利用当日和前一日的指标交错可以发出交易信号。Fisher Transform
的资料百度、知乎很多,这里不再赘述。mid=(low + high) / 2
lowestLow = 周期内最低价
,highestHigh = 周期内最高价
。ratio
为0-1之间常数,例如可取0.5或0.33):x
使用Fisher
变换,得到Fisher
指标:preX
,preFish
开始都置为0。对于Math.log
就是求以自然常数e为底的对数。另外在上面算法中未提及对于x的修正,我在编写时也差点忽略掉这个问题: if (x > 0.99) {
x = 0.999
} else if (x < -0.99) {
x = -0.999
}
Fisher Transform
指标算法源码: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
}
https://www.fmz.com/square
上面有大把的例子可以参考,也可以搜索。var cfg = { // 用来初始化设置图表的对象(即图表设置)
plotOptions: {
candlestick: {
color: \'#d75442\', // 颜色值
upColor: \'#6ba583\' // 颜色值
}
},
title: { text: \'Fisher Transform\'}, //标题
subtitle: {text: \'\'}, //副标题
plotOptions: {
candlestick: {
tooltip: {
pointFormat:
\'\\u25CF {series.name}
\' +
\'开盘: {point.open}
\' +
\'最高: {point.high}
\' +
\'最低: {point.low}
\' +
\'收盘: {point.close}
\'
}
}
},
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
}
}
}
}
这里抛砖引玉,欢迎各位老师、同学留言。
买好币上KuCoin:https://www.kucoin.com/r/af/1f7w3 CoinMarketCap前五的交易所,注册友好操简单快捷!
目前不清退的交易所推荐:
1、全球第二大交易所OKX欧意,邀请链接:https://www.myts3cards.com/cn/join/1837888 注册简单,交易不需要实名,新用户能开合约,币种多,交易量大!。
2、老牌交易所比特儿现改名叫芝麻开门 :https://www.gate.win/signup/649183
买好币上币库:https://www.kucoin.com/r/1f7w3