查看: 946|回复: 0
打印 上一主题 下一主题

KDJ 指标的图形化显示

[复制链接]
跳转到指定楼层
1
 楼主| 发表于 2018-10-17 14:48:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在使用 BotVS 的指标 API 的时候,有时候很想图形化显示一下指标线(其实我初学的时候也是有这个想法,很想画出指标看看)。第一是想练习如何运用指标API, 比如返回的数据的使用。 第二很是好奇,想自己画出来和其它软件或者网站上的对比。近期也有不少朋友提出这个问题,于是我写了一个小DEMO 测试,我们就拿 KDJ指标做示范。



代码:测试的合约为 商品期货 rb1710 合约

  1. // 画 KDJ 指标的 DEMO 程序
  2. // 需要引用  画线类库  模板  有兴趣的可以看下 源码对于学习编写 策略图表显示 很有帮助 : https://www.botvs.com/bbs-topic/608   也是注释版的。

  3. var preTime = 0;                                 // 声明一个变量用来记录 前一个K线 Bar 的时间戳
  4. var ChartObj = null;                             // 声明一个变量 用来 引用 图形API   Chart 函数
  5. function main(){                                 // 测试例子的  主函数 , 本例 代码全部都写在 main 函数中。
  6.     LogReset(1);                                 // 清空所有日志 , 仅保留本次运行的第一条(所以参数传入1)
  7.     ChartObj = Chart(null);                      // 调用 Chart 函数 初始化图表对象
  8.     ChartObj.reset();                            // 清空之前的图表内容
  9.    
  10.     var records = null;                          // 声明一个 变量 records 用于 记录 获取到的K线数据
  11.     var MACD = null;                             // 声明一个 变量 KDJ 用于记录 指标API函数 返回的 数据。
  12.    
  13.     while(exchange.IO("status") == false){       // 程序需要在 和 期货公司前置服务器 连接的状态下 才可以继续操作,
  14.                                                  // 所以会不断调用 exchange.IO("status") 检查连接状态, 连接状态 exchange.IO("status") 返回 true
  15.         Sleep(5000);                             // 每次检测 暂停5秒(5000毫秒),避免过于 访问频繁
  16.     }

  17.     var ContractTypeInfo = _C(exchange.SetContractType, "rb1710");      
  18.                                                  // 设置要操作的合约为  rb1710 合约,并赋值给 ContractTypeInfo 变量, _C() 函数用来容错API 详见API文档
  19.    
  20.     ChartObj = $.GetCfg();                       // 调用模板   画线类库   的导出函数 $.GetCfg()  获取 图表对象 引用给 变量 ChartObj
  21.    
  22.     // 处理 指标轴------------------------         // 由于KDJ 指标数值 与 K线 中价格的 数值 相差很远,所以需要 用2个不同的Y轴显示,否则图像压缩,看不到 指标线、K线变动。
  23.     ChartObj.yAxis = [{
  24.             title: {text: 'K线'},//标题
  25.             style: {color: '#4572A7'},//样式
  26.             opposite: false  //生成右边Y轴
  27.         },
  28.         {
  29.             title:{text: "指标轴"},
  30.             opposite: true,  //生成右边Y轴 , 图表第二个Y轴
  31.         }
  32.     ];

  33.     // 初始化指标线
  34.     while(!records || records.length < 30){     // 如果 records 为 null 或者 records.length 小于 30  ,执行该循环
  35.         records = _C(exchange.GetRecords);      // 调用 获取K线 API 函数 :  GetRecords (即 exchange 对象的成员函数 ),用_C()函数对其进行容错处理, 获取到的数据赋值给records
  36.         LogStatus("records.length:", records.length);  // 在状态栏显示 获取的K线数据长度的信息。
  37.         Sleep(1000);
  38.     }
  39.    
  40.     $.PlotRecords(records, 'rb1710');           // 调用 画线类库 模板的导出函数 $.PlotRecords 画K线
  41.     $.PlotLine('K', 0, records[records.length - 1].Time);  // 添加 KDJ 中的  K指标线
  42.     $.PlotLine('D', 0, records[records.length - 1].Time);  // 添加 KDJ 中的  D指标线
  43.     var chart = $.PlotLine('J', 0, records[records.length - 1].Time);  // 添加 KDJ 中的  J指标线 , 并将 $.PlotLine 函数返回的图表控制对象
  44.     // 修改指标线 坐标轴Y轴
  45.     for(var key in ChartObj.series){                                   // 遍历 图表对象 的数据系列 将数据系列 名称为 'K' 'D' 'J' 的数据绑定在 索引为1的Y轴(即第二个Y轴,第一个Y轴的索引是0)
  46.         if(ChartObj.series[key].name == 'K' || ChartObj.series[key].name == 'D' || ChartObj.series[key].name == 'J'){
  47.             ChartObj.series[key].yAxis = 1;
  48.         }
  49.     }
  50.     chart.update(ChartObj);                                            // 用修改后 图表对象 作为参数 传递给 图表控制对象的成员函数 update , 更新图表设置。
  51.     chart.reset();                                                     // 清空图表数据
  52.    
  53.     while(true){                                                       // 主要的画图循环,设定为死循环。
  54.         if(exchange.IO("status")){                                     // 同样,在画图的时候 必须要确定是 和 服务器 连接状态 (即 不是休市时间)
  55.             records = _C(exchange.GetRecords);                         // 通过容错函数_C() ,  调用 API  获取 K线,赋值给 records
  56.             if(records.length > 50){                                   // 需要K线数量 大于 50
  57.                 $.PlotRecords(records, 'OK期货');                       // 调用  模板  “画线类库”  的导出函数  $.PlotRecords  画K线
  58.                 KDJ = TA.KDJ(records);                                 // 调用 TA.KDJ  指标API  用传入的 records K线数据 计算 KDJ指标数据
  59.                 var K = KDJ[0];                                        // KDJ 数据结构是一个 二维数组 ,包含三个数组,第一个是 指标K线  ,第二个是指标D线,第三个是指标J线。
  60.                 var D = KDJ[1];                                        // 分别赋值 变量 K,D,J
  61.                 var J = KDJ[2];                                        //
  62.                 if(preTime !== records[records.length - 1].Time){      // 用 records K线数据的倒数第一个 bar 的时间戳(即: records[records.length - 1].Time)
  63.                                                                        // 和 preTime 变量记录的时间戳 对比,判断是否是有新K线Bar出现,如果出现 处理图表 并在处理后更新preTime 变量用于下次判断是否有新K线出现
  64.                     $.PlotLine('K', K[K.length - 2], records[records.length - 2].Time);   // 调用 模板 “画线类库”  导出函数 $.PlotLine 画  指标 K
  65.                     $.PlotLine('D', D[D.length - 2], records[records.length - 2].Time);   // ...  要注意的是,新Bar 出现后,出现前那个曾经是最新的Bar各个数值才确定。
  66.                     $.PlotLine('J', J[J.length - 2], records[records.length - 2].Time);   // 所以要用此刻的倒数第二个Bar去画在图表上 以确定数值
  67.                
  68.                     $.PlotLine('K', K[K.length - 1], records[records.length - 1].Time);   // 然后再画 最新的 数据。
  69.                     $.PlotLine('D', D[D.length - 1], records[records.length - 1].Time);
  70.                     $.PlotLine('J', J[J.length - 1], records[records.length - 1].Time);
  71.                
  72.                     preTime = records[records.length - 1].Time;                           // 更新时间戳 用于对比。
  73.                 }else{                                                                    // 如果 preTime == records[records.length - 1].Time, 即没有新的Bar出现
  74.                     $.PlotLine('K', K[K.length - 1], records[records.length - 1].Time);   // 用最新的数据 更新 倒数第一 Bar 在图表上。
  75.                     $.PlotLine('D', D[D.length - 1], records[records.length - 1].Time);
  76.                     $.PlotLine('J', J[J.length - 1], records[records.length - 1].Time);
  77.                 }
  78.             }
  79.             LogStatus("records.length:", records.length, records[records.length - 1]);
  80.         
  81.             Sleep(1000);
  82.         }else{
  83.             LogStatus("休市..");                                                           // 如果 exchange.IO("status") 返回 false 则为休市(一般情况,未连接服务器)
  84.         }
  85.     }
  86. }
复制代码


对比文华上的行情图表



有兴趣的同学可以剖析这个DEMO源码 和 “画线类库” 模板的源码:发明者量化平台测试的时候需要引用上“画线类库”,否则是画不出图表的。







您需要登录后才可以回帖 登录 | 注册入住  

本版积分规则

易家网  ©2015-2023  郑州期米信息技术有限公司版权所有  豫公网安备 41010502005136号 豫ICP备16010300号