avatar of 发明者量化-小小梦 发明者量化-小小梦
پر توجہ دیں نجی پیغام
4
پر توجہ دیں
1271
پیروکار

ملٹی چارٹ لائن ڈرائنگ لائبریری ڈیزائن کریں۔

میں تخلیق کیا: 2022-03-31 11:28:35, تازہ کاری: 2023-09-20 10:04:46
comments   2
hits   1675

ملٹی چارٹ لائن ڈرائنگ لائبریری ڈیزائن کریں۔

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

“ٹیمپلیٹ لائبریری” کے ڈیزائن ایکسپورٹ افعال

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

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

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

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

  • $.PlotMultTitle چارٹ کے عنوان اور ذیلی عنوان میں ترمیم کرنے کے لیے استعمال کیا جاتا ہے۔ پیرامیٹر ڈیزائن: cfgName، عنوان، چارٹ ٹائٹل cfgName : چارٹ کنفیگریشن آبجیکٹ کا نام۔ عنوان: ذیلی عنوان۔ چارٹ ٹائٹل : چارٹ ٹائٹل۔

  • $.PlotMultFlag ایک چھوٹا جھنڈا آئیکن، پیرامیٹر ڈیزائن: cfgName، seriesName، ts، متن، عنوان، شکل، رنگ، onSeriesName cfgName : چارٹ کنفیگریشن آبجیکٹ کا نام۔ سیریز کا نام: ڈیٹا سیریز کا نام۔ ts : ٹائم اسٹیمپ متن: چھوٹے آئیکن میں متن۔ عنوان: چھوٹے آئیکن کا عنوان۔ شکل: چھوٹے آئیکن کی شکل۔ رنگ: چھوٹے آئیکن کا رنگ۔ onSeriesName : جس ڈیٹا سیریز کو ظاہر کیا جاتا ہے اس کی بنیاد پر، ویلیو ڈیٹا سیریز کی id ہے۔

  • $.GetArrCfg چارٹ کنفیگریشن آبجیکٹ کی ایک صف لوٹاتا ہے۔

ٹیسٹ فنکشن ڈیزائن

اس کو سمجھنے میں آسانی پیدا کرنے کے لیے، میں نے ٹیسٹ فنکشنز پر براہ راست تبصرے لکھے تاکہ یہ سمجھا جا سکے کہ ہر فنکشن کال کیا کرتی ہے۔

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

    while (true) {
        var r = exchange.GetRecords()   // 获取K线数据
        var t = exchange.GetTicker()    // 获取实时的tick数据

        $.PlotMultRecords("chart1", "kline1", r, {layout: 'single', col: 6, height: '600px'})   // 创建一个名为chart1的K线图表,独立显示,宽度是6,高度是600px,K线数据系列名称为kline1,使用上面获取的r作为数据源画图
        $.PlotMultRecords("chart2", "kline2", r, {layout: 'single', col: 6, height: '600px'})   // 创建第二个K线图表,名为chart2
        $.PlotMultLine("chart2", "line1", t.Last, r[r.length - 1].Time)  // 在K线图表即chart2上增加一条线,数据系列名称为line1,使用当前的tick数据的最新价Last作为线上的点的Y值。K线数据的最后一个BAR的时间戳作为X值
        $.PlotMultLine("chart3", "line2", t.Last)   // 创建一个只画线的图表,图表名称chart3,数据系列名称line2,使用实时tick数据的Last最新价格在当前时间(X值)画一个点(t.Last为Y值),注意图表不是独立显示
        $.PlotMultLine("chart6", "line6", t.Time)   // 创建一个只画线的图表chart6,注意图表不是独立显示,会和chart3在一起分页显示
        $.PlotMultLine("chart4", "line3", t.Sell, new Date().getTime(), {layout: 'single', col: 4, height: '300px'})  // 创建一个只画线的图表chart4,独立显示,宽度4,高度300px
        $.PlotMultLine("chart5", "line4", t.Volume, new Date().getTime(), {layout: 'single', col: 8, height: '300px'})  // 创建一个只画线的图表chart5,独立显示,宽度8,高度300px     

        $.PlotMultHLine("chart1", r[r.length - 1].Close, "HLine1", "blue", "ShortDot")   // 给图表chart1增加水平横线
        $.PlotMultHLine("chart4", t.Sell, "HLine2", "green")  // 给图表chart4增加水平横线
        $.PlotMultTitle("chart3", "change : chart3->test1", "test1")   // 修改chart3的标题

        var ts = new Date().getTime()
        if (ts - prePrintTs > 1000 * 20) {
            prePrintTs = ts 
            // 触发时,给chart3图表上画小图标
            $.PlotMultFlag("chart3", "flag1", new Date().getTime(), "flag test", "flag1")
        }
        
        if (i == 10) {
            Log("i == 10")
            // 触发时,给chart4,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")
            // 触发时,给chart1上添加一条线,但是只画了这条线的一个点,X坐标时间戳,Y坐标为t.Last值
            $.PlotMultLine("chart1", "line5", t.Last, r[r.length - 1].Time)
        } else if (i == 30) {
            Log("i == 30")
            // 触发时,给chart2上画小图标
            $.PlotMultFlag("chart2", "flag4", new Date().getTime(), "flag test", "flag4", "circlepin", "black", "kline2")
        }
        
        Sleep(1000 * 5)
        i++
    }
}

رننگ ٹیسٹ

ملٹی چارٹ لائن ڈرائنگ لائبریری ڈیزائن کریں۔

ملٹی چارٹ لائن ڈرائنگ لائبریری ڈیزائن کریں۔

آپ دیکھ سکتے ہیں کہ فنکشن کالز کی صرف ایک لائن کے ساتھ، آپ آسانی سے ایک چارٹ بنا سکتے ہیں، اور آپ ایک ہی وقت میں متعدد چارٹ دکھا سکتے ہیں۔

مکمل حکمت عملی سورس کوڈ

پیرامیٹر ترتیب: ملٹی چارٹ لائن ڈرائنگ لائبریری ڈیزائن کریں۔

کلاس لائبریری سورس کوڈ کا نفاذ:


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) {
        _.each(arrCfg, function(cfg, cfgIdx) {
            if (cfg.name == cfgName) {
                registerInfo[cfgName].cfgIdx = cfgIdx
            }
        })

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

            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: {
            name: label || '',
            text: (label + ":" + value) || '',
            align: 'center'
        },
    }
    var found = false
    for (var i = 0; i < cfg.yAxis.plotLines.length; i++) {
        if (cfg.yAxis.plotLines[i].label.name == 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
}

$.removeChart = function(cfgName) {
    var index = -1
    for (var i = 0; i < arrCfg.length; i++) {
        if (arrCfg[i].name == cfgName) {
            index = i
            break
        }
    }
    if (index != -1) {
        arrCfg.splice(index, 1)
    }

    if (typeof(registerInfo[cfgName]) != "undefined") {
        delete registerInfo[cfgName]
    }
    updateSeriesIdx()
}

function init() {
    if (isChartReset) {
        Log("重置图表", "#FF0000")
        chart = Chart(arrCfg)
        chart.reset()

        Log("清空持久化数据,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("恢复 registerInfo、arrCfg #FF0000")
        } else {
            Log("没有数据可以恢复 #FF0000")
        }
    }
}

function onexit() {
    _G("registerInfo", registerInfo)
    _G("arrCfg", arrCfg)
    Log("保存数据,key : registerInfo, arrCfg #FF0000")
}


// test
function main() {
    LogReset(10)
    var i = 0
    var prePrintTs = 0
    var t = _C(exchange.GetTicker)
    
    while (true) {
        var r = _C(exchange.GetRecords)        
        
        $.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", 10 + i)
        $.PlotMultLine("chart6", "line6", 100 + i)
        $.PlotMultLine("chart4", "line3", 1000 + i, new Date().getTime(), {
            layout: 'single',
            col: 4,
            height: '300px'
        })
        $.PlotMultLine("chart5", "line4", 10000 + i, 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" + i, "flag1")
        }

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

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

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