자바스크립트와 함께 게임을 하는 노인 - 구매를 하는 파트너를 만드는 (3) 활기찬 소년이 주변에서 새로운 것을 좋아하는

저자:작은 꿈, 창간: 2017-03-07 12:50:50, 업데이트: 2017-10-11 10:37:06

노인과 함께 자바스크립트 을 플레이하고 구매하는 파트너를 만듭니다.

활기찬 소년이 신선한 것을 좋아합니다.

지난 기사에서는 샌드박스 시스템에서 간단한 상품 선물 거래 프로그램을 자바스크립트로 만들고, 샌드박스에서 즐거운 놀이를 했습니다. 자동화 거래 프로그램은 데이터에 의존하고 있습니다. 즉, 프로그램이 실시간으로 최신 데이터를 얻을 필요가 있습니다. 거래, 의사 결정, 분석 계산에 많은 정보를 제공합니다.

  • 지난 몇 주 동안 사용했던 몇 가지 함수를 다시 살펴보면,

    • GetTicker: 실시간 시장 데이터를 얻습니다. 이 데이터는 시장 정보를 포함하는 객체입니다.

    • GetRecords: 역사적인 K줄 데이터를 얻을 수 있고, K줄 데이터를 반환하는 주기 크기를 제어하는 매개 변수를 지정할 수 있다. 파라미터: PERIOD_M1은 1분, PERIOD_M5는 5분, PERIOD_M15는 15분, PERIOD_M30는 30분, PERIOD_H1는 1시간, PERIOD_D1는 1일

    • GetAccount: 설정에 설정된 미래에셋 회사의 계정 정보를 얻는다. 미래 거래에 경험이 있는 친구들은 확실히 GetAccount 함수의 반환 값을 보았을 때 미래 계좌 정보가 그렇게 간단한 구조가 설명할 수 없다고 말할 것입니다. 사실, 여기 가장 기본적인 데이터가 포착되어 있습니다. 자세한 데이터는 다음과 같은 코드에서 볼 수 있습니다. 여전히 MainLoop 함수에서 우리는 작은 사람에게 약간의 기능을 추가하여 계정 세부 정보를 요청할 수 있습니다.

      function MainLoop(){
          var account = exchange.GetAccount();            // 框架的接口函数,获取配置的账户信息。
          var obj = JSON.parse(exchange.GetRawJSON());    // 框架的接口函数,获取上一次调用的原始调用信息。这里就是GetAccount 调用时 接收到的原始信息。
          var nowTime = new Date();
          var table = {
              type : "table",
              title : "商品期货账户详细信息",
              cols : ["key", "value"],
              rows : [],
          }
          for(var key in obj){
              table.rows.push([key, obj[key]]);
          }
          LogStatus("time:" + nowTime + JSON.stringify(account) + '\n`' + JSON.stringify(table) + '`');
      }
      

함수 main() { var 상태 = null while (진짜) 상태 =exchange.IO("status"); // API 호출 연결 상태를 결정 if ((status === true) { // 상태를 판단합니다 // LogStatus (( 접속!); // 리모델링 또는 실제 실행 중 실시간 데이터, 정보를 표시합니다. // MainLoop에서 LogStatus가 사용되기 때문에 이 자리는 표기해야 합니다. MainLoop ((); // 거래소 서버에 연결된 후 주요 작업 기능을 수행합니다. }else{ // 연결이 안되면exchange.IO("status") 함수는 false를 반환합니다 LogStatus (( 연결 상태가 없습니다!); // 연결 상태가 없습니다. ♪ ♪ Sleep ((1000); // 포괄된 수면 함수, 너무 자주 접근하지 않도록 롤링 간격이 필요합니다. CTP 프로토콜은 초당 2 번 데이터를 푸시합니다. ♪ ♪ ♪ ♪ ``

##### 如图显示:

![img](/upload/asset/d2be567a7af2fb63c7834703d362136de7e794b6.png) 
![img](/upload/asset/f8383059b540e417161d5ac49e9465dd1178d5db.png) 

第一次打印出详细信息的时候我也一头雾水,查询了CTP相关资料知道了具体各个字段的意思。
可以用以下这个对象去在程序中匹配翻译下。

```
var trans = {
    "AccountID": "投资者帐号",
    "Available": "可用资金",
    "Balance": "期货结算准备金",
    "BrokerID": "经纪公司代码",
    "CashIn": "资金差额",
    "CloseProfit": "平仓盈亏",
    "Commission": "手续费",
    "Credit": "信用额度",
    "CurrMargin": "当前保证金总额",
    "CurrencyID": "币种代码",
    "DeliveryMargin": "投资者交割保证金",
    "Deposit": "入金金额",
    "ExchangeDeliveryMargin": "交易所交割保证金",
    "ExchangeMargin": "交易所保证金",
    "FrozenCash": "冻结的资金",
    "FrozenCommission": "冻结的手续费",
    "FrozenMargin": "冻结的保证金",
    "FundMortgageAvailable": "货币质押余额",
    "FundMortgageIn": "货币质入金额",
    "FundMortgageOut": "货币质出金额",
    "Interest": "利息收入",
    "InterestBase": "利息基数",
    "Mortgage": "质押金额",
    "MortgageableFund": "可质押货币金额",
    "PositionProfit": "持仓盈亏",
    "PreBalance": "上次结算准备金",
    "PreCredit": "上次信用额度",
    "PreDeposit": "上次存款额",
    "PreFundMortgageIn": "上次货币质入金额",
    "PreFundMortgageOut": "上次货币质出金额",
    "PreMargin": "上次占用的保证金",
    "PreMortgage": "上次质押金额",
    "Reserve": "基本准备金",
    "ReserveBalance": "保底期货结算准备金",
    "SettlementID": "结算编号",
    "SpecProductCloseProfit": "特殊产品持仓盈亏",
    "SpecProductCommission": "特殊产品手续费",
    "SpecProductExchangeMargin": "特殊产品交易所保证金",
    "SpecProductFrozenCommission": "特殊产品冻结手续费",
    "SpecProductFrozenMargin": "特殊产品冻结保证金",
    "SpecProductMargin": "特殊产品占用保证金",
    "SpecProductPositionProfit": "特殊产品持仓盈亏",
    "SpecProductPositionProfitByAlg": "根据持仓盈亏算法计算的特殊产品持仓盈亏",
    "TradingDay": "交易日",
    "Withdraw": "出金金额",
    "WithdrawQuota": "可取资金",
};
```
##### 先复制这个用来翻译的对象到代码中。
![img](/upload/asset/4f034b84a65aae2f4f4f0cccf601df857f040825.png) 
##### 修改前 
![img](/upload/asset/0b2a2ba84c6c90ac4cc9dd15021e7dd0bfcd3a76.png) 
##### 修改后

```
var desc = trans[key];
table.rows.push([key, typeof(desc) === "undefined" ? "--" : desc, obj[key]]);
```

![img](/upload/asset/f2e3a47db7556f7a64479877982b26244fdc0b0a.png) 
##### 这下直白多了。
![img](/upload/asset/b8d3053f361a8af3ed11e5e2ad30c104968fe854.png) 
  • 또한, 정보를 얻기 위해 사용되는 인터페이스도 있습니다.

    • 데프스 (GetDepth): 깊이 있는 정보를 얻습니다.
    • GetOrders: 모든 미수 주문 정보를 얻을 수 있습니다.
    • 현재 보유 정보를 얻을 수 있습니다.

    다음으로 샌드박스 시스템에서 시도해보세요: (만 MainLoop 함수에서 코드를 추가했습니다)

    function MainLoop(){
        var account = exchange.GetAccount();            // 框架的接口函数,获取配置的账户信息。
        var obj = JSON.parse(exchange.GetRawJSON());    // 框架的接口函数,获取上一次调用的原始调用信息。这里就是GetAccount 调用时 接收到的原始信息。
        var nowTime = new Date();
        var table = {
            type : "table",
            title : "商品期货账户详细信息",
            cols : ["key", "value"],
            rows : [],
        }
        for(var key in obj){
            var desc = trans[key];
            table.rows.push([key, typeof(desc) === "undefined" ? "--" : desc, obj[key]]);
        }
        // 还记得状态栏表格么? 就是刚才我们翻译的账户信息所在的表格。其实可以多表格显示,我们来试下。
        var table2 = {
            type : "table",
            title : "GetDepth、GetOrders、GetPosition",
            cols : ["function Name", "return value"],
            rows : [],
        }
        // 使用 GetDepth 获取深度数据
        exchange.SetContractType("MA705");              // 一定记得 不论是获取数据还是下单,一定要设置或切换操作的合约。
        var depth = exchange.GetDepth();
        table2.rows.push(["GetDepth()", depth]);
      
        // 下个低价买单挂单、然后获取未完成的订单
        exchange.SetDirection("buy");                   // 一定记得 下单前要明确下单方向, 这里是开多仓。
        exchange.Buy(depth.Bids[0].Price - 20, 1);
        var PendingOrders = exchange.GetOrders();
        table2.rows.push(["GetOrders()", PendingOrders]);
      
        // 下个高价买单吃掉盘口的卖单,用获取持仓函数 GetPosition 获取信息来看下是否成交。
        exchange.SetDirection("buy");                   // 一定记得 下单前要明确下单方向, 这里是开多仓。
        exchange.Buy(depth.Asks[0].Price + 1, 1); // 比卖一价 这个价格再多出一块钱,确保吃到单子
        Sleep(1000);
        var positions = exchange.GetPosition();
        table2.rows.push(["GetPosition()", positions]);
      
        var tables = [table, table2];
      
        LogStatus("time:" + nowTime + JSON.stringify(account) + '\n`' + JSON.stringify(tables) + '`');
        throw "仅仅执行一次,抛出个错误停止程序,老白在平时也经常使用这个办法调试代码!因为有时会输出一大堆信息无从下手。";
    }
    
    서둘러!

    img img

  • 활기찬 작은 녀석들 (거래 프로그램) 은 SHOW도 좋아합니다.

    K 라인, 거래 정보, 그리고 SHOW를 통해 관심 있는 데이터를 얻을 수 있습니다. 샌드박스는 그림 도서관을 통합하고 있습니다. 우리는 JS를 손으로 작성하여 선물 회사 CTP 서버에서 들었던 흥미로운 것을 보여줍니다.

var chart = null    // 一个全局 变量 用来接收 Chart 函数返回的  对象。
var series = []     // 数据系列数组,用来保存 图表上的线、标记、K线等数据。
var labelIdx = []   // label 索引,
var preBarTime = 0  // K线前一柱的 时间戳 ( 毫秒数 )
var preFlagTime = 0 // 前一个  标记 的时间戳
var preDotTime = [] //            时间戳

var cfg = {    // 用来初始化设置图表的对象(即图表设置)  具体可见  HighCharts
    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: series,           // 全局变量赋值给该属性, 注意 数组是引用传递,  即: 浅拷贝。(不明白的可以百度:引用传递)
}

$.GetCfg = function() {       // 导出函数 , 用来获取 cfg 对象。
    return cfg
}

$.PlotHLine = function(value, label, color, style) {    // 画 x 轴 水平线。
    if (typeof(cfg.yAxis) === 'undefined') {            // 如果 没有定义 y 轴 属性, 添加y轴属性定义。
        cfg.yAxis = {
            plotLines: []                               // y 轴上的 平行于x 轴的 水平线数组。
        }
    } else if (typeof(cfg.yAxis.plotLines) === 'undefined') {  // 如果定义了 y轴 ,没有定义 水平线数组,则添加水平线数组。
        cfg.yAxis.plotLines = []
    }
    /*
    Solid
    ShortDash
    ShortDot
    ShortDashDot
    ShortDashDotDot
    Dot
    Dash
    LongDash
    DashDot
    LongDashDot
    LongDashDotDot
    */
    var obj = {                                          // 定义一个 对象,保存水平线的 各个属性。
        value: value,                                    // 在y轴上的 位置值。
        color: color || 'red',                           // 没有传入 默认红色。
        width: 2,                                        // 线的宽度是2
        dashStyle: style || 'Solid',                     // 选择线的类型,可以设置为虚线。 'dash'
        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) {  // 如果找到对应的 label 的水平线
            cfg.yAxis.plotLines[i] = obj                   // 把 obj对象赋值给这个索引 指向的元素。(替换)
            found = true                                   // 标记为找到 
        }
    }
    if (!found) {                                          // 如果是没找到   (新压入)
        cfg.yAxis.plotLines.push(obj)
    }
    if (!chart) {                                          // 如果 chart 对象是 null 
        chart = Chart(cfg)                                 // 调用API Chart 初始化图表,返回 对象赋值给chart
    } else {                                               // else
        chart.update(cfg)                                  // 更新图表
    }
}

$.PlotRecords = function(records, title) {                 // 画K线  ,参数是 K线数据(数组), 标题
    var seriesIdx = labelIdx["candlestick"];               // 数据序列 的索引
    if (!chart) {                                          // 如果chart 图表对象为 null 
        chart = Chart(cfg)                                 // 初始化图表,并且返回图表对象给 chart 变量
    }
    if (typeof(seriesIdx) == 'undefined') {                // 如果获取到的数据序列索引 是未定义,执行以下if代码
        cfg.__isStock = true                               // 设置 cfg 对象 __isStock 属性为 true 
        seriesIdx = series.length                          // 设置 当前数据序列索引 为 已经存在的索引之后。
        series.push({                                      // 压入series 数据序列数组 ,该数据序列属性如下:
            type: 'candlestick',                               // type 属性  K线图
            name: typeof(title) == 'undefined' ? '' : title,   // 如果 $.PlotRecords 导出函数调用时,没有传入 title参数,则该数据序列 标题为 空字符串。
            id: 'primary',                                     // 数据序列的 id 为 primary (首要的)
            data: []                                           // 数据序列的 数据数组 ,图表上显示的数据值都储存在该数组内。
        });
        chart.update(cfg)                                  // 用设置过的 cfg 对象 更新 chart 对象。
        labelIdx["candlestick"] = seriesIdx                // 给 labelIdx (索引的标签) 添加 K线数据序列的索引,即 当前的 seriesIdx 值。
    }
    if (typeof(records.Time) !== 'undefined') {            // 如果传入的是单根 K线 数据执行以下if 代码
        var Bar = records;                                 // 把records 赋值给 Bar
        if (Bar.Time == preBarTime) {                      // preBarTime 初始是0, 如果参数传入的records 的时间戳 和 全局变量 preBarTime 相等,即认为当前的Bar (即 records) 没有更新(没有出现新的K线柱)
            chart.add(seriesIdx, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close], -1) // 根据参数传入的records 更新图表上的 值为 labelIdx["candlestick"] 的数据序列的 倒数第一个数据( 因为 add函数 最后一个参数传入的是 -1)。
        } else if (Bar.Time > preBarTime) {                // 如果 参数传入的 records 也就是 Bar 的时间戳 比 preBarTime 大,即 新出现了Bar 。
            preBarTime = Bar.Time                          // 更新preBarTime 这个全局变量用于 下次的比较。
            chart.add(seriesIdx, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close])  // 区别于 Bar.Time == preBarTime 时的操作,没有传参数 -1 ,为在数据序列最后添加一个数据。
        }
    } else {                                               // 如果传入的是一个K线数据数组, 此情况在第一次 preBarTime = 0 时 ,执行比较特殊:会逐个添加全部 records数据
        for (var i = 0; i < records.length; i++) {         // 遍历records 
            if (records[i].Time == preBarTime) {           // 如果 索引i 这个元素的时间戳 等于 上一次记录的 preBarTime 更新图表 该数据序列的最后一个数据 
                chart.add(seriesIdx, [records[i].Time, records[i].Open, records[i].High, records[i].Low, records[i].Close], -1) // 更新
            } else if (records[i].Time > preBarTime) {     // 如果索引i 这个元素的时间戳大于 preBarTime 则添加
                preBarTime = records[i].Time               // 更新preBarTime
                chart.add(seriesIdx, [records[i].Time, records[i].Open, records[i].High, records[i].Low, records[i].Close])  // 添加
            }
        }
    }
    return chart                                           // 返回 chart
}

$.PlotLine = function(label, dot, time) {                  // 画线
    if (!chart) {                                          // 如果 chart 为 null 执行以下
        cfg.xAxis = {                                      // 设置 cfg对象 x轴 的类型为 datatime 时间类型
            type: 'datetime'
        }
        chart = Chart(cfg)                                 // 调用 Chart 这个API函数(cfg为参数) 初始化图表
    }
    var seriesIdx = labelIdx[label]                        // 按照 label参数获取 标签索引 赋值给 数据序列索引。                 
    if (typeof(seriesIdx) === 'undefined') {               // 如果 labelIdx 内没有 参数传入的 label 这个标签的索引 执行以下代码 添加这个数据序列                       
        seriesIdx = series.length                          // 根据已有的数据序列的长度,赋值 新数据序列的索引
        preDotTime[seriesIdx] = 0                          // 在线条的 前一个值(preDotTime中的元素) 使用了一个数组储存(因为可能有多个线条,所以会有多个 “前一个值” ,所以用数组储存,这个“前一个值”作用类似于 preBarTime)
        labelIdx[label] = seriesIdx;                       // 把当前标签 对应的索引 储存在标签索引。
        series.push({                                      // 把数据序列 push 进 数据序列数组
            type: 'line',           // 设置当前的数据序列 类型为: 线
            yAxis: 0,               // 使用的y轴 为索引为 0 的y轴(highcharts 图表 可以有 多个 y 坐标轴,这里指定索引0的y轴)
            showInLegend: true,     // 
            name: label,            // 根据 函数传入的 参数 label 设置
            data: [],               // 数据序列的数据项
            tooltip: {              // 工具提示
                valueDecimals: 5    // 值的小数点 保留5位
            }
        })
        chart.update(cfg)           // 用cfg 对象 更新图表对象 chart
    }
    if (typeof(time) == 'undefined') {                     // 如果参数没有传入 要画线(其实是线上的点)的时间。
        time = new Date().getTime()                        // 给形参 time 赋值当前的时间戳
    }

    if (preDotTime[seriesIdx] != time) {                   // 对比当前时间如果不等于执行if 内的代码
        preDotTime[seriesIdx] = time                       // 更新 上一次时间
        chart.add(seriesIdx, [time, dot])                  // 添加参数传进的点 在x轴值为 time 的时间上
    } else {
        chart.add(seriesIdx, [time, dot], -1)              // 如果时间相等 ,则更新数据序列的最后的点
    }

    return chart                                           // 返回图表对象
}


$.PlotFlag = function(time, text, title, shape, color) {   // 在图表上添加 旗帜标签
    if (!chart) {                                          // 如果 chart 为 null
        chart = Chart(cfg)                                 // 初始化 图表
    }
    label = "flag";                                        // 设置标签类型为 flag  (旗帜)
    var seriesIdx = labelIdx[label]                        // 在数据序列索引数组中获取 旗帜 类型的索引
    if (typeof(seriesIdx) === 'undefined') {               // 如果没有该索引
        seriesIdx = series.length                          // 根据现有的索引数组长度 新设置一个索引
        labelIdx[label] = seriesIdx;                       // 储存该索引 到标签索引数组
        series.push({                                      // 向数据序列数组 压入 当前数据序列
            type: 'flags',             // 设置当前压入的数据序列 类型为 旗帜类型
            onSeries: 'primary',       // 设置 旗帜标记在哪个数据序列上,   这里设置 标记在  id 为 primary的数据序列上(即 K线数据序列)
            data: []                   // 数据序列的 数据项
        })
        chart.update(cfg)              // 更新图表对象
    }

    var obj = {                        // 根据函数参数 初始化一个对象  用来 加载到图表。
        x: time,                       // x轴的值, 即时间戳
        color: color,                  // 颜色
        shape: shape,                  // 形状
        title: title,                  // 标题
        text: text                     // 文本
    }

    if (preFlagTime != time) {         // 上一次的标记时间 如果不等于当前时间 
        preFlagTime = time             // 更新上一次的标记时间
        chart.add(seriesIdx, obj)      // 用设置好的obj对象添加该标记(写入图表)
    } else {
        chart.add(seriesIdx, obj, -1)  // 如果时间相同,则更新最后一个旗帜标记。
    }

    return chart                       // 返回图表对象
}

$.PlotTitle = function(title, chartTitle) {                     // 设置 图表 标题
    cfg.subtitle = {                                            // 根据参数 title设置子标题
        text: title
    };
    if (typeof(chartTitle) !== 'undefined') {                   // 如果 chartTitle 不等于 未定义,即传入了值
        cfg.title = {                                           // 设置 图表标题
            text: chartTitle                                    // 文本为 chartTitle
        };
    }
    if (chart) {                                                // 如果 图表已经初始化,更新图表
        chart.update(cfg)
    }
}

var isFirstPlotLine = true;
var PreBarTime = 0;
function MainLoop(){
    var info = exchange.SetContractType("MA705");
    if(!info){
        return;
    }
    var records = exchange.GetRecords();
    if(!records || records.length < 10){
        return;
    }
    var depth705 = exchange.GetDepth();
    if(!depth705 || depth705.Asks.length == 0 || depth705.Bids.length == 0){
        return;
    }
    info = exchange.SetContractType("MA709");
    if(!info){
        return;
    }
    var depth709 = exchange.GetDepth();
    if(!depth709 || depth709.Asks.length == 0 || depth709.Bids.length == 0){
        return;
    }
    $.PlotRecords(records, "MA705");                // 在图表上画出 MA705 甲醇 合约的 K线数据
    var diffA_B = depth705.Bids[0].Price - depth709.Asks[0].Price;
    var diffB_A = depth705.Asks[0].Price - depth709.Bids[0].Price;
    if(PreBarTime !== records[records.length - 1].Time){
        $.PlotLine("MA705->MA709", diffA_B);
        $.PlotLine("MA705<-MA709", diffB_A);
        PreBarTime = records[records.length - 1].Time;
        if(isFirstPlotLine){
            for(var j = 0;j < cfg.series.length; j++){
                if(cfg.series[j].name == "MA705->MA709" || cfg.series[j].name == "MA705<-MA709"){
                    cfg.series[j].yAxis = 1;
                }
            }
            isFirstPlotLine = false;
        }
    }
}

var cfg = $.GetCfg();
function main() {
    var status = null;
    cfg.yAxis = [{
            title: {text: 'K线'},            //标题
            style: {color: '#4572A7'},       //样式 
            opposite: false                  //生成右边Y轴
        },
       {
            title:{text: "另一个Y轴"},
            opposite: true                   //生成右边Y轴  ceshi
       }
    ];
    while(true){
        status = exchange.IO("status");      //  调用API 确定连接状态
        if(status === true){                 //  判断状态
            // LogStatus("已连接!");         //  在回测或者实际运行中显示一些实时数据、信息。
            // 由于MainLoop 中用到了LogStatus 所以这个地方的要先注释掉, 以免覆盖掉信息
            MainLoop();                      //  连接上 交易所服务器后,执行主要工作函数。
        }else{                               //  如果没有连接上 即 exchange.IO("status") 函数返回 false
            LogStatus("未连接状态!");         //  显示 未连接状态。
        }
        Sleep(1000);                         //  封装的睡眠函数,需要有轮询间隔, 以免访问过于频繁。CTP协议是每秒推送2次数据。
    }
}

실행에 이르면 사장 차원의 스피드 라인이 그려져 있고, MA705와 MA709 계약 스피드, 같은 품종에 기반한 연장 계약 복합 수단을 구성할 수 있다.

img

물론 주의깊은 독자들은 왜 두 접시 가격 차선들이 거의 평행한지 알아낼 수 있을 것이다. 왜냐하면 이들은 Sandbox가 실제 K선을 기반으로 시뮬레이션한 데이터이기 때문에 일관된 변화이며 실제로는 좀 더 무작위적인 것이기 때문이다.

이 글을 쓰기 전에, 독자 저에게 편지를 보내십시오! 제안과 의견을 보내십시오. 재미있다면 더 많은 프로그램을 좋아하는 거래하는 친구에게 공유 할 수 있습니다.

https://www.fmz.com/bbs-topic/726

프로그래머 littleDream 원작


더 많은

대용량if ((isFirstPlotLine) {는 첫 번째 줄입니다. for ((var j = 0; j < cfg.series.length; j++) { if ((cfg.series[j].name == "MA705->MA709" cfg.series[j].yAxis = 1; ♪ ♪ ♪ ♪ isFirstPlotLine = false; 이 부분은 이해가 안되네요.

작은 꿈이것은 두 개의 선을 설정하는 것입니다.