基于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)函数的具体实现步骤过程中涉及到如下图所示的相关函数的实现:
调用异常日期保存方法将date保存在list集合中,并从SegmentTimeline中对当前异常时间线段进行截取标记(即将这一段从SegmentTime中去除掉)后面再次验证时就不会存在该日期的段。
在addException()函数中调用inIncludeSegments()是验证date是否包含在周一至周五(这个时间段)。包含的话就调binarySearchExceptionSegments(Segmentsegment)方法返回一 个int类型的值,用来作为add(index ,segement)的index值。
对当前的segment对象进行是否属于验证(调用inExceptionSegments()函数验证其是否是异 常段),通过验证就说明segmentTimeline中包含该时间段,对应的坐标标记和数据可以显示。
验证segment是否包含在exceptionSegments集合中,同时为在addException()时的index索 引赋值 。
画K线图对于不包含在SegmentTimeline时间线性集合中日期进行隐藏设置,使其不显示在X轴上。super.containsDomainValue(date);里调inIncludeSegments()验证是否是工作日;是工作日在进一步验证是否是异常集合中的元素,是的话,设置X轴时间标记标签时执行回滚操作(rollDate())。
执行回滚时是刻度单位(DateTickUnit)对象执行回滚操作(rollDate()),进而得到有效的标 记标签的文本值和对应的x变量值。
设置时间线段时使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线图停牌日期缺口优化完整解决方案相关推荐
- 利用JFreeChart绘制股票K线图
因为工作的需要,接触了一些股票图形绘制类的工作,其中最主要的还是股票K线图的绘制了,如果利用编程语言最底层的图形绘制方法去绘制这类图形,如果对编程语言不是特别熟悉的话,一般是有很大的困难的,通过在网上 ...
- java绘制均线图_利用JFreeChart绘制股票K线图完整解决方案
因为工作的需要,接触了一些股票图形绘制类的工作,其中最主要的还是股票K线图的绘制了,如果利用编程语言最底层的图形绘制方法去绘制这类图形,如果对编程语言不是特别熟悉的话,一般是有很大的困难的,通过在网上 ...
- 利用JFreeChart绘制股票K线图完整解决方案
网上有很多人在询问如何使用jfreechart来绘制股票K线图,通过阅读其中的一些例子来看,大多比较的凌乱,没有给出一个符合中国股票市场的K线图实例,因为中国的股票市场K线图的颜色表示与国外存在一点差 ...
- 使用jfreeChart绘制股票K线图
http://blog.csdn.net/tufeng1992/article/details/50953419 因项目需要画K线图,上面的原文中有些类jFreeChart已经废弃,有些改了类名,运行 ...
- java+web+股票图表_基于Echarts的股票K线图展示
一.概述 这是一个简单的股票K线图展示,利用echarts第三方进行配置,用户可以进行放大缩小查看K线图,还可进行拖拽. 二.演示效果 三.目录结构 其中dist文件夹是echart插件,jquery ...
- android自定义实现分时图,Android专业版K线图、分时图 android-kline
android-kline 基于MPAndroidChart的专业K线图 简介 android-kline是Android平台的金融图表库,包括分时图和K线图.本项目通过继承的方式定制了最新版本的MP ...
- 调用Tushare数据库绘制K线图
(一)获取股票的日线数据 (1) 导入需要的包 # 绘制k线图 import pandas as pd import matplotlib as mpl import matplotlib.pypl ...
- QCustomPlot之K线图(十七)
文章目录 K线图的数据结构 K线图的风格 timeSeriesToOhlc函数 完整示例 最后 K线图需要引入的类:QCPFinancial,首先来看下K线图的示意图: 其中阳线在中国一般使用红色表示 ...
- plotly基于dataframe数据绘制股票K线图并过滤非交易时间
plotly基于dataframe数据绘制股票K线图并过滤非交易时间 #ohlc过滤非交易时间: import plotly as py # 导入plotly库并命名为py import plotly ...
最新文章
- RNN和LSTM的正向/前向传播-图示公式和代码
- linux 脚本 ,shell中的与
- 160个Crackme021
- 【存储知识学习】第五章-5.4虚拟磁盘和5.5卷管理层-《大话存储》阅读笔记
- Quartus II13.1安装教程
- Swift之深入解析“泛型”的底层原理
- linux更新nvidia驱动程序,[下载]NVIDIA显卡Linux驱动更新304.60
- 5 压缩上传图片_推荐一个干净纯粹的网站,专注图片压缩、pdf相关操作
- Objective-C模版方法(TemplateMethod)
- 前端学习(3105):react-hello-jsx语法规则
- python读excel字体颜色_python操作excel之设置字体颜色及格式
- windows-DOS命令查看DirectX组件版本和软硬件信息版本
- 设置“文件共享”,方便两台主机共享文件
- C语言课程设计超级万年历
- 大数据开源舆情分析系统-数据处理部分架构浅析
- 创意的键盘钢琴音源 Native Instruments Hybrid Keys 1.1.0
- 创业和工作的心态问题
- 安装gooreplacer插件为含有googlefonts api的网页提速
- 武汉市计算机类中专学校排名,武汉中职中专学校一览表 2021最新排名
- ImageNet千分类标签翻译
热门文章
- Zemax光学设计(六)——MTF(调制传递函数)曲线
- dbg 寻找main函数
- nginx 排除 部分地址_在设计排除部分文化的图标时重新设计图标
- IEEE754标准以及非常规划定义,double的二进制转换工具类
- linux文件改为nobody,Nginx配置中user设置为nobody有什么用?
- 别被“选择大于努力”骗了!曾经我最成功的事是选了程序员做职业,如今却一败涂地。...
- PHP CURL解决 此图片来自QQ微信公众平台,未经允许不可引用
- T1.特殊的毕达哥拉斯三元数(11.19)
- 字符串快速变dict字典key
- JAVA判断字符串以什么什么开始_字符串不能以什么开头 Java 判断字符串是否以什么开头...