2012-07-04 112 views
3

我想覆蓋一個移動平均線的OHLC圖表,但它似乎不起作用。JFreeChart:如何繪製一個OHLC圖表的移動平均線

我提供的代碼的兩個關鍵功能:

private static OHLCDataset createPriceDataset(String filename) 
{ 
    OHLCSeries s1 = new OHLCSeries(filename); 

    try { 
     BufferedReader in = new BufferedReader(new FileReader(filename)); 
     DateFormat df = new SimpleDateFormat("yyyyMMdd"); 
     String inputLine; 
     in.readLine(); 
     while ((inputLine = in.readLine()) != null) { 
      StringTokenizer st = new StringTokenizer(inputLine, ","); 
      Date date  = df.parse(st.nextToken()); 
      double open  = Double.parseDouble(st.nextToken()); 
      double high  = Double.parseDouble(st.nextToken()); 
      double low  = Double.parseDouble(st.nextToken()); 
      double close = Double.parseDouble(st.nextToken()); 
      double volume = Double.parseDouble(st.nextToken()); 
      //double adjClose = Double.parseDouble(st.nextToken()); 
      s1.add(new Day(date), open, high, low, close); 
     } 
     in.close(); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 

    OHLCSeriesCollection dataset = new OHLCSeriesCollection(); 
    dataset.addSeries(s1); 

    return dataset; 
} 



private static JFreeChart createCombinedChart() 
{ 
    OHLCDataset data1 = createPriceDataset(filename); 

    XYItemRenderer renderer1 = new HighLowRenderer(); 
    renderer1.setBaseToolTipGenerator(new StandardXYToolTipGenerator(StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT, new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("0.00"))); 
    renderer1.setSeriesPaint(0, Color.blue); 
    DateAxis domainAxis = new DateAxis("Date"); 
    NumberAxis rangeAxis = new NumberAxis("Price"); 
    rangeAxis.setNumberFormatOverride(new DecimalFormat("$0.00")); 
    rangeAxis.setAutoRange(true); 
    rangeAxis.setAutoRangeIncludesZero(false); 
    XYPlot plot1 = new XYPlot(data1, domainAxis, rangeAxis, renderer1); 
    plot1.setBackgroundPaint(Color.lightGray); 
    plot1.setDomainGridlinePaint(Color.white); 
    plot1.setRangeGridlinePaint(Color.white); 
    plot1.setRangePannable(true); 

    //Overlay the Long-Term Trend Indicator 
    XYDataset dataset3 = MovingAverage.createMovingAverage(data1, "LT", 49.0, 49.0); 
    plot1.setDataset(1, dataset3); 
    plot1.setRenderer(1, new StandardXYItemRenderer()); 

    //add a second dataset (volume) and renderer 
    IntervalXYDataset data2 = createVolumeDataset(filename); 
    XYBarRenderer renderer2 = new XYBarRenderer(); 
    renderer2.setDrawBarOutline(false); 
    renderer2.setBaseToolTipGenerator(new StandardXYToolTipGenerator(StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT, new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("0,000.00"))); 
    renderer2.setSeriesPaint(0, Color.red); 

    XYPlot plot2 = new XYPlot(data2, null, new NumberAxis("Volume"), renderer2); 
    plot2.setBackgroundPaint(Color.lightGray); 
    plot2.setDomainGridlinePaint(Color.white); 
    plot2.setRangeGridlinePaint(Color.white); 

    CombinedDomainXYPlot cplot = new CombinedDomainXYPlot(domainAxis); 
    cplot.add(plot1, 3); 
    cplot.add(plot2, 2); 
    cplot.setGap(8.0); 
    cplot.setDomainGridlinePaint(Color.white); 
    cplot.setDomainGridlinesVisible(true); 
    cplot.setDomainPannable(true); 


    //return the new combined chart 
    JFreeChart chart = new JFreeChart("Sun Microsystems (SUNW)", JFreeChart.DEFAULT_TITLE_FONT, cplot, false); 

    ChartUtilities.applyCurrentTheme(chart); 
    renderer2.setShadowVisible(false); 
    renderer2.setBarPainter(new StandardXYBarPainter()); 

    return chart; 
} 

任何想法?

謝謝。

+0

我可以理解,它可以通過包含像DefaultHighLowDataset這樣的數據類實例來完成(正如我從示例中看到的那樣),但是我不知道它是否可以使用OHLCSeriesCollection完成,因爲要計算移動平均值,噸需要的體積。這是一個僅基於價格的計算。 – skiabox

回答

4

我已經添加了下面的代碼,它似乎工作。 如果有人不同意這個解決方案只是讓我知道。 這裏有雲:

public class PriceVolumeChart2 extends ApplicationFrame{ 

final static String filename = "A.txt"; 
*static TimeSeries t1 = new TimeSeries("49-day moving average");* 

/** 
* Default constructor 
*/ 
public PriceVolumeChart2(String title) 
{ 
    super(title); 
    JPanel panel = createDemoPanel(); 
    panel.setPreferredSize(new Dimension(500, 270)); 
    setContentPane(panel); 
} 

//create price dataset 
//hard-coded here 
private static OHLCDataset createPriceDataset(String filename) 
{ 
    //the following data is taken from http://finance.yahoo.com/ 
    //for demo purposes... 

    OHLCSeries s1 = new OHLCSeries(filename); 

    try { 
     BufferedReader in = new BufferedReader(new FileReader(filename)); 
     DateFormat df = new SimpleDateFormat("yyyyMMdd"); 
     String inputLine; 
     in.readLine(); 
     while ((inputLine = in.readLine()) != null) { 
      StringTokenizer st = new StringTokenizer(inputLine, ","); 
      Date date  = df.parse(st.nextToken()); 
      double open  = Double.parseDouble(st.nextToken()); 
      double high  = Double.parseDouble(st.nextToken()); 
      double low  = Double.parseDouble(st.nextToken()); 
      double close = Double.parseDouble(st.nextToken()); 
      double volume = Double.parseDouble(st.nextToken()); 
      //double adjClose = Double.parseDouble(st.nextToken()); 
      s1.add(new Day(date), open, high, low, close); 
      *t1.add(new Day(date), close);* 
     } 
     in.close(); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 



    OHLCSeriesCollection dataset = new OHLCSeriesCollection(); 
    dataset.addSeries(s1); 

    return dataset; 
} 


//create volume dataset 
private static IntervalXYDataset createVolumeDataset(String filename) 
{ 
    //create dataset 2... 
    TimeSeries s1 = new TimeSeries("Volume"); 

    try { 
     BufferedReader in = new BufferedReader(new FileReader(filename)); 
     DateFormat df = new SimpleDateFormat("yyyyMMdd"); 
     String inputLine; 
     in.readLine(); 
     while ((inputLine = in.readLine()) != null) { 
      StringTokenizer st = new StringTokenizer(inputLine, ","); 
      Date date = df.parse(st.nextToken()); 
      st.nextToken(); 
      st.nextToken(); 
      st.nextToken(); 
      st.nextToken(); 
      double volume = Double.parseDouble(st.nextToken()); 
      //double adjClose = Double.parseDouble(st.nextToken()); 
      s1.add(new Day(date), volume); 
     } 
     in.close(); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 

    return new TimeSeriesCollection(s1); 
} 

private static JFreeChart createCombinedChart() 
{ 
    OHLCDataset data1 = createPriceDataset(filename); 

    XYItemRenderer renderer1 = new HighLowRenderer(); 
    renderer1.setBaseToolTipGenerator(new StandardXYToolTipGenerator(
     StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT, 
     new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("0.00"))); 
    renderer1.setSeriesPaint(0, Color.blue); 
    DateAxis domainAxis = new DateAxis("Date"); 
    NumberAxis rangeAxis = new NumberAxis("Price"); 
    rangeAxis.setNumberFormatOverride(new DecimalFormat("$0.00")); 
    rangeAxis.setAutoRange(true); 
    rangeAxis.setAutoRangeIncludesZero(false); 
    XYPlot plot1 = new XYPlot(data1, domainAxis, rangeAxis, renderer1); 
    plot1.setBackgroundPaint(Color.lightGray); 
    plot1.setDomainGridlinePaint(Color.white); 
    plot1.setRangeGridlinePaint(Color.white); 
    plot1.setRangePannable(true); 

    //Overlay the Long-Term Trend Indicator 
    *TimeSeries dataset3 = MovingAverage.createMovingAverage(t1, "LT", 49, 49); 
    TimeSeriesCollection collection = new TimeSeriesCollection(); 
    collection.addSeries(dataset3); 
    plot1.setDataset(1, collection);* 
    plot1.setRenderer(1, new StandardXYItemRenderer()); 

    //add a second dataset (volume) and renderer 
    IntervalXYDataset data2 = createVolumeDataset(filename); 
    XYBarRenderer renderer2 = new XYBarRenderer(); 
    renderer2.setDrawBarOutline(false); 
    renderer2.setBaseToolTipGenerator(new StandardXYToolTipGenerator(
     StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT, 
     new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("0,000.00"))); 
    renderer2.setSeriesPaint(0, Color.red); 

    XYPlot plot2 = new XYPlot(data2, null, new NumberAxis("Volume"), renderer2); 
    plot2.setBackgroundPaint(Color.lightGray); 
    plot2.setDomainGridlinePaint(Color.white); 
    plot2.setRangeGridlinePaint(Color.white); 

    CombinedDomainXYPlot cplot = new CombinedDomainXYPlot(domainAxis); 
    cplot.add(plot1, 3); 
    cplot.add(plot2, 2); 
    cplot.setGap(8.0); 
    cplot.setDomainGridlinePaint(Color.white); 
    cplot.setDomainGridlinesVisible(true); 
    cplot.setDomainPannable(true); 


    //return the new combined chart 
    JFreeChart chart = new JFreeChart("Sun Microsystems (SUNW)", 
     JFreeChart.DEFAULT_TITLE_FONT, cplot, false); 

    ChartUtilities.applyCurrentTheme(chart); 
    renderer2.setShadowVisible(false); 
    renderer2.setBarPainter(new StandardXYBarPainter()); 

    return chart; 
} 

//create a panel 
public static JPanel createDemoPanel() 
{ 
    JFreeChart chart = createCombinedChart(); 
    return new ChartPanel(chart); 
} 

public static void main(String[] args) { 
    // TODO code application logic here 
    PriceVolumeChart2 demo = new PriceVolumeChart2(
     "JFreeChart: CombinedXYPlotDemo1.java (base)"); 
    demo.pack(); 
    RefineryUtilities.centerFrameOnScreen(demo); 
    demo.setVisible(true); 
} 

//Download data from web 
} 

的樣本數據:

 
20110103,41.56,42.14,41.41,41.88,3572300 
20110104,41.99,42.1,41.18,41.49,3588800 
20110105,41.28,41.73,41,41.4,3232700 
20110106,41.37,41.84,41.21,41.48,3361400 
20110107,41.52,41.8,41.04,41.62,2725900 
20110110,41.41,42.72,41.3,42.22,3145800 
20110111,42.52,43.31,42.38,42.94,3315400 
20110112,43.2,43.41,42.96,43.13,2463100 
20110113,42.88,43.23,42.87,42.97,1676400 
20110114,42.79,43.37,42.76,43.26,2215600 
20110117,43.26,43.26,43.26,43.26,0 
20110118,43.33,44.45,43.32,44.35,2982300 
20110119,44.16,44.29,42.27,42.43,4537200 
20110120,41.95,42.58,41.46,42.29,4874700 
20110121,42.5,43.26,42.03,42.11,3004500 
20110124,42.18,42.79,42.07,42.77,2067400 
20110125,42.77,43.52,42.28,42.69,3132700 
20110126,42.82,42.97,42.04,42.57,3927300 
20110127,42.77,43.09,42.37,42.45,3189600 
20110128,42.5,42.52,40.88,40.98,3629800 
20110131,41.21,41.83,40.89,41.83,3690900 
20110201,42.07,42.7,41.93,42.05,3388200 
20110202,41.75,41.91,40.82,41.23,3970700 
20110203,40.93,41.18,40.23,40.99,3522700 
20110204,41.19,43.13,40.94,42.99,5197700 
20110207,43.45,44.66,43.37,44.44,4569800 
20110208,44.65,44.71,43.83,44.17,3734500 
20110209,44.01,44.17,43.16,43.43,3779300 
20110210,43.22,44.01,42.57,44,3275700 
20110211,43.77,45.15,43.65,45.02,4436000 
20110214,45,45.42,44.72,44.79,3484400 
20110215,44.79,45,42.64,42.65,7328000 
20110216,42.91,43.6,42.7,43.57,4159800 
20110217,43.38,44,43.02,43.92,2621800 
20110218,43.78,44.29,43.65,43.92,4390200 
20110221,43.92,43.92,43.92,43.92,0 
20110222,43.21,43.75,42.39,42.49,4143600 
20110223,42.59,42.75,39.94,40.45,7074200 
20110224,40.34,41.55,40.18,41.15,4455700 
20110225,41.16,42.41,41.13,42.36,4297500 
20110228,42.43,42.65,41.36,42.08,3070200 
20110301,41.98,42.49,40.65,40.68,4091300 

新的代碼裏面的星號。

如果您認爲有更優雅的解決方案,請告訴我。

+0

任何數據要與示例? – trashgod

+0

當然...你可以在這裏找到A.txt http://pastebin.com/r9B7FTaM – skiabox

+0

你可能想爲你的答案添加一個小子集來保證完整性。 – trashgod