avatar of 发明者量化-小小梦 发明者量化-小小梦
フォロー ダイレクトメッセージ
4
フォロー
1271
フォロワー

フィッシャー指標の JavaScript 言語実装と FMZ での描画

作成日:: 2021-12-27 09:51:39, 更新日:: 2024-12-02 21:37:27
comments   0
hits   1434

フィッシャー指標の JavaScript 言語実装と FMZ での描画

フィッシャー指標の JavaScript 言語実装と FMZ での描画

トレーディングにおいてテクニカル分析を行う際、トレーダーは株価データを正規分布データとして分析し研究します。しかし、株価データの分布は標準正規分布に従いません。Fisher Transformation価格データを正規分布に変換できる手法です。Fisher Transformation市場データを平滑化し、急激な小周期の振動を排除します。当日と前日の指標のクロスオーバーを使用して、取引シグナルを生成できます。

についてFisher TransformBaidu と Zhihu には多くの情報が掲載されているので、ここでは詳細には触れません。

インジケーターアルゴリズム:

  • 本日の中間価格:

mid=(low + high) / 2

  • 計算期間を決定します。期間として 10 日間を使用できます。期間内の最高価格と最低価格を計算します。

lowestLow = 周期内最低价highestHigh = 周期内最高价

  • 価格変更パラメータを定義する(ここでratioは0から1の間の定数(例えば0.5や0.33)です。

フィッシャー指標の JavaScript 言語実装と FMZ での描画

  • 価格変更パラメータx使用Fisher変換して取得Fisher索引:

フィッシャー指標の JavaScript 言語実装と FMZ での描画

JavaScriptを使用してアルゴリズムを実装する

インジケーターのアルゴリズムに従って段階的に実装します。このアルゴリズムは反復アルゴリズムであることに注意してください。preXpreFish最初は 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での描画は非常に簡単です、Strategy Square:https://www.fmz.com/square上記には参照または検索用の例が多数あります。 記事が長いため、次の描画テスト コードを実行するには、上記の calcFisher 関数の実装を追加する必要があります。

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
            }
        }
    }
}

フィッシャー指標の JavaScript 言語実装と FMZ での描画

したがって、FMZ でデータを研究したり、グラフィックを表示したり、戦略を設計したりするのは非常に便利です。 これは単なる出発点であり、教師と生徒の皆さんはコメントを残すことを歓迎します。