وسائل لوڈ ہو رہے ہیں... لوڈنگ...

ایک کثیر چارٹ پلاٹنگ لائبریری ڈیزائن کریں

مصنف:نینا باداس, تخلیق: 2022-04-06 09:16:48, تازہ کاری:

ایک کثیر چارٹ پلاٹنگ لائبریری ڈیزائن کریں

اس قسم کی لائبریری اکثر لکھنے اور حکمت عملی ڈیزائن کرتے وقت چارٹ اور پلاٹ بنانے کے لئے استعمال کیا جاتا ہے. ایک واحد اپنی مرضی کے مطابق چارٹ کے لئے، ہم استعمال کر سکتے ہیںplotting لائبریری(صارفین جو ایف ایم زیڈ پر ٹیمپلیٹ لائبریری کے تصور سے واقف نہیں ہیں وہ ایف ایم زیڈ اے پی آئی دستاویزات چیک کرسکتے ہیں) ، جو پلاٹنگ آپریشنز کے لئے بہت آسان ہے۔ تاہم ، ایسے منظرناموں کے لئے جن میں متعدد چارٹ کی ضرورت ہوتی ہے ، یہ ٹیمپلیٹ لائبریری ضروریات کو پورا نہیں کرسکتی ہے۔ پھر ہم اس پلاٹنگ لائبریری کے ڈیزائن خیالات سیکھتے ہیں ، اور اس کی بنیاد پر ، پلاٹنگ لائبریری کا ملٹی چارٹ ورژن ڈیزائن کرتے ہیں۔

ٹیمپلیٹ لائبریری کے برآمد افعال ڈیزائن

plot Library کے ایکسپورٹ فنکشن ڈیزائن سے سیکھ کر ہم ملٹی چارٹ پلاٹنگ لائبریری کے لیے بھی اسی طرح کے ایکسپورٹ فنکشن ڈیزائن کر سکتے ہیں۔

  • $، پلاٹMultRecords K لائن چارٹ تیار کرنے کے لئے استعمال کیا جاتا ہے، ڈیزائن پیرامیٹرز: cfgName، seriesName، records، extension。 cfgName: ایک واحد چارٹ کے طور پر، تشکیل شدہ اعتراض کا نام؛
    سیریز نام: ڈیٹا سیریز کا نام جس میں فی الحال K لائنیں کھینچنے کی ضرورت ہے۔ ریکارڈ: K لائن کے اعداد و شمار جو منتقل کیے گئے ہیں؛ توسیع: چارٹ کے طول و عرض کی ترتیب کی معلومات، مثال کے طور پر: پاس{layout: 'single', col: 6, height: '600px'}، یعنی، صرف چوڑائی: 6، اونچائی: 600px ظاہر کرنے کے لئے cfgName کے تشکیل کردہ اعتراض کا نام کے ساتھ چارٹ کی درخواست کریں.

  • $.plotMultLine لائنیں کھینچنے کے لئے استعمال کیا جاتا ہے، ڈیزائن پیرامیٹرز: cfgName، seriesName، dot، ts، توسیع cfgName: ایک واحد چارٹ کے طور پر، تشکیل شدہ اعتراض کا نام؛ سیریز نام: ڈیٹا سیریز کا نام جس میں اس وقت لائنیں کھینچنے کی ضرورت ہے۔ ڈاٹ: کھینچنے والی لکیروں پر ڈاٹ کی ترتیب شدہ قیمت۔ ts: ٹائم اسٹیمپ، یعنی ایکس ٹائم ایکسس پر ویلیو توسیع: چارٹ کے طول و عرض کی ترتیب کی معلومات۔

  • $.plotMultHLine افقی لائنیں کھینچنے کے لئے استعمال کیا جاتا ہے۔ ڈیزائن کردہ پیرامیٹرز: cfgName, value, label, color, style cfgName: چارٹ میں تشکیل شدہ آبجیکٹ؛ قدر: افقی لائن کی ترتیب کی قدر؛ لیبل: افقی لائن پر دکھائے جانے والے متن؛ رنگ: لائن کا رنگ انداز: لائن سٹائل، مثال کے طور پر:Solid ShortDash ShortDot ShortDashDot ShortDashDotDot Dot Dash LongDash DashDot LongDashDot LongDashDotDot.

  • $، پلاٹMultTitle چارٹ کے عنوان اور ذیلی عنوان کو تبدیل کرنے کے لئے استعمال کیا جاتا ہے۔ ڈیزائن کردہ پیرامیٹرز: cfgName, title, chartTitle cfgName: تشکیل شدہ آبجیکٹ کا نام؛ عنوان: ذیلی عنوان چارٹ عنوان: چارٹ کا عنوان۔

  • $.plotMultFlag جھنڈا تیار کرنے کے لئے استعمال کیا جاتا ہے۔ ڈیزائن کردہ پیرامیٹرز: cfgName, seriesName, ts, text, title, shape, color, onSeriesName cfgName: چارٹ میں تشکیل شدہ آبجیکٹ؛ سیریز نام: ڈیٹا سیریز کا نام؛ ts: ٹائم اسٹیمپ؛ متن: پرچم میں متن؛ عنوان: پرچم کا عنوان؛ شکل: پرچم کی شکل رنگ: پرچم کا رنگ onSeriesName: یہ اس بات پر مبنی ہے کہ کس ڈیٹا سیریز پر دکھایا جائے گا۔ قدر ڈیٹا سیریز کی شناخت ہے۔

  • $.GetArrCfg چارٹ کی تشکیل شدہ آبجیکٹ صف واپس کرنے کے لئے استعمال کیا جاتا ہے.

ڈیزائن ٹیسٹ افعال

آسانی سے سمجھنے کے لئے، میں نے ٹیسٹ افعال پر براہ راست تبصرے لکھے ہیں، ہر فنکشن کال کیا کرتا ہے کی وضاحت.

// test
function main() {
    LogReset(10)
    var i = 0 
    var prePrintTs = 0

    while (true) {
        var r = exchange.GetRecords()   // Get K-line data
        var t = exchange.GetTicker()    // Get the real-time tick data 

        $.PlotMultRecords("chart1", "kline1", r, {layout: 'single', col: 6, height: '600px'})   // Create a K-line chart named chart1, and display it solely; the width is 6, and the height is 600px; the K-line data series name is kline1, and use r obtained above as the data source to draw the chart
        $.PlotMultRecords("chart2", "kline2", r, {layout: 'single', col: 6, height: '600px'})   // Craete the second K-line chart, named chart2
        $.PlotMultLine("chart2", "line1", t.Last, r[r.length - 1].Time)  // Add a line to the K-line chart, namely chart2, the name of the data series is line1, and use the Last of the real-time tick data as the Y value of the dot on the line. The timestamp of the last BAR of the K-line data is used as the X value
        $.PlotMultLine("chart3", "line2", t.Last)   // Create a chart named chart3 that only draws lines, with data series name line2; use the Last of real-time tick data to draw a dot at the current time (X value) (t.Last is Y value); note that the chart is not displayed solely
        $.PlotMultLine("chart6", "line6", t.Time)   // Create a chart chart6 that only draws lines; note that the chart is not displayed solely, it will be displayed with chart3 on pagination 
        $.PlotMultLine("chart4", "line3", t.Sell, new Date().getTime(), {layout: 'single', col: 4, height: '300px'})  // Create a chart named chart4 that only draws lines, solely displayed, width 4, height 300px
        $.PlotMultLine("chart5", "line4", t.Volume, new Date().getTime(), {layout: 'single', col: 8, height: '300px'})  // Create a chart named chart5 that only draws lines, solely displayed, width 8, height 300px  

        $.PlotMultHLine("chart1", r[r.length - 1].Close, "HLine1", "blue", "ShortDot")   // Add horizontal lines in chart1
        $.PlotMultHLine("chart4", t.Sell, "HLine2", "green")  // Add horizontal lines in chart4
        $.PlotMultTitle("chart3", "change : chart3->test1", "test1")   // Modify the title of chart3

        var ts = new Date().getTime()
        if (ts - prePrintTs > 1000 * 20) {
            prePrintTs = ts 
            // when triggered, draw a flag on chart3
            $.PlotMultFlag("chart3", "flag1", new Date().getTime(), "flag test", "flag1")
        }
        
        if (i == 10) {
            Log("i == 10")
            // when triggered, draw a flag on chart4, and chart1
            $.PlotMultFlag("chart4", "flag2", new Date().getTime(), "flag test", "flag2")
            $.PlotMultFlag("chart1", "flag3", new Date().getTime(), "flag test", "flag3", "squarepin", "green", "kline1")
        } else if (i == 20) {
            Log("i == 20")
            // when triggered, add a line on chart1, but only draw a dot of the line; X coordinate is timestamp, and Y coordinate is the value of t.Last 
            $.PlotMultLine("chart1", "line5", t.Last, r[r.length - 1].Time)
        } else if (i == 30) {
            Log("i == 30")
            // when triggered, draw a flag on chart2 
            $.PlotMultFlag("chart2", "flag4", new Date().getTime(), "flag test", "flag4", "circlepin", "black", "kline2")
        }
        
        Sleep(1000 * 5)
        i++
    }
}

آپریشن ٹیسٹ

img

img

آپ دیکھ سکتے ہیں کہ فنکشن کال کی صرف ایک سطر کے ساتھ، آپ آسانی سے ایک چارٹ ڈرا سکتے ہیں، اور آپ ایک ہی وقت میں کئی قسم کے چارٹ دکھا سکتے ہیں.

مکمل حکمت عملی کا ماخذ کوڈ

پیرامیٹر کی ترتیبات:img

حکمت عملی کے ماخذ کوڈ کا نفاذ:

var registerInfo = {}
var chart = null 
var arrCfg = []

function updateSeriesIdx() {
    var index = 0
    var map = {}
    _.each(arrCfg, function(cfg) {
        _.each(cfg.series, function(series) {
            var key = cfg.name + "|" + series.name
            map[key] = index
            index++
        })
    })

    for (var cfgName in registerInfo) {
        for (var i in registerInfo[cfgName].seriesIdxs) {
            var seriesName = registerInfo[cfgName].seriesIdxs[i].seriesName
            var key = cfgName + "|" + seriesName
            if (map[key]) {
                registerInfo[cfgName].seriesIdxs[i].index = map[key]
            }

            // Reset preBarTime of K-line data
            if (registerInfo[cfgName].seriesIdxs[i].type == "candlestick") {
                registerInfo[cfgName].seriesIdxs[i].preBarTime = 0
            } else if (registerInfo[cfgName].seriesIdxs[i].type == "line") {
                registerInfo[cfgName].seriesIdxs[i].preDotTime = 0
            } else if (registerInfo[cfgName].seriesIdxs[i].type == "flag") {
                registerInfo[cfgName].seriesIdxs[i].preFlagTime = 0
            }
        }
    }
    
    if (!chart) {
        chart = Chart(arrCfg)
    }
    chart.update(arrCfg)
    chart.reset()

    _G("registerInfo", registerInfo)
    _G("arrCfg", arrCfg)

    for (var cfgName in registerInfo) {
        for (var i in registerInfo[cfgName].seriesIdxs) {
            var buffer = registerInfo[cfgName].seriesIdxs[i].buffer            
            var index = registerInfo[cfgName].seriesIdxs[i].index
            if (buffer && buffer.length != 0 && registerInfo[cfgName].seriesIdxs[i].type == "line" && registerInfo[cfgName].seriesIdxs[i].preDotTime == 0) {                
                _.each(buffer, function(obj) {
                    chart.add(index, [obj.ts, obj.dot])
                    registerInfo[cfgName].seriesIdxs[i].preDotTime = obj.ts
                })
            } else if (buffer && buffer.length != 0 && registerInfo[cfgName].seriesIdxs[i].type == "flag" && registerInfo[cfgName].seriesIdxs[i].preFlagTime == 0) {
                _.each(buffer, function(obj) {
                    chart.add(index, obj.data)
                    registerInfo[cfgName].seriesIdxs[i].preFlagTime = obj.ts
                })
            }
        }
    }
}

function checkBufferLen(buffer, maxLen) {
    while (buffer.length > maxLen) {
        buffer.shift()
    }
}

$.PlotMultRecords = function(cfgName, seriesName, records, extension) {
    if (typeof(cfgName) == "undefined") {
        throw "need cfgName!"
    }

    var index = -1
    var eleIndex = -1

    do {
        var cfgInfo = registerInfo[cfgName]
        if (typeof(cfgInfo) == "undefined") {
            var cfg = {
                name : cfgName,
                __isStock: true,
                title : {
                    text: cfgName
                },
                tooltip: {
                    xDateFormat: '%Y-%m-%d %H:%M:%S, %A'
                },
                legend: {
                    enabled: true,
                },
                plotOptions: {
                    candlestick: {
                        color: '#d75442',
                        upColor: '#6ba583'
                    }
                },
                rangeSelector: {
                    buttons: [{
                        type: 'hour',
                        count: 1,
                        text: '1h'
                    }, {
                        type: 'hour',
                        count: 3,
                        text: '3h'
                    }, {
                        type: 'hour',
                        count: 8,
                        text: '8h'
                    }, {
                        type: 'all',
                        text: 'All'
                    }],
                    selected: 2,
                    inputEnabled: true
                },
                series: [{
                    type: 'candlestick',
                    name: seriesName,
                    id: seriesName,
                    data: []
                }],
            }    

            if (typeof(extension) != "undefined") {
                cfg.extension = extension
            }    

            registerInfo[cfgName] = {
                "cfgIdx" : arrCfg.length,                                                                               
                "seriesIdxs" : [{seriesName: seriesName, index: arrCfg.length, type: "candlestick", preBarTime: 0}],    
            }
            arrCfg.push(cfg)
            updateSeriesIdx()
        }    

        if (!chart) {
            chart = Chart(arrCfg)
        } else {
            chart.update(arrCfg)
        }

        _.each(registerInfo[cfgName].seriesIdxs, function(ele, i) {
            if (ele.seriesName == seriesName && ele.type == "candlestick") {
                index = ele.index
                eleIndex = i
            }
        })
        if (index == -1) {
            arrCfg[registerInfo[cfgName].cfgIdx].series.push({
                type: 'candlestick',
                name: seriesName,
                id: seriesName,
                data: []
            })
            registerInfo[cfgName].seriesIdxs.push({seriesName: seriesName, index: arrCfg.length, type: "candlestick", preBarTime: 0})
            updateSeriesIdx()
        }
    } while (index == -1)

    for (var i = 0 ; i < records.length ; i++) {
        if (records[i].Time == registerInfo[cfgName].seriesIdxs[eleIndex].preBarTime) {
            chart.add(index, [records[i].Time, records[i].Open, records[i].High, records[i].Low, records[i].Close], -1)
        } else if (records[i].Time > registerInfo[cfgName].seriesIdxs[eleIndex].preBarTime) {
            registerInfo[cfgName].seriesIdxs[eleIndex].preBarTime = records[i].Time
            chart.add(index, [records[i].Time, records[i].Open, records[i].High, records[i].Low, records[i].Close])
        }
    }
    
    return chart
}

$.PlotMultLine = function(cfgName, seriesName, dot, ts, extension) {
    if (typeof(cfgName) == "undefined") {
        throw "need cfgName!"
    }

    var index = -1
    var eleIndex = -1

    do {
        var cfgInfo = registerInfo[cfgName]
        if (typeof(cfgInfo) == "undefined") {
            var cfg = {
                name : cfgName,
                __isStock: true,
                title : {
                    text: cfgName
                },
                xAxis: {
                    type: 'datetime'
                },
                series: [{
                    type: 'line',
                    name: seriesName,
                    id: seriesName,
                    data: [],
                }]
            }    

            if (typeof(extension) != "undefined") {
                cfg.extension = extension
            }    

            registerInfo[cfgName] = {
                "cfgIdx" : arrCfg.length,
                "seriesIdxs" : [{seriesName: seriesName, index: arrCfg.length, type: "line", buffer: [], preDotTime: 0}], 
            }
            arrCfg.push(cfg)
            updateSeriesIdx()
        }    

        if (!chart) {
            chart = Chart(arrCfg)
        } else {
            chart.update(arrCfg)
        }

        _.each(registerInfo[cfgName].seriesIdxs, function(ele, i) {
            if (ele.seriesName == seriesName && ele.type == "line") {
                index = ele.index
                eleIndex = i
            }
        })
        if (index == -1) {
            arrCfg[registerInfo[cfgName].cfgIdx].series.push({
                type: 'line',
                name: seriesName,
                id: seriesName,
                data: [],
            })
            registerInfo[cfgName].seriesIdxs.push({seriesName: seriesName, index: arrCfg.length, type: "line", buffer: [], preDotTime: 0})
            updateSeriesIdx()
        }
    } while (index == -1)

    if (typeof(ts) == "undefined") {
        ts = new Date().getTime()
    }

    var buffer = registerInfo[cfgName].seriesIdxs[eleIndex].buffer
    if (registerInfo[cfgName].seriesIdxs[eleIndex].preDotTime != ts) {
        registerInfo[cfgName].seriesIdxs[eleIndex].preDotTime = ts
        chart.add(index, [ts, dot])
        buffer.push({ts: ts, dot: dot})       
        checkBufferLen(buffer, maxBufferLen)  
    } else {
        chart.add(index, [ts, dot], -1)
        buffer[buffer.length - 1].dot = dot   
    }

    return chart
}

$.PlotMultHLine = function(cfgName, value, label, color, style) {
    if (typeof(cfgName) == "undefined" || typeof(registerInfo[cfgName]) == "undefined") {
        throw "need cfgName!"
    }

    var cfg = arrCfg[registerInfo[cfgName].cfgIdx]
    if (typeof(cfg.yAxis) == "undefined") {
        cfg.yAxis = {
            plotLines: []
        }
    } else if (typeof(cfg.yAxis.plotLines) == "undefined") {
        cfg.yAxis.plotLines = []
    }

    var obj = {
        value: value,
        color: color || 'red',
        width: 2,
        dashStyle: style || 'Solid',
        label: {
            text: label || '',
            align: 'center'
        },
    }
    var found = false 
    for (var i = 0; i < cfg.yAxis.plotLines.length; i++) {
        if (cfg.yAxis.plotLines[i].label.text == label) {
            cfg.yAxis.plotLines[i] = obj
            found = true
        }
    }

    if (!found) {
        cfg.yAxis.plotLines.push(obj)
    }
    if (!chart) {
        chart = Chart(arrCfg)
    } else {
        chart.update(arrCfg)
    }

    return chart
}

$.PlotMultTitle = function(cfgName, title, chartTitle) {
    if (typeof(cfgName) == "undefined" || typeof(registerInfo[cfgName]) == "undefined") {
        throw "need cfgName!"
    }

    var cfg = arrCfg[registerInfo[cfgName].cfgIdx]

    cfg.subtitle = {
        text: title
    }

    if (typeof(chartTitle) !== 'undefined') {
        cfg.title = {
            text: chartTitle
        }
    }

    if (chart) {
        chart.update(arrCfg)
    }

    return chart
}

$.PlotMultFlag = function(cfgName, seriesName, ts, text, title, shape, color, onSeriesName) {
    if (typeof(cfgName) == "undefined" || typeof(registerInfo[cfgName]) == "undefined") {
        throw "need cfgName!"
    }

    var index = -1
    var eleIndex = -1

    do {
        if (!chart) {
            chart = Chart(arrCfg)
        } else {
            chart.update(arrCfg)
        }

        _.each(registerInfo[cfgName].seriesIdxs, function(ele, i) {
            if (ele.seriesName == seriesName && ele.type == "flag") {
                index = ele.index
                eleIndex = i
            }
        })
        if (index == -1) {
            arrCfg[registerInfo[cfgName].cfgIdx].series.push({
                type: 'flags',
                name: seriesName,
                onSeries: onSeriesName || arrCfg[registerInfo[cfgName].cfgIdx].series[0].id,
                data: []
            })
            registerInfo[cfgName].seriesIdxs.push({seriesName: seriesName, index: arrCfg.length, type: "flag", buffer: [], preFlagTime: 0})
            updateSeriesIdx()
        }
    } while(index == -1)
    
    if (typeof(ts) == "undefined") {
        ts = new Date().getTime()
    }

    var buffer = registerInfo[cfgName].seriesIdxs[eleIndex].buffer
    var obj = {x: ts, color: color, shape: shape, title: title, text: text}
    if (registerInfo[cfgName].seriesIdxs[eleIndex].preFlagTime != ts) {
        registerInfo[cfgName].seriesIdxs[eleIndex].preFlagTime = ts
        chart.add(index, obj)
        buffer.push({ts: ts, data: obj})
        checkBufferLen(buffer, maxBufferLen)
    } else {
        chart.add(index, obj, -1)
        buffer[buffer.length - 1].data = obj
    }

    return chart
}

$.GetArrCfg = function() {
    return arrCfg
}

function init() {
    if (isChartReset) {
        Log("Reset the chart", "#FF0000")
        chart = Chart(arrCfg)
        chart.reset()

        Log("Empty the persistent data, key:", "registerInfo、arrCfg #FF0000")
        _G("registerInfo", null)
        _G("arrCfg", null)
    } else {
        var multChartRegisterInfo = _G("registerInfo")
        var multChartArrCfg = _G("arrCfg")
        if (multChartRegisterInfo && multChartArrCfg) {
            registerInfo = multChartRegisterInfo
            arrCfg = multChartArrCfg
            Log("Recover registerInfo、arrCfg #FF0000")
        } else {
            Log("No data can be recovered #FF0000")
        }
    }
}

function onexit() {
    _G("registerInfo", registerInfo)
    _G("arrCfg", arrCfg)
    Log("Save data, key : registerInfo, arrCfg #FF0000")
}


// test
function main() {
    LogReset(10)
    var i = 0 
    var prePrintTs = 0

    while (true) {
        var r = exchange.GetRecords()
        var t = exchange.GetTicker()

        $.PlotMultRecords("chart1", "kline1", r, {layout: 'single', col: 6, height: '600px'})
        $.PlotMultRecords("chart2", "kline2", r, {layout: 'single', col: 6, height: '600px'})
        $.PlotMultLine("chart2", "line1", t.Last, r[r.length - 1].Time)
        $.PlotMultLine("chart3", "line2", t.Last)
        $.PlotMultLine("chart6", "line6", t.Time)
        $.PlotMultLine("chart4", "line3", t.Sell, new Date().getTime(), {layout: 'single', col: 4, height: '300px'})
        $.PlotMultLine("chart5", "line4", t.Volume, new Date().getTime(), {layout: 'single', col: 8, height: '300px'})       

        $.PlotMultHLine("chart1", r[r.length - 1].Close, "HLine1", "blue", "ShortDot")
        $.PlotMultHLine("chart4", t.Sell, "HLine2", "green")
        $.PlotMultTitle("chart3", "change : chart3->test1", "test1")

        var ts = new Date().getTime()
        if (ts - prePrintTs > 1000 * 20) {
            prePrintTs = ts 
            $.PlotMultFlag("chart3", "flag1", new Date().getTime(), "flag test", "flag1")
        }
        
        if (i == 10) {
            Log("i == 10")
            $.PlotMultFlag("chart4", "flag2", new Date().getTime(), "flag test", "flag2")
            $.PlotMultFlag("chart1", "flag3", new Date().getTime(), "flag test", "flag3", "squarepin", "green", "kline1")
        } else if (i == 20) {
            Log("i == 20")
            $.PlotMultLine("chart1", "line5", t.Last, r[r.length - 1].Time)
        } else if (i == 30) {
            Log("i == 30")
            $.PlotMultFlag("chart2", "flag4", new Date().getTime(), "flag test", "flag4", "circlepin", "black", "kline2")
        }
        
        Sleep(1000 * 5)
        i++
    }
}

حکمت عملی کا پتہ:https://www.fmz.com/strategy/353264

یہاں میں صرف اس کا استعمال بحث اور موضوع کے بارے میں سوچنے کے لئے کرتا ہوں۔ اگر آپ دلچسپی رکھتے ہیں تو ، آپ معاون چارٹ کی اقسام (جیسے مارکیٹ کی گہرائی کا چارٹ ، بار گراف اور پائی چارٹ وغیرہ) میں اضافہ کرسکتے ہیں اور اپ گریڈ کرتے رہ سکتے ہیں۔


مزید