func (macdl MACDLineSeries) GetPeriods() (w1, w2 int) {
	if macdl.PrimaryPeriod == 0 {
		w1 = DefaultMACDPeriodPrimary
	} else {
		w1 = macdl.PrimaryPeriod
	}
	if macdl.SecondaryPeriod == 0 {
		w2 = DefaultMACDPeriodSecondary
	} else {
		w2 = macdl.SecondaryPeriod
	}
	return
}
GetPeriods returns the primary and secondary periods.
package chart
import "fmt"
const (
	DefaultMACDPeriodPrimary = 26
	DefaultMACDPeriodSecondary = 12
	DefaultMACDSignalPeriod = 9
)
type MACDSeries struct {
	Name        string
	Style       Style
	YAxis       YAxisType
	InnerSeries ValuesProvider
	PrimaryPeriod   int
	SecondaryPeriod int
	SignalPeriod    int
	signal *MACDSignalSeries
	macdl  *MACDLineSeries
}
func (macd MACDSeries) Validate() error {
	var err error
	if macd.signal != nil {
		err = macd.signal.Validate()
	}
	if err != nil {
		return err
	}
	if macd.macdl != nil {
		err = macd.macdl.Validate()
	}
	if err != nil {
		return err
	}
	return nil
}
func (macd MACDSeries) GetPeriods() (w1, w2, sig int) {
	if macd.PrimaryPeriod == 0 {
		w1 = DefaultMACDPeriodPrimary
	} else {
		w1 = macd.PrimaryPeriod
	}
	if macd.SecondaryPeriod == 0 {
		w2 = DefaultMACDPeriodSecondary
	} else {
		w2 = macd.SecondaryPeriod
	}
	if macd.SignalPeriod == 0 {
		sig = DefaultMACDSignalPeriod
	} else {
		sig = macd.SignalPeriod
	}
	return
}
func (macd MACDSeries) GetName() string {
	return macd.Name
}
func (macd MACDSeries) GetStyle() Style {
	return macd.Style
}
func (macd MACDSeries) GetYAxis() YAxisType {
	return macd.YAxis
}
func (macd MACDSeries) Len() int {
	if macd.InnerSeries == nil {
		return 0
	}
	return macd.InnerSeries.Len()
}
func (macd *MACDSeries) GetValues(index int) (x float64, y float64) {
	if macd.InnerSeries == nil {
		return
	}
	if macd.signal == nil || macd.macdl == nil {
		macd.ensureChildSeries()
	}
	_, lv := macd.macdl.GetValues(index)
	_, sv := macd.signal.GetValues(index)
	x, _ = macd.InnerSeries.GetValues(index)
	y = lv - sv
	return
}
func (macd *MACDSeries) ensureChildSeries() {
	w1, w2, sig := macd.GetPeriods()
	macd.signal = &MACDSignalSeries{
		InnerSeries:     macd.InnerSeries,
		PrimaryPeriod:   w1,
		SecondaryPeriod: w2,
		SignalPeriod:    sig,
	}
	macd.macdl = &MACDLineSeries{
		InnerSeries:     macd.InnerSeries,
		PrimaryPeriod:   w1,
		SecondaryPeriod: w2,
	}
}
type MACDSignalSeries struct {
	Name        string
	Style       Style
	YAxis       YAxisType
	InnerSeries ValuesProvider
	PrimaryPeriod   int
	SecondaryPeriod int
	SignalPeriod    int
	signal *EMASeries
}
func (macds MACDSignalSeries) Validate() error {
	if macds.signal != nil {
		return macds.signal.Validate()
	}
	return nil
}
func (macds MACDSignalSeries) GetPeriods() (w1, w2, sig int) {
	if macds.PrimaryPeriod == 0 {
		w1 = DefaultMACDPeriodPrimary
	} else {
		w1 = macds.PrimaryPeriod
	}
	if macds.SecondaryPeriod == 0 {
		w2 = DefaultMACDPeriodSecondary
	} else {
		w2 = macds.SecondaryPeriod
	}
	if macds.SignalPeriod == 0 {
		sig = DefaultMACDSignalPeriod
	} else {
		sig = macds.SignalPeriod
	}
	return
}
func (macds MACDSignalSeries) GetName() string {
	return macds.Name
}
func (macds MACDSignalSeries) GetStyle() Style {
	return macds.Style
}
func (macds MACDSignalSeries) GetYAxis() YAxisType {
	return macds.YAxis
}
func (macds *MACDSignalSeries) Len() int {
	if macds.InnerSeries == nil {
		return 0
	}
	return macds.InnerSeries.Len()
}
func (macds *MACDSignalSeries) GetValues(index int) (x float64, y float64) {
	if macds.InnerSeries == nil {
		return
	}
	if macds.signal == nil {
		macds.ensureSignal()
	}
	x, _ = macds.InnerSeries.GetValues(index)
	_, y = macds.signal.GetValues(index)
	return
}
func (macds *MACDSignalSeries) ensureSignal() {
	w1, w2, sig := macds.GetPeriods()
	macds.signal = &EMASeries{
		InnerSeries: &MACDLineSeries{
			InnerSeries:     macds.InnerSeries,
			PrimaryPeriod:   w1,
			SecondaryPeriod: w2,
		},
		Period: sig,
	}
}
func (macds *MACDSignalSeries) Render(r Renderer, canvasBox Box, xrange, yrange Range, defaults Style) {
	style := macds.Style.InheritFrom(defaults)
	Draw.LineSeries(r, canvasBox, xrange, yrange, style, macds)
}
type MACDLineSeries struct {
	Name        string
	Style       Style
	YAxis       YAxisType
	InnerSeries ValuesProvider
	PrimaryPeriod   int
	SecondaryPeriod int
	ema1 *EMASeries
	ema2 *EMASeries
	Sigma float64
}
func (macdl MACDLineSeries) Validate() error {
	var err error
	if macdl.ema1 != nil {
		err = macdl.ema1.Validate()
	}
	if err != nil {
		return err
	}
	if macdl.ema2 != nil {
		err = macdl.ema2.Validate()
	}
	if err != nil {
		return err
	}
	if macdl.InnerSeries == nil {
		return fmt.Errorf("MACDLineSeries: must provide an inner series")
	}
	return nil
}
func (macdl MACDLineSeries) GetName() string {
	return macdl.Name
}
func (macdl MACDLineSeries) GetStyle() Style {
	return macdl.Style
}
func (macdl MACDLineSeries) GetYAxis() YAxisType {
	return macdl.YAxis
}