/*Ema - Exponential Moving Average

Input = double

Output = double

Optional Parameters

-------------------

optInTimePeriod:(From 2 to 100000)

Number of period

*/
424953
func Ema(real []float64, timePeriod int32) []float64 {
	var outBegIdx C.int
	var outNBElement C.int
	outReal := make([]float64, len(real))
	C.TA_EMA(0, C.int(len(real)-1), (*C.double)(unsafe.Pointer(&real[0])), C.int(timePeriod), &outBegIdx, &outNBElement, (*C.double)(unsafe.Pointer(&outReal[0])))
	return outReal[:outNBElement]
}
120382
func Average(audiences []db.Audience) int64 {
	var rv int64
	for _, a := range audiences {
		rv += int64(a.Audience)
	}

	if len(audiences) == 0 {
		return 0
	}

	return rv / int64(len(audiences))
}
415086
func (t *Translator) formatDateTimeComponentPeriodAbbreviated(hour int) string {
	if hour < 12 {
		return t.rules.DateTime.FormatNames.Periods.Abbreviated.AM
	}

	return t.rules.DateTime.FormatNames.Periods.Abbreviated.PM
}
183708
func (p *PWMPin) Period() (period uint32, err error) {
	buf, err := p.read(p.pwmPeriodPath())
	if err != nil {
		return
	}
	if len(buf) == 0 {
		return 0, nil
	}

	v := bytes.TrimRight(buf, "\n")
	val, e := strconv.Atoi(string(v))
	return uint32(val), e
}
1351064
func HtDcPeriod(real []float64) []float64 {
	var outBegIdx C.int
	var outNBElement C.int
	outReal := make([]float64, len(real))
	C.TA_HT_DCPERIOD(0, C.int(len(real)-1), (*C.double)(unsafe.Pointer(&real[0])), &outBegIdx, &outNBElement, (*C.double)(unsafe.Pointer(&outReal[0])))
	return outReal[:outNBElement]
}
496966
func MinIndex(real []float64, timePeriod int32) []int32 {
	var outBegIdx C.int
	var outNBElement C.int
	outInteger := make([]int32, len(real))
	C.TA_MININDEX(0, C.int(len(real)-1), (*C.double)(unsafe.Pointer(&real[0])), C.int(timePeriod), &outBegIdx, &outNBElement, (*C.int)(unsafe.Pointer(&outInteger[0])))
	return outInteger[:outNBElement]
}
608597
func (p *PWMPin) Period() (period uint32, err error) {
	if p.period == 0 {
		return p.period, errors.New("Raspi PWM pin period not set")
	}

	return p.period, nil
}
295364
func NewDefaultTrima() (indicator *Trima, err error) {
	timePeriod := 30
	return NewTrima(timePeriod, gotrade.UseClosePrice)
}
108207
func ExponentialRegression(s Series) (regressions Series, err error) {

	if len(s) == 0 {
		return nil, EmptyInputErr
	}

	var sum [6]float64

	for i := 0; i < len(s); i++ {
		if s[i].Y < 0 {
			return nil, YCoordErr
		}
		sum[0] += s[i].X
		sum[1] += s[i].Y
		sum[2] += s[i].X * s[i].X * s[i].Y
		sum[3] += s[i].Y * math.Log(s[i].Y)
		sum[4] += s[i].X * s[i].Y * math.Log(s[i].Y)
		sum[5] += s[i].X * s[i].Y
	}

	denominator := (sum[1]*sum[2] - sum[5]*sum[5])
	a := math.Pow(math.E, (sum[2]*sum[3]-sum[5]*sum[4])/denominator)
	b := (sum[1]*sum[4] - sum[5]*sum[3]) / denominator

	for j := 0; j < len(s); j++ {
		regressions = append(regressions, Coordinate{
			X: s[j].X,
			Y: a * math.Exp(b*s[j].X),
		})
	}

	return regressions, nil
}
763284
func Macd(inReal []float64, inFastPeriod int, inSlowPeriod int, inSignalPeriod int) ([]float64, []float64, []float64) {

	if inSlowPeriod < inFastPeriod {
		inSlowPeriod, inFastPeriod = inFastPeriod, inSlowPeriod
	}

	k1 := 0.0
	k2 := 0.0
	if inSlowPeriod != 0 {
		k1 = 2.0 / float64(inSlowPeriod+1)
	} else {
		inSlowPeriod = 26
		k1 = 0.075
	}
	if inFastPeriod != 0 {
		k2 = 2.0 / float64(inFastPeriod+1)
	} else {
		inFastPeriod = 12
		k2 = 0.15
	}

	lookbackSignal := inSignalPeriod - 1
	lookbackTotal := lookbackSignal
	lookbackTotal += (inSlowPeriod - 1)

	fastEMABuffer := ema(inReal, inFastPeriod, k2)
	slowEMABuffer := ema(inReal, inSlowPeriod, k1)
	for i := 0; i < len(fastEMABuffer); i++ {
		fastEMABuffer[i] = fastEMABuffer[i] - slowEMABuffer[i]
	}

	outMACD := make([]float64, len(inReal))
	for i := lookbackTotal - 1; i < len(fastEMABuffer); i++ {
		outMACD[i] = fastEMABuffer[i]
	}
	outMACDSignal := ema(outMACD, inSignalPeriod, (2.0 / float64(inSignalPeriod+1)))

	outMACDHist := make([]float64, len(inReal))
	for i := lookbackTotal; i < len(outMACDHist); i++ {
		outMACDHist[i] = outMACD[i] - outMACDSignal[i]
	}

	return outMACD, outMACDSignal, outMACDHist
}
908998
func Sum(inReal []float64, inTimePeriod int) []float64 {

	outReal := make([]float64, len(inReal))

	lookbackTotal := inTimePeriod - 1
	startIdx := lookbackTotal
	periodTotal := 0.0
	trailingIdx := startIdx - lookbackTotal
	i := trailingIdx
	if inTimePeriod > 1 {
		for i < startIdx {
			periodTotal += inReal[i]
			i++
		}
	}
	outIdx := startIdx
	for i < len(inReal) {
		periodTotal += inReal[i]
		tempReal := periodTotal
		periodTotal -= inReal[trailingIdx]
		outReal[outIdx] = tempReal
		i++
		trailingIdx++
		outIdx++
	}

	return outReal
}
170997
func Dx(inHigh []float64, inLow []float64, inClose []float64, inTimePeriod int) []float64 {

	outReal := make([]float64, len(inClose))

	lookbackTotal := 2
	if inTimePeriod > 1 {
		lookbackTotal = inTimePeriod
	}
	startIdx := lookbackTotal
	outIdx := startIdx
	prevMinusDM := 0.0
	prevPlusDM := 0.0
	prevTR := 0.0
	today := startIdx - lookbackTotal
	prevHigh := inHigh[today]
	prevLow := inLow[today]
	prevClose := inClose[today]
	i := inTimePeriod - 1
	for i > 0 {
		i--
		today++
		tempReal := inHigh[today]
		diffP := tempReal - prevHigh
		prevHigh = tempReal
		tempReal = inLow[today]
		diffM := prevLow - tempReal
		prevLow = tempReal
		if (diffM > 0) && (diffP < diffM) {
			prevMinusDM += diffM
		} else if (diffP > 0) && (diffP > diffM) {
			prevPlusDM += diffP
		}
		tempReal = prevHigh - prevLow
		tempReal2 := math.Abs(prevHigh - prevClose)
		if tempReal2 > tempReal {
			tempReal = tempReal2
		}
		tempReal2 = math.Abs(prevLow - prevClose)
		if tempReal2 > tempReal {
			tempReal = tempReal2
		}

		prevTR += tempReal
		prevClose = inClose[today]
	}

	if !(((-(0.00000000000001)) < prevTR) && (prevTR < (0.00000000000001))) {
		minusDI := (100.0 * (prevMinusDM / prevTR))
		plusDI := (100.0 * (prevPlusDM / prevTR))
		tempReal := minusDI + plusDI
		if !(((-(0.00000000000001)) < tempReal) && (tempReal < (0.00000000000001))) {
			outReal[outIdx] = (100.0 * (math.Abs(minusDI-plusDI) / tempReal))
		} else {
			outReal[outIdx] = 0.0
		}
	} else {
		outReal[outIdx] = 0.0
	}

	outIdx = startIdx
	for today < len(inClose)-1 {
		today++
		tempReal := inHigh[today]
		diffP := tempReal - prevHigh
		prevHigh = tempReal
		tempReal = inLow[today]
		diffM := prevLow - tempReal
		prevLow = tempReal
		prevMinusDM -= prevMinusDM / float64(inTimePeriod)
		prevPlusDM -= prevPlusDM / float64(inTimePeriod)
		if (diffM > 0) && (diffP < diffM) {
			prevMinusDM += diffM
		} else if (diffP > 0) && (diffP > diffM) {
			prevPlusDM += diffP
		}
		tempReal = prevHigh - prevLow
		tempReal2 := math.Abs(prevHigh - prevClose)
		if tempReal2 > tempReal {
			tempReal = tempReal2
		}
		tempReal2 = math.Abs(prevLow - prevClose)
		if tempReal2 > tempReal {
			tempReal = tempReal2
		}

		prevTR = prevTR - (prevTR / float64(inTimePeriod)) + tempReal
		prevClose = inClose[today]
		if !(((-(0.00000000000001)) < prevTR) && (prevTR < (0.00000000000001))) {
			minusDI := (100.0 * (prevMinusDM / prevTR))
			plusDI := (100.0 * (prevPlusDM / prevTR))
			tempReal = minusDI + plusDI
			if !(((-(0.00000000000001)) < tempReal) && (tempReal < (0.00000000000001))) {
				outReal[outIdx] = (100.0 * (math.Abs(minusDI-plusDI) / tempReal))
			} else {
				outReal[outIdx] = outReal[outIdx-1]
			}
		} else {
			outReal[outIdx] = outReal[outIdx-1]
		}
		outIdx++
	}
	return outReal
}
519257
func (sma SMASeries) GetPeriod(defaults ...int) int {
	if sma.Period == 0 {
		if len(defaults) > 0 {
			return defaults[0]
		}
		return DefaultSimpleMovingAveragePeriod
	}
	return sma.Period
}
139446
func MinCyclePeriod(d time.Duration) detector.Option {
	return func(di interface{}) detector.Option {
		md := di.(*MasterDetector)
		old := md.minDetectorCyclePeriod
		md.minDetectorCyclePeriod = d
		return MinCyclePeriod(old)
	}
}
685648
func TriMa(real []float64, timePeriod int32) []float64 {
	var outBegIdx C.int
	var outNBElement C.int
	outReal := make([]float64, len(real))
	C.TA_TRIMA(0, C.int(len(real)-1), (*C.double)(unsafe.Pointer(&real[0])), C.int(timePeriod), &outBegIdx, &outNBElement, (*C.double)(unsafe.Pointer(&outReal[0])))
	return outReal[:outNBElement]
}
356995
func (m *Machine) ETA() time.Duration {
	lastTool := -1
	lastToolSuggestion := -1
	var eta time.Duration
	var lx, ly, lz float64
	for _, pos := range m.Positions {
		if pos.State.ToolIndex != lastTool {
			if pos.State.ToolIndex == lastToolSuggestion {
				eta += 5 * time.Second
			} else {
				eta += 10 * time.Second
			}
		}
		lastTool = pos.State.ToolIndex
		lastToolSuggestion = pos.State.NextToolIndex

		feed := pos.State.Feedrate
		if feed <= 0 {
			// Just to use something...
			feed = 300
		}

		// Convert from minutes to microseconds
		feed /= 60000000

		switch pos.State.MoveMode {
		case MoveModeNone:
			continue
		case MoveModeRapid:
			// This is silly, but it gives something to calculate with
			feed *= 8
		case MoveModeDwell:
			eta += time.Duration(pos.State.DwellTime) * time.Second
			continue
		}
		dx, dy, dz := pos.X-lx, pos.Y-ly, pos.Z-lz
		lx, ly, lz = pos.X, pos.Y, pos.Z

		dist := math.Sqrt(math.Pow(dx, 2) + math.Pow(dy, 2) + math.Pow(dz, 2))
		eta += time.Duration(dist/feed) * time.Microsecond
	}
	return eta
}
911948
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
}