我的问题有两个,但逻辑可能相似。
我有一个简单的烛台图表,有两个不同的指标。一个位于底部,另一个位于烛台数据之上。 (见截图)
第一: 在下图中,我不想在计算之前绘制值。在这种情况下,简单移动平均线有14个周期。 (请参见黄色框的屏幕截图。不想绘制这些值)
第二: 在叠加层上我想要"打开",最低值,最高值和"关闭"最后一个酒吧。我想在这四点之间划一条线,忽略其间的所有数据。 (它应该看起来像截图中的黄线。)
如何重新设置设定图表功能以忽略下线图上14个周期之前的值?
如何忽略其他点并在组合视图的折线图上的四个值之间进行插值?
目前我必须设置我想要的值"忽略"零(1950年的截图,使其可读,而不是压扁),以摆脱界限错误。
试图尽可能地简化代码,使其更具可读性:
//
// ViewController.swift
//
import Foundation
import Cocoa
import Charts
var yValuesIndicatorLower: [Double] = []
var yValuesIndicatorOverlay: [Double] = []
class ViewController: NSViewController {
//Chart view outlets
@IBOutlet weak var combinedChartView: CombinedChartView!
@IBOutlet weak var lineChartView: LineChartView!
// Zoom Buttons
@IBAction func zoomAll(sender: AnyObject) {
combinedChartView.fitScreen()
lineChartView.fitScreen()
}
@IBAction func zoomIn(sender: AnyObject) {
combinedChartView.zoomIn()
lineChartView.zoomIn()
}
@IBAction func zoomOut(sender: AnyObject) {
combinedChartView.zoomOut()
lineChartView.zoomOut()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view.wantsLayer = true
view.layer?.backgroundColor = NSColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 0.95).CGColor
combinedChartView.noDataText = "Loading data..."
lineChartView.noDataText = "Loading data..."
// Do any additional setup after loading the view.
let xValues = ["05-16", "05-17", "05-18", "05-19", "05-20", "05-23", "05-24", "05-25", "05-26", "05-27", "05-31", "06-01", "06-02", "06-03", "06-06", "06-07", "06-08", "06-09", "06-10", "06-13", "06-14", "06-15", "06-16", "06-17", "06-20", "06-21", "06-22", "06-23", "06-24", "06-27", "06-28", "06-29", "06-30", "07-01", "07-05", "07-06", "07-07", "07-08", "07-11", "07-12", "07-13", "07-14", "07-15", "07-18", "07-19", "07-20", "07-21", "07-22", "07-25", "07-26", "07-27", "07-28", "07-29", "08-01", "08-02", "08-03"]
////Prices are ["Open"=[0], "High"=[1], "Low"=[2], "Last"[3]]
let yValues: [[Double]] = [[2032.75, 2060.0, 2027.0, 2053.5], [2052.5, 2061.0, 2028.75, 2036.5], [2035.75, 2049.5, 2022.75, 2034.75], [2035.75, 2036.25, 2014.0, 2030.5], [2030.5, 2047.5, 2029.5, 2042.0], [2043.75, 2047.5, 2035.25, 2036.75], [2037.5, 2069.0, 2032.75, 2067.0], [2066.5, 2084.25, 2065.75, 2080.75], [2080.5, 2083.75, 2074.5, 2083.0], [2082.0, 2090.25, 2080.0, 2090.25], [2091.25, 2095.25, 2078.0, 2086.25], [2085.0, 2090.75, 2075.0, 2088.75], [2088.75, 2096.0, 2078.25, 2095.25], [2094.5, 2097.25, 2074.0, 2088.25], [2088.5, 2103.25, 2085.25, 2099.75], [2099.25, 2108.75, 2098.0, 2101.75], [2101.25, 2110.75, 2098.0, 2108.5], [2108.5, 2109.5, 2097.25, 2104.75], [2104.5, 2104.75, 2079.5, 2087.0], [2081.0, 2089.25, 2066.5, 2067.25], [2067.25, 2072.75, 2054.75, 2064.75], [2064.5, 2079.5, 2059.75, 2062.5], [2062.5, 2071.5, 2040.75, 2069.5], [2068.75, 2074.75, 2053.25, 2059.75], [2071.0, 2092.5, 2070.25, 2082.75], [2079.0, 2086.0, 2074.0, 2079.25], [2079.25, 2091.25, 2075.25, 2077.0], [2083.0, 2113.25, 2083.0, 2113.25], [2115.75, 2119.5, 1999.0, 2018.25], [2013.75, 2022.5, 1981.5, 1982.0], [1982.5, 2029.75, 1982.25, 2028.25], [2028.25, 2074.75, 2022.75, 2074.25], [2072.25, 2091.25, 2056.5, 2086.5], [2086.5, 2100.75, 2081.5, 2096.25], [2099.75, 2104.75, 2072.5, 2084.5], [2084.0, 2094.5, 2065.75, 2093.0], [2092.0, 2102.0, 2081.75, 2092.25], [2092.0, 2125.5, 2087.5, 2120.75], [2120.25, 2136.75, 2120.0, 2130.5], [2130.75, 2149.25, 2128.5, 2146.0], [2145.75, 2152.25, 2139.5, 2145.75], [2145.25, 2168.0, 2142.75, 2157.75], [2156.5, 2164.75, 2143.25, 2146.0], [2154.5, 2163.25, 2152.75, 2160.25], [2160.0, 2160.75, 2151.25, 2159.0], [2159.0, 2169.75, 2155.25, 2168.75], [2168.25, 2170.25, 2153.5, 2159.25], [2159.0, 2169.25, 2156.0, 2167.25], [2167.75, 2172.5, 2155.75, 2163.25], [2162.75, 2168.0, 2153.75, 2166.0], [2166.0, 2169.25, 2152.0, 2163.25], [2162.75, 2168.5, 2153.5, 2166.0], [2165.5, 2171.75, 2157.5, 2171.0], [2174.0, 2177.75, 2159.75, 2165.5], [2166.0, 2171.0, 2141.5, 2153.0], [2152.25, 2158.25, 2145.25, 2156.75]]
//Pass values to indicators and get returned indicator values
yValuesIndicatorOverlay = indicatorOverlay(yValues)
yValuesIndicatorLower = indicatorLower(yValues)
//Pass values to chart setting function
setChart(xValues, valuesCandleChart: yValues, indicatorLowerValues: yValuesIndicatorLower, indicatorOverlayValues: yValuesIndicatorOverlay)
}
func indicatorOverlay(yValues: [[Double]]) -> [Double]{
var highest = Double()
var ZigZag: [Double] = []
for i in 0..<yValues.count {
highest = max(highest, yValues[i][1])
}
var lowest = highest
for i in 0..<yValues.count {
lowest = min(lowest, yValues[i][2])
}
for i in 0..<yValues.count {
if i == 0 {
ZigZag.append(yValues[i][0])
}
else if yValues[i][1] == highest {
ZigZag.append(highest)
}
else if yValues[i][2] == lowest {
ZigZag.append(lowest)
}
else if i == yValues.count-1 {
ZigZag.append(yValues[i][3])
}
else {
ZigZag.append(0)//These values should be ignored and then interpolated between other values.
}
}
print(highest)
print(lowest)
return ZigZag
}
func indicatorLower(yValues: [[Double]]) -> [Double]{
let peroid = 14.0
var sum = 0.0
var SMA: [Double] = []
//Simple Moving Average
for i in 0..<Int(peroid) {
sum += yValues[i][3]
if i < Int(peroid)-1 {
SMA.append(0)//These values are to be ignored
}
}
SMA.append(sum/peroid)
for i in Int(peroid)..<yValues.count {
sum = (sum - yValues[i - Int(peroid)][3]) + yValues[i][3]
SMA.append(sum/peroid)
}
return SMA
}
//Function to set chart values
func setChart(xValues: [String], valuesCandleChart: [[Double]], indicatorLowerValues: [Double], indicatorOverlayValues: [Double]) {
var yValsCandleChart : [CandleChartDataEntry] = []
for i in 0..<valuesCandleChart.count {
let high = valuesCandleChart[i][1]
let low = valuesCandleChart[i][2]
let open = valuesCandleChart[i][0]
let close = valuesCandleChart[i][3]
yValsCandleChart.append(CandleChartDataEntry(xIndex: i, shadowH: high, shadowL: low, open: open, close: close))
}
//How to ignore values that are "0" or below a set index?
var indicatorLower_yValues: [ChartDataEntry] = []
for i in 0..<xValues.count {
let indicatorLower_yValue = ChartDataEntry(value: indicatorLowerValues[i], xIndex: i)
indicatorLower_yValues.append(indicatorLower_yValue)
}
//How to use only vlaues that are calculated and not "0" to draw a ZigZag across the candlestick chart?
var indicatorOverlay_yValues: [ChartDataEntry] = []
for i in 0..<xValues.count {
let indicatorOverlay_yValue = ChartDataEntry(value: indicatorOverlayValues[i], xIndex: i)
indicatorOverlay_yValues.append(indicatorOverlay_yValue)
}
let candleChartDataSet = CandleChartDataSet(yVals: yValsCandleChart, label: "Price")
let lineOverlayChartDataSet = LineChartDataSet(yVals: indicatorOverlay_yValues, label: "indicatorOverlay")
let data: CombinedChartData = CombinedChartData(xVals: xValues)
data.candleData = CandleChartData(xVals: xValues, dataSets: [candleChartDataSet])
data.lineData = LineChartData(xVals: xValues, dataSets: [lineOverlayChartDataSet])
combinedChartView.drawOrder = [3, 2]
combinedChartView.data = data
candleChartDataSet.decreasingColor = NSColor.redColor()
candleChartDataSet.increasingColor = NSColor.greenColor()
candleChartDataSet.neutralColor = NSColor.blueColor()
candleChartDataSet.shadowColorSameAsCandle = true
candleChartDataSet.shadowWidth = 1
candleChartDataSet.decreasingFilled = true
candleChartDataSet.increasingFilled = false
candleChartDataSet.drawValuesEnabled = false
combinedChartView.doubleTapToZoomEnabled = false
lineOverlayChartDataSet.drawCirclesEnabled = false
lineOverlayChartDataSet.drawValuesEnabled = false
let lineChartDataSet = LineChartDataSet(yVals: indicatorLower_yValues, label: "indicatorLower")
let lineChartData = LineChartData(xVals: xValues, dataSet: lineChartDataSet)
lineChartView.data = lineChartData
lineChartView.doubleTapToZoomEnabled = false
lineChartDataSet.drawCirclesEnabled = false
lineChartDataSet.drawValuesEnabled = false
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
}
答案 0 :(得分:1)
要100%精确并复制底部图表(即解决方案),必须添加以下行。如果不是MA将从左上角开始,两个图表之间的x轴将不再对齐。
lineChartView.xAxis.axisMinimum = 0.0
答案 1 :(得分:0)
显示我喜欢这个库的程度。
此处有关于此问题的建议:LineChartView avoid painting 0 values #830
我所要做的就是改变这些:
//How to ignore values that are "0" or below a set index?
var indicatorLower_yValues: [ChartDataEntry] = []
for i in 0..<xValues.count {
let indicatorLower_yValue = ChartDataEntry(value: indicatorLowerValues[i], xIndex: i)
indicatorLower_yValues.append(indicatorLower_yValue)
}
//How to use only vlaues that are calculated and not "0" to draw a ZigZag across the candlestick chart?
var indicatorOverlay_yValues: [ChartDataEntry] = []
for i in 0..<xValues.count {
let indicatorOverlay_yValue = ChartDataEntry(value: indicatorOverlayValues[i], xIndex: i)
indicatorOverlay_yValues.append(indicatorOverlay_yValue)
}
对于这些:
//Ignore values that are "0"
var indicatorLower_yValues: [ChartDataEntry] = []
for i in 0..<xValues.count {
if indicatorLowerValues[i] != 0 {//ADD: If clause to skip "0"
let indicatorLower_yValue = ChartDataEntry(value: indicatorLowerValues[i], xIndex: i)
indicatorLower_yValues.append(indicatorLower_yValue)
}
}
//Use only vlaues that are not "0" to draw a ZigZag
var indicatorOverlay_yValues: [ChartDataEntry] = []
for i in 0..<xValues.count {
if indicatorOverlayValues[i] != 0 {//ADD: If clause to skip "0"
let indicatorOverlay_yValue = ChartDataEntry(value: indicatorOverlayValues[i], xIndex: i)
indicatorOverlay_yValues.append(indicatorOverlay_yValue)
}
}