Skip to main content

ChartIndicator

An indicator attached to a chart, with optional color overrides.

public struct ChartIndicator: Identifiable {
public var indicator: any Indicator
public var colors: [Color]
public var lineWidth: CGFloat?
public var isVisible: Bool
}
PropertyDescription
indicatorThe indicator itself. Mutable so a settings UI can write edited parameters back.
colorsOverrides for the palette this indicator's plots resolve IndicatorColorRole.series(_:) against. Empty uses the chart style's palette.
lineWidthOverrides the width of every line plot. nil keeps each plot's own width.
isVisibleHides the indicator without removing it, so a settings UI can offer a visibility toggle that preserves configuration.

Initializer​

public init(_ indicator: any Indicator, colors: [Color] = [], lineWidth: CGFloat? = nil, isVisible: Bool = true)

Computed properties​

public var id: String // stable, distinct per configuration
public var label: String // compact legend label, e.g. "RSI 14"
public var descriptor: IndicatorDescriptor // what a saved layout stores

Built-in factories​

Every factory below returns a configured ChartIndicator. See the Indicators guide for a friendlier walkthrough with descriptions and screenshots — this table is the terse signature reference.

FactorySignature
Simple moving averagestatic func sma(_ period: Int, color: Color? = nil, lineWidth: CGFloat? = nil) -> ChartIndicator
Exponential moving averagestatic func ema(_ period: Int, color: Color? = nil, lineWidth: CGFloat? = nil) -> ChartIndicator
Weighted moving averagestatic func wma(_ period: Int, color: Color? = nil, lineWidth: CGFloat? = nil) -> ChartIndicator
Bollinger Bandsstatic func bollingerBands(period: Int = 20, multiplier: Double = 2) -> ChartIndicator
VWAPstatic func vwap() -> ChartIndicator
RSIstatic func rsi(_ period: Int = 14) -> ChartIndicator
MACDstatic func macd(fast: Int = 12, slow: Int = 26, signal: Int = 9) -> ChartIndicator
Stochasticstatic func stochastic(period: Int = 14, smoothK: Int = 3, smoothD: Int = 3) -> ChartIndicator
ATRstatic func atr(_ period: Int = 14) -> ChartIndicator
On-Balance Volumestatic func obv() -> ChartIndicator
Donchian Channelsstatic func donchianChannels(period: Int = 20) -> ChartIndicator
Keltner Channelsstatic func keltnerChannels(period: Int = 20, atrPeriod: Int = 10, multiplier: Double = 2) -> ChartIndicator
SuperTrendstatic func superTrend(period: Int = 10, multiplier: Double = 3) -> ChartIndicator
Parabolic SARstatic func parabolicSAR(step: Double = 0.02, maximum: Double = 0.2) -> ChartIndicator
Ichimoku Cloudstatic func ichimokuCloud(conversionPeriod: Int = 9, basePeriod: Int = 26, spanBPeriod: Int = 52, displacement: Int = 26) -> ChartIndicator
Pivot Pointsstatic func pivotPoints(method: IndicatorMath.PivotMethod = .classic) -> ChartIndicator
ADX / DMIstatic func adx(_ period: Int = 14) -> ChartIndicator
CCIstatic func cci(_ period: Int = 20) -> ChartIndicator
Money Flow Indexstatic func mfi(_ period: Int = 14) -> ChartIndicator
Williams %Rstatic func williamsR(_ period: Int = 14) -> ChartIndicator
Rate of Changestatic func rateOfChange(period: Int = 12, mode: ROCIndicator.Mode = .percentage) -> ChartIndicator
Chaikin Money Flowstatic func chaikinMoneyFlow(_ period: Int = 20) -> ChartIndicator

Indicator

The protocol behind every indicator, built-in or custom. Conform your own type to add an indicator CandleKit doesn't ship.

public protocol Indicator: Sendable {
static var identifier: String { get }
static var displayName: String { get }
static var category: IndicatorCategory { get }

var parameters: [IndicatorParameter] { get set }
var pane: IndicatorPane { get }
var shortLabel: String { get }

func compute(_ candles: [Candle]) -> IndicatorResult
}
MemberDescription
identifierStable across releases — it's what saved layouts store. Changing it orphans existing layouts.
displayNameShown in the picker, e.g. "Relative Strength Index".
categoryAn IndicatorCategory used to group entries in a picker.
parametersConfigurable inputs. Settable so a picker can write edited values back.
paneWhere this indicator draws — .price (overlaid on the candles) or .separate(preferredHeight:) (its own pane below).
shortLabelCompact label for the chart legend, usually name plus key parameters, e.g. "RSI 14".
compute(_:)Computes every plot, fill and level for candles. Called when the data changes, not on every frame.
struct RangeIndicator: Indicator {
static let identifier = "range"
static let displayName = "High − Low"
static let category = IndicatorCategory.volatility
var parameters: [IndicatorParameter] = []
var pane: IndicatorPane { .separate() }
var shortLabel: String { "Range" }

func compute(_ candles: [Candle]) -> IndicatorResult {
IndicatorResult(plots: [
IndicatorPlot(key: "range", name: "Range", values: candles.map { $0.high - $0.low })
])
}
}

IndicatorDescriptor​

A serializable reference to a configured indicator: which one, and with what settings. This is what a saved chart layout stores.

public struct IndicatorDescriptor: Hashable, Sendable, Codable, Identifiable {
public var identifier: String
public var parameters: [String: IndicatorParameterValue]

public init(identifier: String, parameters: [String: IndicatorParameterValue] = [:])
}

IndicatorCatalog​

The set of indicators available to a chart — what a picker lists, and what saved layouts can resolve against. Immutable by design; add your own indicators with adding(_:) rather than mutating shared state.

public struct IndicatorCatalog: Sendable {
public let entries: [IndicatorCatalogEntry]

public init(entries: [IndicatorCatalogEntry])
public func entry(for identifier: String) -> IndicatorCatalogEntry?
public func makeIndicator(from descriptor: IndicatorDescriptor) -> (any Indicator)?
public func groupedByCategory() -> [(category: IndicatorCategory, entries: [IndicatorCatalogEntry])]
public func search(_ query: String) -> [IndicatorCatalogEntry]
public func adding(_ entry: IndicatorCatalogEntry) -> IndicatorCatalog
public func removing(identifier: String) -> IndicatorCatalog
}

IndicatorCatalogEntry​

One indicator type the picker can offer.

public struct IndicatorCatalogEntry: Sendable, Identifiable {
public let identifier: String
public let displayName: String
public let category: IndicatorCategory
public let defaultParameters: [IndicatorParameter]

public init<T: Indicator>(_ type: T.Type, default makeDefault: @Sendable @escaping () -> T)
public func makeDefault() -> any Indicator
public func makeIndicator(parameters stored: [String: IndicatorParameterValue]) -> any Indicator
}