JFreeChart绘制K线图停牌日期缺口优化

摘要 这是在绘制股票交易K线图时遇到的一个问题,有关问题的优化方案,与一些具体的实现

方法,以及在这个过程中的心得。

关键词JFreeChart、SegmentTimeline

问题

在绘制股票交易K线图时,遇到如何去除停牌日期的交易数据问题。此问题涉及到两个方面,

周六周日股票停牌无交易日期和特殊假日股票停牌无交易日期。对于周末这个固定的休息日,股

票是不存在交易数据的,即停牌,在K线图上显示的话就是空白。同样,对于特殊的时间节点

也不存在交易数据,在K线图上也是空白。因此在绘制K线图时,为了保证数据显示的连续性

和美化视角,我们要将这些特殊的日期的横轴坐标从原数据坐标中去掉,或者说隐藏不显示。

现状分析

在设置K线图的X轴时间线性集合时没有将异常交易日期(即停牌缺口)从时间线性集合

中去除掉。要想实现停牌日期缺口优化,就要设法将缺口日期从时间线性集合去除或使该缺口日

期隐藏不显示,从而达到K线图的连续不间断,便于统计分析。

意义

主要是对停牌日期缺口进行异常处理,以去除掉无交易的日期,保证X轴时间上的连续

性(有交易),使K线图显示数据变化是连续不间断的,有利于数据分析。

要将停牌缺口从时间线性集合中去除掉,必须涉及到下列相关对象、属性和方法的应用:

SegmentTimeline: 时间线性集合对象,包含已定义的交易时间轴的下限和上限

timeline.setStartTime(SegmentedTimeline.FIRST_MONDAY_AFTER_1900);//设置

时间线起点为1900年(一定要设置起始年份,否则时间轴没有基点,会错乱)

addException(Date date):从已定义的时间轴范围内,去除参数指定日期函数

DateAxis:时间线性X轴对象

x1Axis.setAutoRange(false);//设置不采用自动设置时间范围

x1Axis.setRange(date1,date2);//设置时间范围

x1Axis.setTimeline(timeline);//设置X轴时间线性集合

x1Axis.setAutoTickUnitSelection(false);//设置不采用自动选择刻度值

x1Axis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);//设置标记的位置

x1Axis.setStandardTickUnits(DateAxis.createStandardDateTickUnits());//设

置标准的时间刻度单位

x1Axis.setTickUnit(newDateTickUnit(DateTickUnit.DAY,1));//设置时间刻度的

间隔,这里以天为单位

x1Axis.setDateFormatOverride(newSimpleDateFormat("yyyy-MM-dd"));//设置

显示时间的格式

x1DateAxis.setVerticalTickLabels(true);//设置X轴时间标记是否垂直显示

上述是在设置X轴时间线性显示时涉及到的相关对象,设置好相关对象的属性值,就可以

将交易停牌缺口从K线图中去除,从而使得K线图保持连续性且美观。

思路分析

思路一

第一步:首先应用SegmentTimeline类默认的去除周末日期缺口的函数来构造SegmentTimeline

对象,即SegmentedTimeline.newMondayThroughFridayTimeline();

第二步:进一步从去除周末缺口的时间线性集合中出去特殊无交易日期缺口。

思路二 

对SegmentTimeline时间线性集合对象的Calendar(日历对象)进行重新定义,即对时间

日历对象的time属性进行赋值(calendar.setTime(Date date);),当然date的取值来自数据

源提供的和SegmentTimeline对象的Date相匹配的date属性值,如果不匹配,调用

SegmentTimeline对象的addException(Date date)方法将其保存在exceptionSegments集合中

且设置该日期对应的无交易时间刻度在X轴显示时隐藏起来,并从Calendar对象去除该日期对

应的时间,从而实

现缺口优化。

解决过程 

分两步:第一步,首先重载SegmentTimeline类的方法,调用默认的构造函数,以去除周

六日这些有周期的日期缺口;第二部,在前一步的基础上,再判断某个某个日期(特殊日期)是

否有交易,有则绘制交易数据,无则隐藏此数据交易不现实。从而达到K线图的数据连续性。

DateAxisx1Axis=new DateAxis();//设置x轴,也就是时间轴

x1Axis.setAutoRange(false);//设置不采用自动设置时间范围

x1Axis.setRange(dateFormat.parse("2007-08-20"),dateFormat.parse("2007-10-11

"));//设置时间范围,注意时间的最大值要比已有的时间最大值要多一天

//x1Axis.setTimeline(SegmentedTimeline.newMondayThroughFridayTimeline());设

置时间线显示的规则,用这个方法就摒除掉了周六和周日这些没有交易的日期(很多人都不知道

有此方法),使图形看上去连续

Map<String,Date>map = new HashMap<String,Date>();//将有交易的日期以键值对的形

式存放到Map集合中(后面要用来验证时间是否匹配)

for(intindex = 0;index <series.getItemCount();index++) {

RegularTimePeriodperiod =series.getPeriod(index);

Stringss =new SimpleDateFormat("yyyy-MM-dd").format(period.getStart());

map.put(ss,period.getStart());

}

//自定义时间线性集合,作为X轴显示的时间集合(匿名内部类调用其父类的方法)

SegmentedTimelinetimeline = new

SegmentedTimeline(SegmentedTimeline.DAY_SEGMENT_SIZE, 5, 2){

publicboolean containsDomainValue(Datedate) {

StringstringDate =date.toString();

System.out.println(date);

String key=new SimpleDateFormat("yyyy-MM-dd").format(date);

Date d=map.get(key);

if(d ==null) {//判断当前日期是否存在交易

this.addException(date);//不存在交易即为异常日期,添加到异常日期

集合中,并在Calendar对象中去除该时间

}

returnsuper.containsDomainValue(date);//判断当前日期是否包含在

SegmentTimeline的日期集合中

}

};

timeline.setStartTime(SegmentedTimeline.FIRST_MONDAY_AFTER_1900);

x1Axis.setTimeline(timeline);//设置X轴时间线性集合

x1Axis.setAutoTickUnitSelection(false);//设置不采用自动选择刻度值

x1Axis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);//设置标记的位置

x1Axis.setStandardTickUnits(DateAxis.createStandardDateTickUnits());//设置标

准的时间刻度单位

x1Axis.setTickUnit(newDateTickUnit(DateTickUnit.DAY,1));//设置标准的时间刻

度间隔单位(此处以一天为例则是1,如果以一周为例则是7)

x1Axis.setDateFormatOverride(newSimpleDateFormat("yyyy-MM-dd"));//设置显示时间的格式

NumberAxisy1Axis=new NumberAxis();//设定y轴,就是数字轴

y1Axis.setAutoRange(false);//设置是否采用自动设置Y轴数值范围

y1Axis.setRange(minValue*0.9,highValue*1.1);//设定y轴值的范围,比最大值要大一些,

这样图形看起来会美观些

y1Axis.setTickUnit(newNumberTickUnit((highValue*1.1-minValue*0.9)/10));//设置刻度

显示的密度

XYPlotplot1=new XYPlot(seriesCollection,x1Axis,y1Axis,candlestickRender);//设置画图区域对象

CombinedDomainXYPlotcombineddomainxyplot =new

CombinedDomainXYPlot(x1Axis);//建立一个联合图形区域对象,以x轴为共享轴

combineddomainxyplot.add(plot1);

combineddomainxyplot.add(plot1);//添加图形区域对象,后面的数字(如果有数字)是计算这个区域对象应该占据多大的区域2/3

JFreeChartchart =newJFreeChart("xx公司股票", JFreeChart.DEFAULT_TITLE_FONT,combineddomainxyplot,false);

ChartFrameframe =newChartFrame("xx公司xx股票",chart);

frame.pack();

frame.setVisible(true);

解决后的效果图

总结

addException(Date date)函数的具体实现步骤过程中涉及到如下图所示的相关函数的实现:

  1. 调用异常日期保存方法将date保存在list集合中,并从SegmentTimeline中对当前异常时间线段进行截取标记(即将这一段从SegmentTime中去除掉)后面再次验证时就不会存在该日期的段。

  2. 在addException()函数中调用inIncludeSegments()是验证date是否包含在周一至周五(这个时间段)。包含的话就调binarySearchExceptionSegments(Segmentsegment)方法返回一 个int类型的值,用来作为add(index ,segement)的index值。

  3. 对当前的segment对象进行是否属于验证(调用inExceptionSegments()函数验证其是否是异 常段),通过验证就说明segmentTimeline中包含该时间段,对应的坐标标记和数据可以显示。

  4. 验证segment是否包含在exceptionSegments集合中,同时为在addException()时的index索 引赋值 。

  5. 画K线图对于不包含在SegmentTimeline时间线性集合中日期进行隐藏设置,使其不显示在X轴上。super.containsDomainValue(date);里调inIncludeSegments()验证是否是工作日;是工作日在进一步验证是否是异常集合中的元素,是的话,设置X轴时间标记标签时执行回滚操作(rollDate())。

  6. 执行回滚时是刻度单位(DateTickUnit)对象执行回滚操作(rollDate()),进而得到有效的标 记标签的文本值和对应的x变量值。

  7. 设置时间线段时使date在起始日期的基础上以天为单位进行叠加,直至达到时间线段的上 限值(upperDate)。

    当isHiddenValue(long millis)返回true时,TickUnit(时间刻度单位)对象调rollDate()方法将Calendar对象的日期按卷单元指定的数量(2天)滚动日期(如当前日期为2017-04-30,下一个日期2017-05-01无交易,需要跳过,即下一个日期应该为2017-05-02,此处调用calendar.add(intFiled , count)函数后,日期会设置为2007-05-02);

    当返回false时,TickUnit调用addToDate()方法对date进行“1天”时间线段的设置。

    rollDate()和addToDate()这两个函数是在绘制X轴的timelineLabel标记标签时用到的函 数,目的是在segmentTimeline中将异常日期的标签按指定单位和数量回滚过去,以达到在X 轴不显示缺口标签的目的。

     

    addException()则是通过添加exceptionSegments集合元素来验证segmentTimeline中的 段(缺口)是否是异常段,异常就会在绘制X轴标记标签时进行回滚。



基于JFreeChart的股票交易K线图停牌日期缺口优化完整解决方案相关推荐

  1. 利用JFreeChart绘制股票K线图

    因为工作的需要,接触了一些股票图形绘制类的工作,其中最主要的还是股票K线图的绘制了,如果利用编程语言最底层的图形绘制方法去绘制这类图形,如果对编程语言不是特别熟悉的话,一般是有很大的困难的,通过在网上 ...

  2. java绘制均线图_利用JFreeChart绘制股票K线图完整解决方案

    因为工作的需要,接触了一些股票图形绘制类的工作,其中最主要的还是股票K线图的绘制了,如果利用编程语言最底层的图形绘制方法去绘制这类图形,如果对编程语言不是特别熟悉的话,一般是有很大的困难的,通过在网上 ...

  3. 利用JFreeChart绘制股票K线图完整解决方案

    网上有很多人在询问如何使用jfreechart来绘制股票K线图,通过阅读其中的一些例子来看,大多比较的凌乱,没有给出一个符合中国股票市场的K线图实例,因为中国的股票市场K线图的颜色表示与国外存在一点差 ...

  4. 使用jfreeChart绘制股票K线图

    http://blog.csdn.net/tufeng1992/article/details/50953419 因项目需要画K线图,上面的原文中有些类jFreeChart已经废弃,有些改了类名,运行 ...

  5. java+web+股票图表_基于Echarts的股票K线图展示

    一.概述 这是一个简单的股票K线图展示,利用echarts第三方进行配置,用户可以进行放大缩小查看K线图,还可进行拖拽. 二.演示效果 三.目录结构 其中dist文件夹是echart插件,jquery ...

  6. android自定义实现分时图,Android专业版K线图、分时图 android-kline

    android-kline 基于MPAndroidChart的专业K线图 简介 android-kline是Android平台的金融图表库,包括分时图和K线图.本项目通过继承的方式定制了最新版本的MP ...

  7. 调用Tushare数据库绘制K线图

    (一)获取股票的日线数据 (1)  导入需要的包 # 绘制k线图 import pandas as pd import matplotlib as mpl import matplotlib.pypl ...

  8. QCustomPlot之K线图(十七)

    文章目录 K线图的数据结构 K线图的风格 timeSeriesToOhlc函数 完整示例 最后 K线图需要引入的类:QCPFinancial,首先来看下K线图的示意图: 其中阳线在中国一般使用红色表示 ...

  9. plotly基于dataframe数据绘制股票K线图并过滤非交易时间

    plotly基于dataframe数据绘制股票K线图并过滤非交易时间 #ohlc过滤非交易时间: import plotly as py # 导入plotly库并命名为py import plotly ...

最新文章

  1. RNN和LSTM的正向/前向传播-图示公式和代码
  2. linux 脚本 ,shell中的与
  3. 160个Crackme021
  4. 【存储知识学习】第五章-5.4虚拟磁盘和5.5卷管理层-《大话存储》阅读笔记
  5. Quartus II13.1安装教程
  6. Swift之深入解析“泛型”的底层原理
  7. linux更新nvidia驱动程序,[下载]NVIDIA显卡Linux驱动更新304.60
  8. 5 压缩上传图片_推荐一个干净纯粹的网站,专注图片压缩、pdf相关操作
  9. Objective-C模版方法(TemplateMethod)
  10. 前端学习(3105):react-hello-jsx语法规则
  11. python读excel字体颜色_python操作excel之设置字体颜色及格式
  12. windows-DOS命令查看DirectX组件版本和软硬件信息版本
  13. 设置“文件共享”,方便两台主机共享文件
  14. C语言课程设计超级万年历
  15. 大数据开源舆情分析系统-数据处理部分架构浅析
  16. 创意的键盘钢琴音源 Native Instruments Hybrid Keys 1.1.0
  17. 创业和工作的心态问题
  18. 安装gooreplacer插件为含有googlefonts api的网页提速
  19. 武汉市计算机类中专学校排名,武汉中职中专学校一览表 2021最新排名
  20. ImageNet千分类标签翻译

热门文章

  1. Zemax光学设计(六)——MTF(调制传递函数)曲线
  2. dbg 寻找main函数
  3. nginx 排除 部分地址_在设计排除部分文化的图标时重新设计图标
  4. IEEE754标准以及非常规划定义,double的二进制转换工具类
  5. linux文件改为nobody,Nginx配置中user设置为nobody有什么用?
  6. 别被“选择大于努力”骗了!曾经我最成功的事是选了程序员做职业,如今却一败涂地。...
  7. PHP CURL解决 此图片来自QQ微信公众平台,未经允许不可引用
  8. T1.特殊的毕达哥拉斯三元数(11.19)
  9. 字符串快速变dict字典key
  10. JAVA判断字符串以什么什么开始_字符串不能以什么开头 Java 判断字符串是否以什么开头...