Browse Source

Market

- refactoring
Alexey Kim 6 months ago
parent
commit
dbcfe85323
4 changed files with 4 additions and 5993 deletions
  1. 1 1
      go.mod
  2. 2 2
      go.sum
  3. 1 1
      market.go
  4. 0 5989
      talib/talib.go

+ 1 - 1
go.mod

@@ -2,4 +2,4 @@ module git.beejay.kim/Gshopper/sentio
 
 go 1.22.2
 
-require google.golang.org/protobuf v1.35.2
+require google.golang.org/protobuf v1.36.3

+ 2 - 2
go.sum

@@ -2,5 +2,5 @@ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
-google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
+google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU=
+google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=

+ 1 - 1
market.go

@@ -14,7 +14,7 @@ type Market interface {
 	Account() (MarketAccount, error)
 
 	CreateOrder(symbol string, quantity uint, rm RiskManager) (Order, error)
-	UpdateOrder(orderID string, sl float64) error
+	UpdateOrder(orderID string, rm RiskManager) error
 	CloseOrder(order Order) (Order, error)
 
 	Order(orderID string, nested bool) (Order, error)

+ 0 - 5989
talib/talib.go

@@ -1,5989 +0,0 @@
-package talib
-
-/*
-Copyright 2016 Mark Chenoweth
-Licensed under terms of MIT license (see LICENSE)
-*/
-
-import (
-	"errors"
-	"math"
-)
-
-// MaType - Moving average type
-type MaType int
-
-type moneyFlow struct {
-	positive float64
-	negative float64
-}
-
-// Kinds of moving averages
-const (
-	SMA MaType = iota
-	EMA
-	WMA
-	DEMA
-	TEMA
-	TRIMA
-	KAMA
-	MAMA
-	T3MA
-)
-
-/* Overlap Studies */
-
-// BBands - Bollinger Bands
-// upperband, middleband, lowerband = BBands(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
-func BBands(inReal []float64, inTimePeriod int, inNbDevUp float64, inNbDevDn float64, inMAType MaType) ([]float64, []float64, []float64) {
-
-	outRealUpperBand := make([]float64, len(inReal))
-	outRealMiddleBand := Ma(inReal, inTimePeriod, inMAType)
-	outRealLowerBand := make([]float64, len(inReal))
-
-	tempBuffer2 := StdDev(inReal, inTimePeriod, 1.0)
-
-	if inNbDevUp == inNbDevDn {
-
-		if inNbDevUp == 1.0 {
-			for i := 0; i < len(inReal); i++ {
-				tempReal := tempBuffer2[i]
-				tempReal2 := outRealMiddleBand[i]
-				outRealUpperBand[i] = tempReal2 + tempReal
-				outRealLowerBand[i] = tempReal2 - tempReal
-			}
-		} else {
-			for i := 0; i < len(inReal); i++ {
-				tempReal := tempBuffer2[i] * inNbDevUp
-				tempReal2 := outRealMiddleBand[i]
-				outRealUpperBand[i] = tempReal2 + tempReal
-				outRealLowerBand[i] = tempReal2 - tempReal
-			}
-		}
-	} else if inNbDevUp == 1.0 {
-		for i := 0; i < len(inReal); i++ {
-			tempReal := tempBuffer2[i]
-			tempReal2 := outRealMiddleBand[i]
-			outRealUpperBand[i] = tempReal2 + tempReal
-			outRealLowerBand[i] = tempReal2 - (tempReal * inNbDevDn)
-		}
-	} else if inNbDevDn == 1.0 {
-		for i := 0; i < len(inReal); i++ {
-			tempReal := tempBuffer2[i]
-			tempReal2 := outRealMiddleBand[i]
-			outRealLowerBand[i] = tempReal2 - tempReal
-			outRealUpperBand[i] = tempReal2 + (tempReal * inNbDevUp)
-		}
-	} else {
-		for i := 0; i < len(inReal); i++ {
-			tempReal := tempBuffer2[i]
-			tempReal2 := outRealMiddleBand[i]
-			outRealUpperBand[i] = tempReal2 + (tempReal * inNbDevUp)
-			outRealLowerBand[i] = tempReal2 - (tempReal * inNbDevDn)
-		}
-	}
-	return outRealUpperBand, outRealMiddleBand, outRealLowerBand
-}
-
-// Dema - Double Exponential Moving Average
-func Dema(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-	firstEMA := Ema(inReal, inTimePeriod)
-	secondEMA := Ema(firstEMA[inTimePeriod-1:], inTimePeriod)
-
-	for outIdx, secondEMAIdx := (inTimePeriod*2)-2, inTimePeriod-1; outIdx < len(inReal); outIdx, secondEMAIdx = outIdx+1, secondEMAIdx+1 {
-		outReal[outIdx] = (2.0 * firstEMA[outIdx]) - secondEMA[secondEMAIdx]
-	}
-
-	return outReal
-}
-
-// Ema - Exponential Moving Average
-func ema(inReal []float64, inTimePeriod int, k1 float64) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	lookbackTotal := inTimePeriod - 1
-	startIdx := lookbackTotal
-	today := startIdx - lookbackTotal
-	i := inTimePeriod
-	tempReal := 0.0
-	for i > 0 {
-		tempReal += inReal[today]
-		today++
-		i--
-	}
-
-	prevMA := tempReal / float64(inTimePeriod)
-
-	for today <= startIdx {
-		prevMA = ((inReal[today] - prevMA) * k1) + prevMA
-		today++
-	}
-	outReal[startIdx] = prevMA
-	outIdx := startIdx + 1
-	for today < len(inReal) {
-		prevMA = ((inReal[today] - prevMA) * k1) + prevMA
-		outReal[outIdx] = prevMA
-		today++
-		outIdx++
-	}
-
-	return outReal
-}
-
-// Ema - Exponential Moving Average
-func Ema(inReal []float64, inTimePeriod int) []float64 {
-
-	k := 2.0 / float64(inTimePeriod+1)
-	outReal := ema(inReal, inTimePeriod, k)
-	return outReal
-}
-
-// HtTrendline - Hilbert Transform - Instantaneous Trendline (lookback=63)
-func HtTrendline(inReal []float64) []float64 {
-
-	outReal := make([]float64, len(inReal))
-	a := 0.0962
-	b := 0.5769
-	detrenderOdd := make([]float64, 3)
-	detrenderEven := make([]float64, 3)
-	q1Odd := make([]float64, 3)
-	q1Even := make([]float64, 3)
-	jIOdd := make([]float64, 3)
-	jIEven := make([]float64, 3)
-	jQOdd := make([]float64, 3)
-	jQEven := make([]float64, 3)
-	smoothPriceIdx := 0
-	maxIdxSmoothPrice := (50 - 1)
-	smoothPrice := make([]float64, maxIdxSmoothPrice+1)
-	iTrend1 := 0.0
-	iTrend2 := 0.0
-	iTrend3 := 0.0
-	tempReal := math.Atan(1)
-	rad2Deg := 45.0 / tempReal
-	lookbackTotal := 63
-	startIdx := lookbackTotal
-	trailingWMAIdx := startIdx - lookbackTotal
-	today := trailingWMAIdx
-	tempReal = inReal[today]
-	today++
-	periodWMASub := tempReal
-	periodWMASum := tempReal
-	tempReal = inReal[today]
-	today++
-	periodWMASub += tempReal
-	periodWMASum += tempReal * 2.0
-	tempReal = inReal[today]
-	today++
-	periodWMASub += tempReal
-	periodWMASum += tempReal * 3.0
-	trailingWMAValue := 0.0
-	i := 34
-	for ok := true; ok; {
-		tempReal = inReal[today]
-		today++
-		periodWMASub += tempReal
-		periodWMASub -= trailingWMAValue
-		periodWMASum += tempReal * 4.0
-		trailingWMAValue = inReal[trailingWMAIdx]
-		trailingWMAIdx++
-		//smoothedValue := periodWMASum * 0.1
-		periodWMASum -= periodWMASub
-		i--
-		ok = i != 0
-	}
-	hilbertIdx := 0
-	detrender := 0.0
-	prevDetrenderOdd := 0.0
-	prevDetrenderEven := 0.0
-	prevDetrenderInputOdd := 0.0
-	prevDetrenderInputEven := 0.0
-	q1 := 0.0
-	prevq1Odd := 0.0
-	prevq1Even := 0.0
-	prevq1InputOdd := 0.0
-	prevq1InputEven := 0.0
-	jI := 0.0
-	prevJIOdd := 0.0
-	prevJIEven := 0.0
-	prevJIInputOdd := 0.0
-	prevJIInputEven := 0.0
-	jQ := 0.0
-	prevJQOdd := 0.0
-	prevJQEven := 0.0
-	prevJQInputOdd := 0.0
-	prevJQInputEven := 0.0
-	period := 0.0
-	outIdx := 63
-	previ2 := 0.0
-	prevq2 := 0.0
-	Re := 0.0
-	Im := 0.0
-	i1ForOddPrev3 := 0.0
-	i1ForEvenPrev3 := 0.0
-	i1ForOddPrev2 := 0.0
-	i1ForEvenPrev2 := 0.0
-	smoothPeriod := 0.0
-	q2 := 0.0
-	i2 := 0.0
-	for today < len(inReal) {
-		adjustedPrevPeriod := (0.075 * period) + 0.54
-		todayValue := inReal[today]
-		periodWMASub += todayValue
-		periodWMASub -= trailingWMAValue
-		periodWMASum += todayValue * 4.0
-		trailingWMAValue = inReal[trailingWMAIdx]
-		trailingWMAIdx++
-		smoothedValue := periodWMASum * 0.1
-		periodWMASum -= periodWMASub
-		smoothPrice[smoothPriceIdx] = smoothedValue
-		if (today % 2) == 0 {
-			hilbertTempReal := a * smoothedValue
-			detrender = -detrenderEven[hilbertIdx]
-			detrenderEven[hilbertIdx] = hilbertTempReal
-			detrender += hilbertTempReal
-			detrender -= prevDetrenderEven
-			prevDetrenderEven = b * prevDetrenderInputEven
-			detrender += prevDetrenderEven
-			prevDetrenderInputEven = smoothedValue
-			detrender *= adjustedPrevPeriod
-			hilbertTempReal = a * detrender
-			q1 = -q1Even[hilbertIdx]
-			q1Even[hilbertIdx] = hilbertTempReal
-			q1 += hilbertTempReal
-			q1 -= prevq1Even
-			prevq1Even = b * prevq1InputEven
-			q1 += prevq1Even
-			prevq1InputEven = detrender
-			q1 *= adjustedPrevPeriod
-			hilbertTempReal = a * i1ForEvenPrev3
-			jI = -jIEven[hilbertIdx]
-			jIEven[hilbertIdx] = hilbertTempReal
-			jI += hilbertTempReal
-			jI -= prevJIEven
-			prevJIEven = b * prevJIInputEven
-			jI += prevJIEven
-			prevJIInputEven = i1ForEvenPrev3
-			jI *= adjustedPrevPeriod
-			hilbertTempReal = a * q1
-			jQ = -jQEven[hilbertIdx]
-			jQEven[hilbertIdx] = hilbertTempReal
-			jQ += hilbertTempReal
-			jQ -= prevJQEven
-			prevJQEven = b * prevJQInputEven
-			jQ += prevJQEven
-			prevJQInputEven = q1
-			jQ *= adjustedPrevPeriod
-			hilbertIdx++
-			if hilbertIdx == 3 {
-				hilbertIdx = 0
-			}
-			q2 = (0.2 * (q1 + jI)) + (0.8 * prevq2)
-			i2 = (0.2 * (i1ForEvenPrev3 - jQ)) + (0.8 * previ2)
-			i1ForOddPrev3 = i1ForOddPrev2
-			i1ForOddPrev2 = detrender
-		} else {
-			hilbertTempReal := a * smoothedValue
-			detrender = -detrenderOdd[hilbertIdx]
-			detrenderOdd[hilbertIdx] = hilbertTempReal
-			detrender += hilbertTempReal
-			detrender -= prevDetrenderOdd
-			prevDetrenderOdd = b * prevDetrenderInputOdd
-			detrender += prevDetrenderOdd
-			prevDetrenderInputOdd = smoothedValue
-			detrender *= adjustedPrevPeriod
-			hilbertTempReal = a * detrender
-			q1 = -q1Odd[hilbertIdx]
-			q1Odd[hilbertIdx] = hilbertTempReal
-			q1 += hilbertTempReal
-			q1 -= prevq1Odd
-			prevq1Odd = b * prevq1InputOdd
-			q1 += prevq1Odd
-			prevq1InputOdd = detrender
-			q1 *= adjustedPrevPeriod
-			hilbertTempReal = a * i1ForOddPrev3
-			jI = -jIOdd[hilbertIdx]
-			jIOdd[hilbertIdx] = hilbertTempReal
-			jI += hilbertTempReal
-			jI -= prevJIOdd
-			prevJIOdd = b * prevJIInputOdd
-			jI += prevJIOdd
-			prevJIInputOdd = i1ForOddPrev3
-			jI *= adjustedPrevPeriod
-			hilbertTempReal = a * q1
-			jQ = -jQOdd[hilbertIdx]
-			jQOdd[hilbertIdx] = hilbertTempReal
-			jQ += hilbertTempReal
-			jQ -= prevJQOdd
-			prevJQOdd = b * prevJQInputOdd
-			jQ += prevJQOdd
-			prevJQInputOdd = q1
-			jQ *= adjustedPrevPeriod
-			q2 = (0.2 * (q1 + jI)) + (0.8 * prevq2)
-			i2 = (0.2 * (i1ForOddPrev3 - jQ)) + (0.8 * previ2)
-			i1ForEvenPrev3 = i1ForEvenPrev2
-			i1ForEvenPrev2 = detrender
-		}
-		Re = (0.2 * ((i2 * previ2) + (q2 * prevq2))) + (0.8 * Re)
-		Im = (0.2 * ((i2 * prevq2) - (q2 * previ2))) + (0.8 * Im)
-		prevq2 = q2
-		previ2 = i2
-		tempReal = period
-		if (Im != 0.0) && (Re != 0.0) {
-			period = 360.0 / (math.Atan(Im/Re) * rad2Deg)
-		}
-		tempReal2 := 1.5 * tempReal
-		if period > tempReal2 {
-			period = tempReal2
-		}
-		tempReal2 = 0.67 * tempReal
-		if period < tempReal2 {
-			period = tempReal2
-		}
-		if period < 6 {
-			period = 6
-		} else if period > 50 {
-			period = 50
-		}
-		period = (0.2 * period) + (0.8 * tempReal)
-		smoothPeriod = (0.33 * period) + (0.67 * smoothPeriod)
-		DCPeriod := smoothPeriod + 0.5
-		DCPeriodInt := math.Floor(DCPeriod)
-		idx := today
-		tempReal = 0.0
-		for i := 0; i < int(DCPeriodInt); i++ {
-			tempReal += inReal[idx]
-			idx--
-		}
-		if DCPeriodInt > 0 {
-			tempReal = tempReal / (DCPeriodInt * 1.0)
-		}
-		tempReal2 = (4.0*tempReal + 3.0*iTrend1 + 2.0*iTrend2 + iTrend3) / 10.0
-		iTrend3 = iTrend2
-		iTrend2 = iTrend1
-		iTrend1 = tempReal
-		if today >= startIdx {
-			outReal[outIdx] = tempReal2
-			outIdx++
-		}
-		smoothPriceIdx++
-		if smoothPriceIdx > maxIdxSmoothPrice {
-			smoothPriceIdx = 0
-		}
-
-		today++
-	}
-	return outReal
-}
-
-// Kama - Kaufman Adaptive Moving Average
-func Kama(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	constMax := 2.0 / (30.0 + 1.0)
-	constDiff := 2.0/(2.0+1.0) - constMax
-	lookbackTotal := inTimePeriod
-	startIdx := lookbackTotal
-	sumROC1 := 0.0
-	today := startIdx - lookbackTotal
-	trailingIdx := today
-	i := inTimePeriod
-	for i > 0 {
-		tempReal := inReal[today]
-		today++
-		tempReal -= inReal[today]
-		sumROC1 += math.Abs(tempReal)
-		i--
-	}
-	prevKAMA := inReal[today-1]
-	tempReal := inReal[today]
-	tempReal2 := inReal[trailingIdx]
-	trailingIdx++
-	periodROC := tempReal - tempReal2
-	trailingValue := tempReal2
-	if (sumROC1 <= periodROC) || (((-(0.00000000000001)) < sumROC1) && (sumROC1 < (0.00000000000001))) {
-		tempReal = 1.0
-	} else {
-		tempReal = math.Abs(periodROC / sumROC1)
-	}
-	tempReal = (tempReal * constDiff) + constMax
-	tempReal *= tempReal
-	prevKAMA = ((inReal[today] - prevKAMA) * tempReal) + prevKAMA
-	today++
-	for today <= startIdx {
-		tempReal = inReal[today]
-		tempReal2 = inReal[trailingIdx]
-		trailingIdx++
-		periodROC = tempReal - tempReal2
-		sumROC1 -= math.Abs(trailingValue - tempReal2)
-		sumROC1 += math.Abs(tempReal - inReal[today-1])
-		trailingValue = tempReal2
-		if (sumROC1 <= periodROC) || (((-(0.00000000000001)) < sumROC1) && (sumROC1 < (0.00000000000001))) {
-			tempReal = 1.0
-		} else {
-			tempReal = math.Abs(periodROC / sumROC1)
-		}
-		tempReal = (tempReal * constDiff) + constMax
-		tempReal *= tempReal
-		prevKAMA = ((inReal[today] - prevKAMA) * tempReal) + prevKAMA
-		today++
-	}
-	outReal[inTimePeriod] = prevKAMA
-	outIdx := inTimePeriod + 1
-	for today < len(inReal) {
-		tempReal = inReal[today]
-		tempReal2 = inReal[trailingIdx]
-		trailingIdx++
-		periodROC = tempReal - tempReal2
-		sumROC1 -= math.Abs(trailingValue - tempReal2)
-		sumROC1 += math.Abs(tempReal - inReal[today-1])
-		trailingValue = tempReal2
-		if (sumROC1 <= periodROC) || (((-(0.00000000000001)) < sumROC1) && (sumROC1 < (0.00000000000001))) {
-			tempReal = 1.0
-		} else {
-			tempReal = math.Abs(periodROC / sumROC1)
-		}
-		tempReal = (tempReal * constDiff) + constMax
-		tempReal *= tempReal
-		prevKAMA = ((inReal[today] - prevKAMA) * tempReal) + prevKAMA
-		today++
-		outReal[outIdx] = prevKAMA
-		outIdx++
-	}
-
-	return outReal
-}
-
-// Ma - Moving average
-func Ma(inReal []float64, inTimePeriod int, inMAType MaType) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	if inTimePeriod == 1 {
-		copy(outReal, inReal)
-		return outReal
-	}
-
-	switch inMAType {
-	case SMA:
-		outReal = Sma(inReal, inTimePeriod)
-	case EMA:
-		outReal = Ema(inReal, inTimePeriod)
-	case WMA:
-		outReal = Wma(inReal, inTimePeriod)
-	case DEMA:
-		outReal = Dema(inReal, inTimePeriod)
-	case TEMA:
-		outReal = Tema(inReal, inTimePeriod)
-	case TRIMA:
-		outReal = Trima(inReal, inTimePeriod)
-	case KAMA:
-		outReal = Kama(inReal, inTimePeriod)
-	case MAMA:
-		outReal, _ = Mama(inReal, 0.5, 0.05)
-	case T3MA:
-		outReal = T3(inReal, inTimePeriod, 0.7)
-	}
-	return outReal
-}
-
-// Mama - MESA Adaptive Moving Average (lookback=32)
-func Mama(inReal []float64, inFastLimit float64, inSlowLimit float64) ([]float64, []float64) {
-
-	outMAMA := make([]float64, len(inReal))
-	outFAMA := make([]float64, len(inReal))
-
-	a := 0.0962
-	b := 0.5769
-	detrenderOdd := make([]float64, 3)
-	detrenderEven := make([]float64, 3)
-	q1Odd := make([]float64, 3)
-	q1Even := make([]float64, 3)
-	jIOdd := make([]float64, 3)
-	jIEven := make([]float64, 3)
-	jQOdd := make([]float64, 3)
-	jQEven := make([]float64, 3)
-	rad2Deg := 180.0 / (4.0 * math.Atan(1))
-	lookbackTotal := 32
-	startIdx := lookbackTotal
-	trailingWMAIdx := startIdx - lookbackTotal
-	today := trailingWMAIdx
-	tempReal := inReal[today]
-	today++
-	periodWMASub := tempReal
-	periodWMASum := tempReal
-	tempReal = inReal[today]
-	today++
-	periodWMASub += tempReal
-	periodWMASum += tempReal * 2.0
-	tempReal = inReal[today]
-	today++
-	periodWMASub += tempReal
-	periodWMASum += tempReal * 3.0
-	trailingWMAValue := 0.0
-	i := 9
-	smoothedValue := 0.0
-	for ok := true; ok; {
-		tempReal = inReal[today]
-		today++
-		periodWMASub += tempReal
-		periodWMASub -= trailingWMAValue
-		periodWMASum += tempReal * 4.0
-		trailingWMAValue = inReal[trailingWMAIdx]
-		trailingWMAIdx++
-		smoothedValue = periodWMASum * 0.1
-		periodWMASum -= periodWMASub
-		i--
-		ok = i != 0
-	}
-	hilbertIdx := 0
-	detrenderOdd[0] = 0.0
-	detrenderOdd[1] = 0.0
-	detrenderOdd[2] = 0.0
-	detrenderEven[0] = 0.0
-	detrenderEven[1] = 0.0
-	detrenderEven[2] = 0.0
-	detrender := 0.0
-	prevDetrenderOdd := 0.0
-	prevDetrenderEven := 0.0
-	prevDetrenderInputOdd := 0.0
-	prevDetrenderInputEven := 0.0
-
-	q1Odd[0] = 0.0
-	q1Odd[1] = 0.0
-	q1Odd[2] = 0.0
-	q1Even[0] = 0.0
-	q1Even[1] = 0.0
-	q1Even[2] = 0.0
-	q1 := 0.0
-	prevq1Odd := 0.0
-	prevq1Even := 0.0
-	prevq1InputOdd := 0.0
-	prevq1InputEven := 0.0
-
-	jIOdd[0] = 0.0
-	jIOdd[1] = 0.0
-	jIOdd[2] = 0.0
-	jIEven[0] = 0.0
-	jIEven[1] = 0.0
-	jIEven[2] = 0.0
-	jI := 0.0
-	prevjIOdd := 0.0
-	prevjIEven := 0.0
-	prevjIInputOdd := 0.0
-	prevjIInputEven := 0.0
-
-	jQOdd[0] = 0.0
-	jQOdd[1] = 0.0
-	jQOdd[2] = 0.0
-	jQEven[0] = 0.0
-	jQEven[1] = 0.0
-	jQEven[2] = 0.0
-	jQ := 0.0
-	prevjQOdd := 0.0
-	prevjQEven := 0.0
-	prevjQInputOdd := 0.0
-	prevjQInputEven := 0.0
-
-	period := 0.0
-	outIdx := startIdx
-	previ2, prevq2 := 0.0, 0.0
-	Re, Im := 0.0, 0.0
-	mama, fama := 0.0, 0.0
-	i1ForOddPrev3, i1ForEvenPrev3 := 0.0, 0.0
-	i1ForOddPrev2, i1ForEvenPrev2 := 0.0, 0.0
-	prevPhase := 0.0
-	adjustedPrevPeriod := 0.0
-	todayValue := 0.0
-	hilbertTempReal := 0.0
-	for today < len(inReal) {
-		adjustedPrevPeriod = (0.075 * period) + 0.54
-		todayValue = inReal[today]
-
-		periodWMASub += todayValue
-		periodWMASub -= trailingWMAValue
-		periodWMASum += todayValue * 4.0
-		trailingWMAValue = inReal[trailingWMAIdx]
-		trailingWMAIdx++
-		smoothedValue = periodWMASum * 0.1
-		periodWMASum -= periodWMASub
-		q2, i2 := 0.0, 0.0
-		tempReal2 := 0.0
-		if (today % 2) == 0 {
-
-			hilbertTempReal = a * smoothedValue
-			detrender = -detrenderEven[hilbertIdx]
-			detrenderEven[hilbertIdx] = hilbertTempReal
-			detrender += hilbertTempReal
-			detrender -= prevDetrenderEven
-			prevDetrenderEven = b * prevDetrenderInputEven
-			detrender += prevDetrenderEven
-			prevDetrenderInputEven = smoothedValue
-			detrender *= adjustedPrevPeriod
-
-			hilbertTempReal = a * detrender
-			q1 = -q1Even[hilbertIdx]
-			q1Even[hilbertIdx] = hilbertTempReal
-			q1 += hilbertTempReal
-			q1 -= prevq1Even
-			prevq1Even = b * prevq1InputEven
-			q1 += prevq1Even
-			prevq1InputEven = detrender
-			q1 *= adjustedPrevPeriod
-
-			hilbertTempReal = a * i1ForEvenPrev3
-			jI = -jIEven[hilbertIdx]
-			jIEven[hilbertIdx] = hilbertTempReal
-			jI += hilbertTempReal
-			jI -= prevjIEven
-			prevjIEven = b * prevjIInputEven
-			jI += prevjIEven
-			prevjIInputEven = i1ForEvenPrev3
-			jI *= adjustedPrevPeriod
-
-			hilbertTempReal = a * q1
-			jQ = -jQEven[hilbertIdx]
-			jQEven[hilbertIdx] = hilbertTempReal
-			jQ += hilbertTempReal
-			jQ -= prevjQEven
-			prevjQEven = b * prevjQInputEven
-			jQ += prevjQEven
-			prevjQInputEven = q1
-			jQ *= adjustedPrevPeriod
-			hilbertIdx++
-			if hilbertIdx == 3 {
-				hilbertIdx = 0
-			}
-			q2 = (0.2 * (q1 + jI)) + (0.8 * prevq2)
-			i2 = (0.2 * (i1ForEvenPrev3 - jQ)) + (0.8 * previ2)
-			i1ForOddPrev3 = i1ForOddPrev2
-			i1ForOddPrev2 = detrender
-			if i1ForEvenPrev3 != 0.0 {
-				tempReal2 = (math.Atan(q1/i1ForEvenPrev3) * rad2Deg)
-			} else {
-				tempReal2 = 0.0
-			}
-		} else {
-
-			hilbertTempReal = a * smoothedValue
-			detrender = -detrenderOdd[hilbertIdx]
-			detrenderOdd[hilbertIdx] = hilbertTempReal
-			detrender += hilbertTempReal
-			detrender -= prevDetrenderOdd
-			prevDetrenderOdd = b * prevDetrenderInputOdd
-			detrender += prevDetrenderOdd
-			prevDetrenderInputOdd = smoothedValue
-			detrender *= adjustedPrevPeriod
-
-			hilbertTempReal = a * detrender
-			q1 = -q1Odd[hilbertIdx]
-			q1Odd[hilbertIdx] = hilbertTempReal
-			q1 += hilbertTempReal
-			q1 -= prevq1Odd
-			prevq1Odd = b * prevq1InputOdd
-			q1 += prevq1Odd
-			prevq1InputOdd = detrender
-			q1 *= adjustedPrevPeriod
-
-			hilbertTempReal = a * i1ForOddPrev3
-			jI = -jIOdd[hilbertIdx]
-			jIOdd[hilbertIdx] = hilbertTempReal
-			jI += hilbertTempReal
-			jI -= prevjIOdd
-			prevjIOdd = b * prevjIInputOdd
-			jI += prevjIOdd
-			prevjIInputOdd = i1ForOddPrev3
-			jI *= adjustedPrevPeriod
-
-			hilbertTempReal = a * q1
-			jQ = -jQOdd[hilbertIdx]
-			jQOdd[hilbertIdx] = hilbertTempReal
-			jQ += hilbertTempReal
-			jQ -= prevjQOdd
-			prevjQOdd = b * prevjQInputOdd
-			jQ += prevjQOdd
-			prevjQInputOdd = q1
-			jQ *= adjustedPrevPeriod
-
-			q2 = (0.2 * (q1 + jI)) + (0.8 * prevq2)
-			i2 = (0.2 * (i1ForOddPrev3 - jQ)) + (0.8 * previ2)
-			i1ForEvenPrev3 = i1ForEvenPrev2
-			i1ForEvenPrev2 = detrender
-			if i1ForOddPrev3 != 0.0 {
-				tempReal2 = (math.Atan(q1/i1ForOddPrev3) * rad2Deg)
-			} else {
-				tempReal2 = 0.0
-			}
-		}
-		tempReal = prevPhase - tempReal2
-		prevPhase = tempReal2
-		if tempReal < 1.0 {
-			tempReal = 1.0
-		}
-		if tempReal > 1.0 {
-			tempReal = inFastLimit / tempReal
-			if tempReal < inSlowLimit {
-				tempReal = inSlowLimit
-			}
-		} else {
-			tempReal = inFastLimit
-		}
-		mama = (tempReal * todayValue) + ((1 - tempReal) * mama)
-		tempReal *= 0.5
-		fama = (tempReal * mama) + ((1 - tempReal) * fama)
-		if today >= startIdx {
-			outMAMA[outIdx] = mama
-			outFAMA[outIdx] = fama
-			outIdx++
-		}
-		Re = (0.2 * ((i2 * previ2) + (q2 * prevq2))) + (0.8 * Re)
-		Im = (0.2 * ((i2 * prevq2) - (q2 * previ2))) + (0.8 * Im)
-		prevq2 = q2
-		previ2 = i2
-		tempReal = period
-		if (Im != 0.0) && (Re != 0.0) {
-			period = 360.0 / (math.Atan(Im/Re) * rad2Deg)
-		}
-		tempReal2 = 1.5 * tempReal
-		if period > tempReal2 {
-			period = tempReal2
-		}
-		tempReal2 = 0.67 * tempReal
-		if period < tempReal2 {
-			period = tempReal2
-		}
-		if period < 6 {
-			period = 6
-		} else if period > 50 {
-			period = 50
-		}
-		period = (0.2 * period) + (0.8 * tempReal)
-		today++
-	}
-	return outMAMA, outFAMA
-}
-
-// MaVp - Moving average with variable period
-func MaVp(inReal []float64, inPeriods []float64, inMinPeriod int, inMaxPeriod int, inMAType MaType) []float64 {
-
-	outReal := make([]float64, len(inReal))
-	startIdx := inMaxPeriod - 1
-	outputSize := len(inReal)
-
-	localPeriodArray := make([]float64, outputSize)
-	for i := startIdx; i < outputSize; i++ {
-		tempInt := int(inPeriods[i])
-		if tempInt < inMinPeriod {
-			tempInt = inMinPeriod
-		} else if tempInt > inMaxPeriod {
-			tempInt = inMaxPeriod
-		}
-		localPeriodArray[i] = float64(tempInt)
-	}
-
-	for i := startIdx; i < outputSize; i++ {
-		curPeriod := int(localPeriodArray[i])
-		if curPeriod != 0 {
-			localOutputArray := Ma(inReal, curPeriod, inMAType)
-			outReal[i] = localOutputArray[i]
-			for j := i + 1; j < outputSize; j++ {
-				if localPeriodArray[j] == float64(curPeriod) {
-					localPeriodArray[j] = 0
-					outReal[j] = localOutputArray[j]
-				}
-			}
-		}
-	}
-	return outReal
-}
-
-// MidPoint - MidPoint over period
-func MidPoint(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-	nbInitialElementNeeded := inTimePeriod - 1
-	startIdx := nbInitialElementNeeded
-	outIdx := inTimePeriod - 1
-	today := startIdx
-	trailingIdx := startIdx - nbInitialElementNeeded
-
-	for today < len(inReal) {
-		lowest := inReal[trailingIdx]
-		trailingIdx++
-		highest := lowest
-		for i := trailingIdx; i <= today; i++ {
-			tmp := inReal[i]
-			if tmp < lowest {
-				lowest = tmp
-			} else if tmp > highest {
-				highest = tmp
-			}
-		}
-		outReal[outIdx] = (highest + lowest) / 2.0
-		outIdx++
-		today++
-	}
-	return outReal
-}
-
-// MidPrice - Midpoint Price over period
-func MidPrice(inHigh []float64, inLow []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inHigh))
-
-	nbInitialElementNeeded := inTimePeriod - 1
-	startIdx := nbInitialElementNeeded
-	outIdx := inTimePeriod - 1
-	today := startIdx
-	trailingIdx := startIdx - nbInitialElementNeeded
-	for today < len(inHigh) {
-		lowest := inLow[trailingIdx]
-		highest := inHigh[trailingIdx]
-		trailingIdx++
-		for i := trailingIdx; i <= today; i++ {
-			tmp := inLow[i]
-			if tmp < lowest {
-				lowest = tmp
-			}
-			tmp = inHigh[i]
-			if tmp > highest {
-				highest = tmp
-			}
-		}
-		outReal[outIdx] = (highest + lowest) / 2.0
-		outIdx++
-		today++
-	}
-	return outReal
-}
-
-// Sar - Parabolic SAR
-// real = Sar(high, low, acceleration=0, maximum=0)
-func Sar(inHigh []float64, inLow []float64, inAcceleration float64, inMaximum float64) []float64 {
-
-	outReal := make([]float64, len(inHigh))
-
-	af := inAcceleration
-	if af > inMaximum {
-		af, inAcceleration = inMaximum, inMaximum
-	}
-
-	epTemp := MinusDM(inHigh, inLow, 1)
-	isLong := 1
-	if epTemp[1] > 0 {
-		isLong = 0
-	}
-	startIdx := 1
-	outIdx := startIdx
-	todayIdx := startIdx
-	newHigh := inHigh[todayIdx-1]
-	newLow := inLow[todayIdx-1]
-	sar, ep := 0.0, 0.0
-	if isLong == 1 {
-		ep = inHigh[todayIdx]
-		sar = newLow
-	} else {
-		ep = inLow[todayIdx]
-		sar = newHigh
-	}
-	newLow = inLow[todayIdx]
-	newHigh = inHigh[todayIdx]
-	prevLow := 0.0
-	prevHigh := 0.0
-	for todayIdx < len(inHigh) {
-		prevLow = newLow
-		prevHigh = newHigh
-		newLow = inLow[todayIdx]
-		newHigh = inHigh[todayIdx]
-		todayIdx++
-		if isLong == 1 {
-			if newLow <= sar {
-				isLong = 0
-				sar = ep
-				if sar < prevHigh {
-					sar = prevHigh
-				}
-				if sar < newHigh {
-					sar = newHigh
-				}
-				outReal[outIdx] = sar
-				outIdx++
-				af = inAcceleration
-				ep = newLow
-				sar = sar + af*(ep-sar)
-				if sar < prevHigh {
-					sar = prevHigh
-				}
-				if sar < newHigh {
-					sar = newHigh
-				}
-			} else {
-				outReal[outIdx] = sar
-				outIdx++
-				if newHigh > ep {
-					ep = newHigh
-					af += inAcceleration
-					if af > inMaximum {
-						af = inMaximum
-					}
-				}
-				sar = sar + af*(ep-sar)
-				if sar > prevLow {
-					sar = prevLow
-				}
-				if sar > newLow {
-					sar = newLow
-				}
-			}
-		} else {
-			if newHigh >= sar {
-				isLong = 1
-				sar = ep
-				if sar > prevLow {
-					sar = prevLow
-				}
-				if sar > newLow {
-					sar = newLow
-				}
-				outReal[outIdx] = sar
-				outIdx++
-				af = inAcceleration
-				ep = newHigh
-				sar = sar + af*(ep-sar)
-				if sar > prevLow {
-					sar = prevLow
-				}
-				if sar > newLow {
-					sar = newLow
-				}
-			} else {
-				outReal[outIdx] = sar
-				outIdx++
-				if newLow < ep {
-					ep = newLow
-					af += inAcceleration
-					if af > inMaximum {
-						af = inMaximum
-					}
-				}
-				sar = sar + af*(ep-sar)
-				if sar < prevHigh {
-					sar = prevHigh
-				}
-				if sar < newHigh {
-					sar = newHigh
-				}
-			}
-		}
-	}
-	return outReal
-}
-
-// SarExt - Parabolic SAR - Extended
-// real = SAREXT(high, low, startvalue=0, offsetonreverse=0, accelerationinitlong=0, accelerationlong=0, accelerationmaxlong=0, accelerationinitshort=0, accelerationshort=0, accelerationmaxshort=0)
-func SarExt(inHigh []float64, inLow []float64,
-	inStartValue float64,
-	inOffsetOnReverse float64,
-	inAccelerationInitLong float64,
-	inAccelerationLong float64,
-	inAccelerationMaxLong float64,
-	inAccelerationInitShort float64,
-	inAccelerationShort float64,
-	inAccelerationMaxShort float64) []float64 {
-
-	outReal := make([]float64, len(inHigh))
-
-	startIdx := 1
-	afLong := inAccelerationInitLong
-	afShort := inAccelerationInitShort
-	if afLong > inAccelerationMaxLong {
-		afLong, inAccelerationInitLong = inAccelerationMaxLong, inAccelerationMaxLong
-	}
-
-	if inAccelerationLong > inAccelerationMaxLong {
-		inAccelerationLong = inAccelerationMaxLong
-	}
-
-	if afShort > inAccelerationMaxShort {
-		afShort, inAccelerationInitShort = inAccelerationMaxShort, inAccelerationMaxShort
-	}
-
-	if inAccelerationShort > inAccelerationMaxShort {
-		inAccelerationShort = inAccelerationMaxShort
-	}
-
-	isLong := 0
-	if inStartValue == 0 {
-		epTemp := MinusDM(inHigh, inLow, 1)
-		if epTemp[1] > 0 {
-			isLong = 0
-		} else {
-			isLong = 1
-		}
-	} else if inStartValue > 0 {
-		isLong = 1
-	}
-	outIdx := startIdx
-	todayIdx := startIdx
-	newHigh := inHigh[todayIdx-1]
-	newLow := inLow[todayIdx-1]
-	ep := 0.0
-	sar := 0.0
-	if inStartValue == 0 {
-		if isLong == 1 {
-			ep = inHigh[todayIdx]
-			sar = newLow
-		} else {
-			ep = inLow[todayIdx]
-			sar = newHigh
-		}
-	} else if inStartValue > 0 {
-		ep = inHigh[todayIdx]
-		sar = inStartValue
-	} else {
-		ep = inLow[todayIdx]
-		sar = math.Abs(inStartValue)
-	}
-	newLow = inLow[todayIdx]
-	newHigh = inHigh[todayIdx]
-	prevLow := 0.0
-	prevHigh := 0.0
-	for todayIdx < len(inHigh) {
-		prevLow = newLow
-		prevHigh = newHigh
-		newLow = inLow[todayIdx]
-		newHigh = inHigh[todayIdx]
-		todayIdx++
-		if isLong == 1 {
-			if newLow <= sar {
-				isLong = 0
-				sar = ep
-				if sar < prevHigh {
-					sar = prevHigh
-				}
-				if sar < newHigh {
-					sar = newHigh
-				}
-				if inOffsetOnReverse != 0.0 {
-					sar += sar * inOffsetOnReverse
-				}
-				outReal[outIdx] = -sar
-				outIdx++
-				afShort = inAccelerationInitShort
-				ep = newLow
-				sar = sar + afShort*(ep-sar)
-				if sar < prevHigh {
-					sar = prevHigh
-				}
-				if sar < newHigh {
-					sar = newHigh
-				}
-			} else {
-				outReal[outIdx] = sar
-				outIdx++
-				if newHigh > ep {
-					ep = newHigh
-					afLong += inAccelerationLong
-					if afLong > inAccelerationMaxLong {
-						afLong = inAccelerationMaxLong
-					}
-				}
-				sar = sar + afLong*(ep-sar)
-				if sar > prevLow {
-					sar = prevLow
-				}
-				if sar > newLow {
-					sar = newLow
-				}
-			}
-		} else {
-			if newHigh >= sar {
-				isLong = 1
-				sar = ep
-				if sar > prevLow {
-					sar = prevLow
-				}
-				if sar > newLow {
-					sar = newLow
-				}
-				if inOffsetOnReverse != 0.0 {
-					sar -= sar * inOffsetOnReverse
-				}
-				outReal[outIdx] = sar
-				outIdx++
-				afLong = inAccelerationInitLong
-				ep = newHigh
-				sar = sar + afLong*(ep-sar)
-				if sar > prevLow {
-					sar = prevLow
-				}
-				if sar > newLow {
-					sar = newLow
-				}
-			} else {
-				outReal[outIdx] = -sar
-				outIdx++
-				if newLow < ep {
-					ep = newLow
-					afShort += inAccelerationShort
-					if afShort > inAccelerationMaxShort {
-						afShort = inAccelerationMaxShort
-					}
-				}
-				sar = sar + afShort*(ep-sar)
-				if sar < prevHigh {
-					sar = prevHigh
-				}
-				if sar < newHigh {
-					sar = newHigh
-				}
-			}
-		}
-	}
-	return outReal
-}
-
-// Sma - Simple Moving Average
-func Sma(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 ok := true; ok; {
-		periodTotal += inReal[i]
-		tempReal := periodTotal
-		periodTotal -= inReal[trailingIdx]
-		outReal[outIdx] = tempReal / float64(inTimePeriod)
-		trailingIdx++
-		i++
-		outIdx++
-		ok = i < len(outReal)
-	}
-
-	return outReal
-}
-
-// T3 - Triple Exponential Moving Average (T3) (lookback=6*inTimePeriod)
-func T3(inReal []float64, inTimePeriod int, inVFactor float64) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	lookbackTotal := 6 * (inTimePeriod - 1)
-	startIdx := lookbackTotal
-	today := startIdx - lookbackTotal
-	k := 2.0 / (float64(inTimePeriod) + 1.0)
-	oneMinusK := 1.0 - k
-	tempReal := inReal[today]
-	today++
-	for i := inTimePeriod - 1; i > 0; i-- {
-		tempReal += inReal[today]
-		today++
-	}
-	e1 := tempReal / float64(inTimePeriod)
-	tempReal = e1
-	for i := inTimePeriod - 1; i > 0; i-- {
-		e1 = (k * inReal[today]) + (oneMinusK * e1)
-		tempReal += e1
-		today++
-	}
-	e2 := tempReal / float64(inTimePeriod)
-	tempReal = e2
-	for i := inTimePeriod - 1; i > 0; i-- {
-		e1 = (k * inReal[today]) + (oneMinusK * e1)
-		e2 = (k * e1) + (oneMinusK * e2)
-		tempReal += e2
-		today++
-	}
-	e3 := tempReal / float64(inTimePeriod)
-	tempReal = e3
-	for i := inTimePeriod - 1; i > 0; i-- {
-		e1 = (k * inReal[today]) + (oneMinusK * e1)
-		e2 = (k * e1) + (oneMinusK * e2)
-		e3 = (k * e2) + (oneMinusK * e3)
-		tempReal += e3
-		today++
-	}
-	e4 := tempReal / float64(inTimePeriod)
-	tempReal = e4
-	for i := inTimePeriod - 1; i > 0; i-- {
-		e1 = (k * inReal[today]) + (oneMinusK * e1)
-		e2 = (k * e1) + (oneMinusK * e2)
-		e3 = (k * e2) + (oneMinusK * e3)
-		e4 = (k * e3) + (oneMinusK * e4)
-		tempReal += e4
-		today++
-	}
-	e5 := tempReal / float64(inTimePeriod)
-	tempReal = e5
-	for i := inTimePeriod - 1; i > 0; i-- {
-		e1 = (k * inReal[today]) + (oneMinusK * e1)
-		e2 = (k * e1) + (oneMinusK * e2)
-		e3 = (k * e2) + (oneMinusK * e3)
-		e4 = (k * e3) + (oneMinusK * e4)
-		e5 = (k * e4) + (oneMinusK * e5)
-		tempReal += e5
-		today++
-	}
-	e6 := tempReal / float64(inTimePeriod)
-	for today <= startIdx {
-		e1 = (k * inReal[today]) + (oneMinusK * e1)
-		e2 = (k * e1) + (oneMinusK * e2)
-		e3 = (k * e2) + (oneMinusK * e3)
-		e4 = (k * e3) + (oneMinusK * e4)
-		e5 = (k * e4) + (oneMinusK * e5)
-		e6 = (k * e5) + (oneMinusK * e6)
-		today++
-	}
-	tempReal = inVFactor * inVFactor
-	c1 := -(tempReal * inVFactor)
-	c2 := 3.0 * (tempReal - c1)
-	c3 := -6.0*tempReal - 3.0*(inVFactor-c1)
-	c4 := 1.0 + 3.0*inVFactor - c1 + 3.0*tempReal
-	outIdx := lookbackTotal
-	outReal[outIdx] = c1*e6 + c2*e5 + c3*e4 + c4*e3
-	outIdx++
-	for today < len(inReal) {
-		e1 = (k * inReal[today]) + (oneMinusK * e1)
-		e2 = (k * e1) + (oneMinusK * e2)
-		e3 = (k * e2) + (oneMinusK * e3)
-		e4 = (k * e3) + (oneMinusK * e4)
-		e5 = (k * e4) + (oneMinusK * e5)
-		e6 = (k * e5) + (oneMinusK * e6)
-		outReal[outIdx] = c1*e6 + c2*e5 + c3*e4 + c4*e3
-		outIdx++
-		today++
-	}
-
-	return outReal
-}
-
-// Tema - Triple Exponential Moving Average
-func Tema(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-	firstEMA := Ema(inReal, inTimePeriod)
-	secondEMA := Ema(firstEMA[inTimePeriod-1:], inTimePeriod)
-	thirdEMA := Ema(secondEMA[inTimePeriod-1:], inTimePeriod)
-
-	outIdx := (inTimePeriod * 3) - 3
-	secondEMAIdx := (inTimePeriod * 2) - 2
-	thirdEMAIdx := inTimePeriod - 1
-
-	for outIdx < len(inReal) {
-		outReal[outIdx] = thirdEMA[thirdEMAIdx] + ((3.0 * firstEMA[outIdx]) - (3.0 * secondEMA[secondEMAIdx]))
-		outIdx++
-		secondEMAIdx++
-		thirdEMAIdx++
-	}
-
-	return outReal
-}
-
-// Trima - Triangular Moving Average
-func Trima(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	lookbackTotal := inTimePeriod - 1
-	startIdx := lookbackTotal
-	outIdx := inTimePeriod - 1
-	var factor float64
-
-	if inTimePeriod%2 == 1 {
-		i := inTimePeriod >> 1
-		factor = (float64(i) + 1.0) * (float64(i) + 1.0)
-		factor = 1.0 / factor
-		trailingIdx := startIdx - lookbackTotal
-		middleIdx := trailingIdx + i
-		todayIdx := middleIdx + i
-		numerator := 0.0
-		numeratorSub := 0.0
-		for i := middleIdx; i >= trailingIdx; i-- {
-			tempReal := inReal[i]
-			numeratorSub += tempReal
-			numerator += numeratorSub
-		}
-		numeratorAdd := 0.0
-		middleIdx++
-		for i := middleIdx; i <= todayIdx; i++ {
-			tempReal := inReal[i]
-			numeratorAdd += tempReal
-			numerator += numeratorAdd
-		}
-		outIdx = inTimePeriod - 1
-		tempReal := inReal[trailingIdx]
-		trailingIdx++
-		outReal[outIdx] = numerator * factor
-		outIdx++
-		todayIdx++
-		for todayIdx < len(inReal) {
-			numerator -= numeratorSub
-			numeratorSub -= tempReal
-			tempReal = inReal[middleIdx]
-			middleIdx++
-			numeratorSub += tempReal
-			numerator += numeratorAdd
-			numeratorAdd -= tempReal
-			tempReal = inReal[todayIdx]
-			todayIdx++
-			numeratorAdd += tempReal
-			numerator += tempReal
-			tempReal = inReal[trailingIdx]
-			trailingIdx++
-			outReal[outIdx] = numerator * factor
-			outIdx++
-		}
-
-	} else {
-
-		i := (inTimePeriod >> 1)
-		factor = float64(i) * (float64(i) + 1)
-		factor = 1.0 / factor
-		trailingIdx := startIdx - lookbackTotal
-		middleIdx := trailingIdx + i - 1
-		todayIdx := middleIdx + i
-		numerator := 0.0
-		numeratorSub := 0.0
-		for i := middleIdx; i >= trailingIdx; i-- {
-			tempReal := inReal[i]
-			numeratorSub += tempReal
-			numerator += numeratorSub
-		}
-		numeratorAdd := 0.0
-		middleIdx++
-		for i := middleIdx; i <= todayIdx; i++ {
-			tempReal := inReal[i]
-			numeratorAdd += tempReal
-			numerator += numeratorAdd
-		}
-		outIdx = inTimePeriod - 1
-		tempReal := inReal[trailingIdx]
-		trailingIdx++
-		outReal[outIdx] = numerator * factor
-		outIdx++
-		todayIdx++
-
-		for todayIdx < len(inReal) {
-			numerator -= numeratorSub
-			numeratorSub -= tempReal
-			tempReal = inReal[middleIdx]
-			middleIdx++
-			numeratorSub += tempReal
-			numeratorAdd -= tempReal
-			numerator += numeratorAdd
-			tempReal = inReal[todayIdx]
-			todayIdx++
-			numeratorAdd += tempReal
-			numerator += tempReal
-			tempReal = inReal[trailingIdx]
-			trailingIdx++
-			outReal[outIdx] = numerator * factor
-			outIdx++
-		}
-	}
-	return outReal
-}
-
-// Wma - Weighted Moving Average
-func Wma(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	lookbackTotal := inTimePeriod - 1
-	startIdx := lookbackTotal
-
-	if inTimePeriod == 1 {
-		copy(outReal, inReal)
-		return outReal
-	}
-	divider := (inTimePeriod * (inTimePeriod + 1)) >> 1
-	outIdx := inTimePeriod - 1
-	trailingIdx := startIdx - lookbackTotal
-	periodSum, periodSub := 0.0, 0.0
-	inIdx := trailingIdx
-	i := 1
-	for inIdx < startIdx {
-		tempReal := inReal[inIdx]
-		periodSub += tempReal
-		periodSum += tempReal * float64(i)
-		inIdx++
-		i++
-	}
-	trailingValue := 0.0
-	for inIdx < len(inReal) {
-		tempReal := inReal[inIdx]
-		periodSub += tempReal
-		periodSub -= trailingValue
-		periodSum += tempReal * float64(inTimePeriod)
-		trailingValue = inReal[trailingIdx]
-		outReal[outIdx] = periodSum / float64(divider)
-		periodSum -= periodSub
-		inIdx++
-		trailingIdx++
-		outIdx++
-	}
-	return outReal
-}
-
-/* Momentum Indicators */
-
-// Adx - Average Directional Movement Index
-func Adx(inHigh []float64, inLow []float64, inClose []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inClose))
-
-	inTimePeriodF := float64(inTimePeriod)
-	lookbackTotal := (2 * inTimePeriod) - 1
-	startIdx := lookbackTotal
-	outIdx := inTimePeriod
-	prevMinusDM := 0.0
-	prevPlusDM := 0.0
-	prevTR := 0.0
-	today := startIdx - lookbackTotal
-	prevHigh := inHigh[today]
-	prevLow := inLow[today]
-	prevClose := inClose[today]
-	for i := inTimePeriod - 1; 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]
-	}
-	sumDX := 0.0
-	for i := inTimePeriod; i > 0; i-- {
-		today++
-		tempReal := inHigh[today]
-		diffP := tempReal - prevHigh
-		prevHigh = tempReal
-		tempReal = inLow[today]
-		diffM := prevLow - tempReal
-		prevLow = tempReal
-		prevMinusDM -= prevMinusDM / inTimePeriodF
-		prevPlusDM -= prevPlusDM / inTimePeriodF
-		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 / inTimePeriodF) + 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))) {
-				sumDX += (100.0 * (math.Abs(minusDI-plusDI) / tempReal))
-			}
-		}
-	}
-	prevADX := (sumDX / inTimePeriodF)
-
-	outReal[startIdx] = prevADX
-	outIdx = startIdx + 1
-	today++
-	for today < len(inClose) {
-		tempReal := inHigh[today]
-		diffP := tempReal - prevHigh
-		prevHigh = tempReal
-		tempReal = inLow[today]
-		diffM := prevLow - tempReal
-		prevLow = tempReal
-		prevMinusDM -= prevMinusDM / inTimePeriodF
-		prevPlusDM -= prevPlusDM / inTimePeriodF
-		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 / inTimePeriodF) + 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))) {
-				tempReal = (100.0 * (math.Abs(minusDI-plusDI) / tempReal))
-				prevADX = (((prevADX * (inTimePeriodF - 1)) + tempReal) / inTimePeriodF)
-			}
-		}
-		outReal[outIdx] = prevADX
-		outIdx++
-		today++
-	}
-	return outReal
-}
-
-// AdxR - Average Directional Movement Index Rating
-func AdxR(inHigh []float64, inLow []float64, inClose []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inClose))
-	startIdx := (2 * inTimePeriod) - 1
-	tmpadx := Adx(inHigh, inLow, inClose, inTimePeriod)
-	i := startIdx
-	j := startIdx + inTimePeriod - 1
-	for outIdx := startIdx + inTimePeriod - 1; outIdx < len(inClose); outIdx, i, j = outIdx+1, i+1, j+1 {
-		outReal[outIdx] = ((tmpadx[i] + tmpadx[j]) / 2.0)
-	}
-	return outReal
-}
-
-// Apo - Absolute Price Oscillator
-func Apo(inReal []float64, inFastPeriod int, inSlowPeriod int, inMAType MaType) []float64 {
-
-	if inSlowPeriod < inFastPeriod {
-		inSlowPeriod, inFastPeriod = inFastPeriod, inSlowPeriod
-	}
-	tempBuffer := Ma(inReal, inFastPeriod, inMAType)
-	outReal := Ma(inReal, inSlowPeriod, inMAType)
-	for i := inSlowPeriod - 1; i < len(inReal); i++ {
-		outReal[i] = tempBuffer[i] - outReal[i]
-	}
-
-	return outReal
-}
-
-// Aroon - Aroon
-// aroondown, aroonup = AROON(high, low, timeperiod=14)
-func Aroon(inHigh []float64, inLow []float64, inTimePeriod int) ([]float64, []float64) {
-
-	outAroonUp := make([]float64, len(inHigh))
-	outAroonDown := make([]float64, len(inHigh))
-
-	startIdx := inTimePeriod
-	outIdx := startIdx
-	today := startIdx
-	trailingIdx := startIdx - inTimePeriod
-	lowestIdx := -1
-	highestIdx := -1
-	lowest := 0.0
-	highest := 0.0
-	factor := 100.0 / float64(inTimePeriod)
-	for today < len(inHigh) {
-		tmp := inLow[today]
-		if lowestIdx < trailingIdx {
-			lowestIdx = trailingIdx
-			lowest = inLow[lowestIdx]
-			i := lowestIdx
-			i++
-			for i <= today {
-				tmp = inLow[i]
-				if tmp <= lowest {
-					lowestIdx = i
-					lowest = tmp
-				}
-				i++
-			}
-		} else if tmp <= lowest {
-			lowestIdx = today
-			lowest = tmp
-		}
-		tmp = inHigh[today]
-		if highestIdx < trailingIdx {
-			highestIdx = trailingIdx
-			highest = inHigh[highestIdx]
-			i := highestIdx
-			i++
-			for i <= today {
-				tmp = inHigh[i]
-				if tmp >= highest {
-					highestIdx = i
-					highest = tmp
-				}
-				i++
-			}
-		} else if tmp >= highest {
-			highestIdx = today
-			highest = tmp
-		}
-		outAroonUp[outIdx] = factor * float64(inTimePeriod-(today-highestIdx))
-		outAroonDown[outIdx] = factor * float64(inTimePeriod-(today-lowestIdx))
-		outIdx++
-		trailingIdx++
-		today++
-	}
-	return outAroonDown, outAroonUp
-}
-
-// AroonOsc - Aroon Oscillator
-func AroonOsc(inHigh []float64, inLow []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inHigh))
-
-	startIdx := inTimePeriod
-	outIdx := startIdx
-	today := startIdx
-	trailingIdx := startIdx - inTimePeriod
-	lowestIdx := -1
-	highestIdx := -1
-	lowest := 0.0
-	highest := 0.0
-	factor := 100.0 / float64(inTimePeriod)
-	for today < len(inHigh) {
-		tmp := inLow[today]
-		if lowestIdx < trailingIdx {
-			lowestIdx = trailingIdx
-			lowest = inLow[lowestIdx]
-			i := lowestIdx
-			i++
-			for i <= today {
-				tmp = inLow[i]
-				if tmp <= lowest {
-					lowestIdx = i
-					lowest = tmp
-				}
-				i++
-			}
-		} else if tmp <= lowest {
-			lowestIdx = today
-			lowest = tmp
-		}
-		tmp = inHigh[today]
-		if highestIdx < trailingIdx {
-			highestIdx = trailingIdx
-			highest = inHigh[highestIdx]
-			i := highestIdx
-			i++
-			for i <= today {
-				tmp = inHigh[i]
-				if tmp >= highest {
-					highestIdx = i
-					highest = tmp
-				}
-				i++
-			}
-		} else if tmp >= highest {
-			highestIdx = today
-			highest = tmp
-		}
-		aroon := factor * float64(highestIdx-lowestIdx)
-		outReal[outIdx] = aroon
-		outIdx++
-		trailingIdx++
-		today++
-	}
-
-	return outReal
-}
-
-// Bop - Balance Of Power
-func Bop(inOpen []float64, inHigh []float64, inLow []float64, inClose []float64) []float64 {
-
-	outReal := make([]float64, len(inClose))
-
-	for i := 0; i < len(inClose); i++ {
-		tempReal := inHigh[i] - inLow[i]
-		if tempReal < (0.00000000000001) {
-			outReal[i] = 0.0
-		} else {
-			outReal[i] = (inClose[i] - inOpen[i]) / tempReal
-		}
-	}
-
-	return outReal
-}
-
-// Cmo - Chande Momentum Oscillator
-func Cmo(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	lookbackTotal := inTimePeriod
-	startIdx := lookbackTotal
-	outIdx := startIdx
-	if inTimePeriod == 1 {
-		copy(outReal, inReal)
-		return outReal
-	}
-	today := startIdx - lookbackTotal
-	prevValue := inReal[today]
-	prevGain := 0.0
-	prevLoss := 0.0
-	today++
-	for i := inTimePeriod; i > 0; i-- {
-		tempValue1 := inReal[today]
-		tempValue2 := tempValue1 - prevValue
-		prevValue = tempValue1
-		if tempValue2 < 0 {
-			prevLoss -= tempValue2
-		} else {
-			prevGain += tempValue2
-		}
-		today++
-	}
-	prevLoss /= float64(inTimePeriod)
-	prevGain /= float64(inTimePeriod)
-	if today > startIdx {
-		tempValue1 := prevGain + prevLoss
-		if !(((-(0.00000000000001)) < tempValue1) && (tempValue1 < (0.00000000000001))) {
-			outReal[outIdx] = 100.0 * ((prevGain - prevLoss) / tempValue1)
-		} else {
-			outReal[outIdx] = 0.0
-		}
-		outIdx++
-	} else {
-		for today < startIdx {
-			tempValue1 := inReal[today]
-			tempValue2 := tempValue1 - prevValue
-			prevValue = tempValue1
-			prevLoss *= float64(inTimePeriod - 1)
-			prevGain *= float64(inTimePeriod - 1)
-			if tempValue2 < 0 {
-				prevLoss -= tempValue2
-			} else {
-				prevGain += tempValue2
-			}
-			prevLoss /= float64(inTimePeriod)
-			prevGain /= float64(inTimePeriod)
-			today++
-		}
-	}
-	for today < len(inReal) {
-		tempValue1 := inReal[today]
-		today++
-		tempValue2 := tempValue1 - prevValue
-		prevValue = tempValue1
-		prevLoss *= float64(inTimePeriod - 1)
-		prevGain *= float64(inTimePeriod - 1)
-		if tempValue2 < 0 {
-			prevLoss -= tempValue2
-		} else {
-			prevGain += tempValue2
-		}
-		prevLoss /= float64(inTimePeriod)
-		prevGain /= float64(inTimePeriod)
-		tempValue1 = prevGain + prevLoss
-		if !(((-(0.00000000000001)) < tempValue1) && (tempValue1 < (0.00000000000001))) {
-			outReal[outIdx] = 100.0 * ((prevGain - prevLoss) / tempValue1)
-		} else {
-			outReal[outIdx] = 0.0
-		}
-		outIdx++
-	}
-	return outReal
-}
-
-// Cci - Commodity Channel Index
-func Cci(inHigh []float64, inLow []float64, inClose []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inClose))
-
-	circBufferIdx := 0
-	lookbackTotal := inTimePeriod - 1
-	startIdx := lookbackTotal
-	circBuffer := make([]float64, inTimePeriod)
-	maxIdxCircBuffer := (inTimePeriod - 1)
-	i := startIdx - lookbackTotal
-	if inTimePeriod > 1 {
-		for i < startIdx {
-			circBuffer[circBufferIdx] = (inHigh[i] + inLow[i] + inClose[i]) / 3
-			i++
-			circBufferIdx++
-			if circBufferIdx > maxIdxCircBuffer {
-				circBufferIdx = 0
-			}
-
-		}
-	}
-	outIdx := inTimePeriod - 1
-	for i < len(inClose) {
-		lastValue := (inHigh[i] + inLow[i] + inClose[i]) / 3
-		circBuffer[circBufferIdx] = lastValue
-		theAverage := 0.0
-		for j := 0; j < inTimePeriod; j++ {
-			theAverage += circBuffer[j]
-		}
-
-		theAverage /= float64(inTimePeriod)
-		tempReal2 := 0.0
-		for j := 0; j < inTimePeriod; j++ {
-			tempReal2 += math.Abs(circBuffer[j] - theAverage)
-		}
-		tempReal := lastValue - theAverage
-		if (tempReal != 0.0) && (tempReal2 != 0.0) {
-			outReal[outIdx] = tempReal / (0.015 * (tempReal2 / float64(inTimePeriod)))
-		} else {
-			outReal[outIdx] = 0.0
-		}
-		{
-			circBufferIdx++
-			if circBufferIdx > maxIdxCircBuffer {
-				circBufferIdx = 0
-			}
-		}
-		outIdx++
-		i++
-	}
-
-	return outReal
-}
-
-// Dx - Directional Movement Index
-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
-}
-
-// Macd - Moving Average Convergence/Divergence
-// unstable period ~= 100
-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
-}
-
-// MacdExt - MACD with controllable MA type
-// unstable period ~= 100
-func MacdExt(inReal []float64, inFastPeriod int, inFastMAType MaType, inSlowPeriod int, inSlowMAType MaType, inSignalPeriod int, inSignalMAType MaType) ([]float64, []float64, []float64) {
-
-	lookbackLargest := 0
-	if inFastPeriod < inSlowPeriod {
-		lookbackLargest = inSlowPeriod
-	} else {
-		lookbackLargest = inFastPeriod
-	}
-	lookbackTotal := (inSignalPeriod - 1) + (lookbackLargest - 1)
-
-	outMACD := make([]float64, len(inReal))
-	outMACDSignal := make([]float64, len(inReal))
-	outMACDHist := make([]float64, len(inReal))
-
-	slowMABuffer := Ma(inReal, inSlowPeriod, inSlowMAType)
-	fastMABuffer := Ma(inReal, inFastPeriod, inFastMAType)
-	tempBuffer1 := make([]float64, len(inReal))
-
-	for i := 0; i < len(slowMABuffer); i++ {
-		tempBuffer1[i] = fastMABuffer[i] - slowMABuffer[i]
-	}
-	tempBuffer2 := Ma(tempBuffer1, inSignalPeriod, inSignalMAType)
-
-	for i := lookbackTotal; i < len(outMACDHist); i++ {
-		outMACD[i] = tempBuffer1[i]
-		outMACDSignal[i] = tempBuffer2[i]
-		outMACDHist[i] = outMACD[i] - outMACDSignal[i]
-	}
-
-	return outMACD, outMACDSignal, outMACDHist
-}
-
-// MacdFix - MACD Fix 12/26
-// unstable period ~= 100
-func MacdFix(inReal []float64, inSignalPeriod int) ([]float64, []float64, []float64) {
-	return Macd(inReal, 0, 0, inSignalPeriod)
-}
-
-// MinusDI - Minus Directional Indicator
-func MinusDI(inHigh []float64, inLow []float64, inClose []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inClose))
-
-	lookbackTotal := 1
-	if inTimePeriod > 1 {
-		lookbackTotal = inTimePeriod
-	}
-	startIdx := lookbackTotal
-	outIdx := startIdx
-
-	prevHigh := 0.0
-	prevLow := 0.0
-	prevClose := 0.0
-	if inTimePeriod <= 1 {
-		today := startIdx - 1
-		prevHigh = inHigh[today]
-		prevLow = inLow[today]
-		prevClose = inClose[today]
-		for today < len(inClose)-1 {
-			today++
-			tempReal := inHigh[today]
-			diffP := tempReal - prevHigh
-			prevHigh = tempReal
-			tempReal = inLow[today]
-			diffM := prevLow - tempReal
-			prevLow = tempReal
-			if (diffM > 0) && (diffP < diffM) {
-
-				tempReal = prevHigh - prevLow
-				tempReal2 := math.Abs(prevHigh - prevClose)
-				if tempReal2 > tempReal {
-					tempReal = tempReal2
-				}
-				tempReal2 = math.Abs(prevLow - prevClose)
-				if tempReal2 > tempReal {
-					tempReal = tempReal2
-				}
-
-				if ((-(0.00000000000001)) < tempReal) && (tempReal < (0.00000000000001)) {
-					outReal[outIdx] = 0.0
-				} else {
-					outReal[outIdx] = diffM / tempReal
-				}
-				outIdx++
-			} else {
-				outReal[outIdx] = 0.0
-				outIdx++
-			}
-			prevClose = inClose[today]
-		}
-		return outReal
-	}
-	prevMinusDM := 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
-		}
-		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]
-	}
-	i = 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 = prevMinusDM - (prevMinusDM / float64(inTimePeriod)) + diffM
-		} else {
-			prevMinusDM = prevMinusDM - (prevMinusDM / float64(inTimePeriod))
-		}
-		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))) {
-		outReal[startIdx] = (100.0 * (prevMinusDM / prevTR))
-	} else {
-		outReal[startIdx] = 0.0
-	}
-	outIdx = startIdx + 1
-	for today < len(inClose)-1 {
-		today++
-		tempReal := inHigh[today]
-		diffP := tempReal - prevHigh
-		prevHigh = tempReal
-		tempReal = inLow[today]
-		diffM := prevLow - tempReal
-		prevLow = tempReal
-		if (diffM > 0) && (diffP < diffM) {
-			prevMinusDM = prevMinusDM - (prevMinusDM / float64(inTimePeriod)) + diffM
-		} else {
-			prevMinusDM = prevMinusDM - (prevMinusDM / float64(inTimePeriod))
-		}
-		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))) {
-			outReal[outIdx] = (100.0 * (prevMinusDM / prevTR))
-		} else {
-			outReal[outIdx] = 0.0
-		}
-		outIdx++
-	}
-
-	return outReal
-}
-
-// MinusDM - Minus Directional Movement
-func MinusDM(inHigh []float64, inLow []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inHigh))
-
-	lookbackTotal := 1
-	if inTimePeriod > 1 {
-		lookbackTotal = inTimePeriod - 1
-	}
-	startIdx := lookbackTotal
-	outIdx := startIdx
-	today := startIdx
-	prevHigh := 0.0
-	prevLow := 0.0
-	if inTimePeriod <= 1 {
-		today = startIdx - 1
-		prevHigh = inHigh[today]
-		prevLow = inLow[today]
-		for today < len(inHigh)-1 {
-			today++
-			tempReal := inHigh[today]
-			diffP := tempReal - prevHigh
-			prevHigh = tempReal
-			tempReal = inLow[today]
-			diffM := prevLow - tempReal
-			prevLow = tempReal
-			if (diffM > 0) && (diffP < diffM) {
-				outReal[outIdx] = diffM
-			} else {
-				outReal[outIdx] = 0
-			}
-			outIdx++
-		}
-		return outReal
-	}
-	prevMinusDM := 0.0
-	today = startIdx - lookbackTotal
-	prevHigh = inHigh[today]
-	prevLow = inLow[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
-		}
-	}
-	i = 0
-	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 = prevMinusDM - (prevMinusDM / float64(inTimePeriod)) + diffM
-		} else {
-			prevMinusDM = prevMinusDM - (prevMinusDM / float64(inTimePeriod))
-		}
-	}
-	outReal[startIdx] = prevMinusDM
-	outIdx = startIdx + 1
-	for today < len(inHigh)-1 {
-		today++
-		tempReal := inHigh[today]
-		diffP := tempReal - prevHigh
-		prevHigh = tempReal
-		tempReal = inLow[today]
-		diffM := prevLow - tempReal
-		prevLow = tempReal
-		if (diffM > 0) && (diffP < diffM) {
-			prevMinusDM = prevMinusDM - (prevMinusDM / float64(inTimePeriod)) + diffM
-		} else {
-			prevMinusDM = prevMinusDM - (prevMinusDM / float64(inTimePeriod))
-		}
-		outReal[outIdx] = prevMinusDM
-		outIdx++
-	}
-	return outReal
-}
-
-// Mfi - Money Flow Index
-func Mfi(inHigh []float64, inLow []float64, inClose []float64, inVolume []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inClose))
-	mflowIdx := 0
-	maxIdxMflow := (50 - 1)
-	mflow := make([]moneyFlow, inTimePeriod)
-	maxIdxMflow = inTimePeriod - 1
-	lookbackTotal := inTimePeriod
-	startIdx := lookbackTotal
-	outIdx := startIdx
-	today := startIdx - lookbackTotal
-	prevValue := (inHigh[today] + inLow[today] + inClose[today]) / 3.0
-	posSumMF := 0.0
-	negSumMF := 0.0
-	today++
-	for i := inTimePeriod; i > 0; i-- {
-		tempValue1 := (inHigh[today] + inLow[today] + inClose[today]) / 3.0
-		tempValue2 := tempValue1 - prevValue
-		prevValue = tempValue1
-		tempValue1 *= inVolume[today]
-		today++
-		if tempValue2 < 0 {
-			(mflow[mflowIdx]).negative = tempValue1
-			negSumMF += tempValue1
-			(mflow[mflowIdx]).positive = 0.0
-		} else if tempValue2 > 0 {
-			(mflow[mflowIdx]).positive = tempValue1
-			posSumMF += tempValue1
-			(mflow[mflowIdx]).negative = 0.0
-		} else {
-			(mflow[mflowIdx]).positive = 0.0
-			(mflow[mflowIdx]).negative = 0.0
-		}
-		mflowIdx++
-		if mflowIdx > maxIdxMflow {
-			mflowIdx = 0
-		}
-
-	}
-	if today > startIdx {
-		tempValue1 := posSumMF + negSumMF
-		if tempValue1 < 1.0 {
-		} else {
-			outReal[outIdx] = 100.0 * (posSumMF / tempValue1)
-			outIdx++
-		}
-	} else {
-		for today < startIdx {
-			posSumMF -= mflow[mflowIdx].positive
-			negSumMF -= mflow[mflowIdx].negative
-			tempValue1 := (inHigh[today] + inLow[today] + inClose[today]) / 3.0
-			tempValue2 := tempValue1 - prevValue
-			prevValue = tempValue1
-			tempValue1 *= inVolume[today]
-			today++
-			if tempValue2 < 0 {
-				(mflow[mflowIdx]).negative = tempValue1
-				negSumMF += tempValue1
-				(mflow[mflowIdx]).positive = 0.0
-			} else if tempValue2 > 0 {
-				(mflow[mflowIdx]).positive = tempValue1
-				posSumMF += tempValue1
-				(mflow[mflowIdx]).negative = 0.0
-			} else {
-				(mflow[mflowIdx]).positive = 0.0
-				(mflow[mflowIdx]).negative = 0.0
-			}
-			mflowIdx++
-			if mflowIdx > maxIdxMflow {
-				mflowIdx = 0
-			}
-
-		}
-	}
-	for today < len(inClose) {
-		posSumMF -= (mflow[mflowIdx]).positive
-		negSumMF -= (mflow[mflowIdx]).negative
-		tempValue1 := (inHigh[today] + inLow[today] + inClose[today]) / 3.0
-		tempValue2 := tempValue1 - prevValue
-		prevValue = tempValue1
-		tempValue1 *= inVolume[today]
-		today++
-		if tempValue2 < 0 {
-			(mflow[mflowIdx]).negative = tempValue1
-			negSumMF += tempValue1
-			(mflow[mflowIdx]).positive = 0.0
-		} else if tempValue2 > 0 {
-			(mflow[mflowIdx]).positive = tempValue1
-			posSumMF += tempValue1
-			(mflow[mflowIdx]).negative = 0.0
-		} else {
-			(mflow[mflowIdx]).positive = 0.0
-			(mflow[mflowIdx]).negative = 0.0
-		}
-		tempValue1 = posSumMF + negSumMF
-		if tempValue1 < 1.0 {
-			outReal[outIdx] = 0.0
-		} else {
-			outReal[outIdx] = 100.0 * (posSumMF / tempValue1)
-		}
-		outIdx++
-		mflowIdx++
-		if mflowIdx > maxIdxMflow {
-			mflowIdx = 0
-		}
-	}
-	return outReal
-}
-
-// Mom - Momentum
-func Mom(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	inIdx, outIdx, trailingIdx := inTimePeriod, inTimePeriod, 0
-	for inIdx < len(inReal) {
-		outReal[outIdx] = inReal[inIdx] - inReal[trailingIdx]
-		inIdx, outIdx, trailingIdx = inIdx+1, outIdx+1, trailingIdx+1
-	}
-
-	return outReal
-}
-
-// PlusDI - Plus Directional Indicator
-func PlusDI(inHigh []float64, inLow []float64, inClose []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inClose))
-
-	lookbackTotal := 1
-	if inTimePeriod > 1 {
-		lookbackTotal = inTimePeriod
-	}
-	startIdx := lookbackTotal
-	outIdx := startIdx
-
-	prevHigh := 0.0
-	prevLow := 0.0
-	prevClose := 0.0
-	if inTimePeriod <= 1 {
-		today := startIdx - 1
-		prevHigh = inHigh[today]
-		prevLow = inLow[today]
-		prevClose = inClose[today]
-		for today < len(inClose)-1 {
-			today++
-			tempReal := inHigh[today]
-			diffP := tempReal - prevHigh
-			prevHigh = tempReal
-			tempReal = inLow[today]
-			diffM := prevLow - tempReal
-			prevLow = tempReal
-			if (diffP > 0) && (diffP > diffM) {
-
-				tempReal = prevHigh - prevLow
-				tempReal2 := math.Abs(prevHigh - prevClose)
-				if tempReal2 > tempReal {
-					tempReal = tempReal2
-				}
-				tempReal2 = math.Abs(prevLow - prevClose)
-				if tempReal2 > tempReal {
-					tempReal = tempReal2
-				}
-
-				if ((-(0.00000000000001)) < tempReal) && (tempReal < (0.00000000000001)) {
-					outReal[outIdx] = 0.0
-				} else {
-					outReal[outIdx] = diffP / tempReal
-				}
-				outIdx++
-			} else {
-				outReal[outIdx] = 0.0
-				outIdx++
-			}
-			prevClose = inClose[today]
-		}
-		return outReal
-	}
-	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 (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]
-	}
-	i = 1
-	for i != 0 {
-		i--
-		today++
-		tempReal := inHigh[today]
-		diffP := tempReal - prevHigh
-		prevHigh = tempReal
-		tempReal = inLow[today]
-		diffM := prevLow - tempReal
-		prevLow = tempReal
-		if (diffP > 0) && (diffP > diffM) {
-			prevPlusDM = prevPlusDM - (prevPlusDM / float64(inTimePeriod)) + diffP
-		} else {
-			prevPlusDM = prevPlusDM - (prevPlusDM / float64(inTimePeriod))
-		}
-		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))) {
-		outReal[startIdx] = (100.0 * (prevPlusDM / prevTR))
-	} else {
-		outReal[startIdx] = 0.0
-	}
-	outIdx = startIdx + 1
-	for today < len(inClose)-1 {
-		today++
-		tempReal := inHigh[today]
-		diffP := tempReal - prevHigh
-		prevHigh = tempReal
-		tempReal = inLow[today]
-		diffM := prevLow - tempReal
-		prevLow = tempReal
-		if (diffP > 0) && (diffP > diffM) {
-			prevPlusDM = prevPlusDM - (prevPlusDM / float64(inTimePeriod)) + diffP
-		} else {
-			prevPlusDM = prevPlusDM - (prevPlusDM / float64(inTimePeriod))
-		}
-		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))) {
-			outReal[outIdx] = (100.0 * (prevPlusDM / prevTR))
-		} else {
-			outReal[outIdx] = 0.0
-		}
-		outIdx++
-	}
-
-	return outReal
-}
-
-// PlusDM - Plus Directional Movement
-func PlusDM(inHigh []float64, inLow []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inHigh))
-
-	lookbackTotal := 1
-	if inTimePeriod > 1 {
-		lookbackTotal = inTimePeriod - 1
-	}
-	startIdx := lookbackTotal
-	outIdx := startIdx
-	today := startIdx
-	prevHigh := 0.0
-	prevLow := 0.0
-	if inTimePeriod <= 1 {
-		today = startIdx - 1
-		prevHigh = inHigh[today]
-		prevLow = inLow[today]
-		for today < len(inHigh)-1 {
-			today++
-			tempReal := inHigh[today]
-			diffP := tempReal - prevHigh
-			prevHigh = tempReal
-			tempReal = inLow[today]
-			diffM := prevLow - tempReal
-			prevLow = tempReal
-			if (diffP > 0) && (diffP > diffM) {
-				outReal[outIdx] = diffP
-			} else {
-				outReal[outIdx] = 0
-			}
-			outIdx++
-		}
-		return outReal
-	}
-	prevPlusDM := 0.0
-	today = startIdx - lookbackTotal
-	prevHigh = inHigh[today]
-	prevLow = inLow[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 (diffP > 0) && (diffP > diffM) {
-			prevPlusDM += diffP
-		}
-	}
-	i = 0
-	for i != 0 {
-		i--
-		today++
-		tempReal := inHigh[today]
-		diffP := tempReal - prevHigh
-		prevHigh = tempReal
-		tempReal = inLow[today]
-		diffM := prevLow - tempReal
-		prevLow = tempReal
-		if (diffP > 0) && (diffP > diffM) {
-			prevPlusDM = prevPlusDM - (prevPlusDM / float64(inTimePeriod)) + diffP
-		} else {
-			prevPlusDM = prevPlusDM - (prevPlusDM / float64(inTimePeriod))
-		}
-	}
-	outReal[startIdx] = prevPlusDM
-	outIdx = startIdx + 1
-	for today < len(inHigh)-1 {
-		today++
-		tempReal := inHigh[today]
-		diffP := tempReal - prevHigh
-		prevHigh = tempReal
-		tempReal = inLow[today]
-		diffM := prevLow - tempReal
-		prevLow = tempReal
-		if (diffP > 0) && (diffP > diffM) {
-			prevPlusDM = prevPlusDM - (prevPlusDM / float64(inTimePeriod)) + diffP
-		} else {
-			prevPlusDM = prevPlusDM - (prevPlusDM / float64(inTimePeriod))
-		}
-		outReal[outIdx] = prevPlusDM
-		outIdx++
-	}
-	return outReal
-}
-
-// Ppo - Percentage Price Oscillator
-func Ppo(inReal []float64, inFastPeriod int, inSlowPeriod int, inMAType MaType) []float64 {
-
-	if inSlowPeriod < inFastPeriod {
-		inSlowPeriod, inFastPeriod = inFastPeriod, inSlowPeriod
-	}
-	tempBuffer := Ma(inReal, inFastPeriod, inMAType)
-	outReal := Ma(inReal, inSlowPeriod, inMAType)
-
-	for i := inSlowPeriod - 1; i < len(inReal); i++ {
-		tempReal := outReal[i]
-		if !(((-(0.00000000000001)) < tempReal) && (tempReal < (0.00000000000001))) {
-			outReal[i] = ((tempBuffer[i] - tempReal) / tempReal) * 100.0
-		} else {
-			outReal[i] = 0.0
-		}
-	}
-
-	return outReal
-}
-
-// Rocp - Rate of change Percentage: (price-prevPrice)/prevPrice
-func Rocp(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	if inTimePeriod < 1 {
-		return outReal
-	}
-
-	startIdx := inTimePeriod
-	outIdx := startIdx
-	inIdx := startIdx
-	trailingIdx := startIdx - inTimePeriod
-	for inIdx < len(outReal) {
-		tempReal := inReal[trailingIdx]
-		if tempReal != 0.0 {
-			outReal[outIdx] = (inReal[inIdx] - tempReal) / tempReal
-		} else {
-			outReal[outIdx] = 0.0
-		}
-		trailingIdx++
-		outIdx++
-		inIdx++
-	}
-
-	return outReal
-}
-
-// Roc - Rate of change : ((price/prevPrice)-1)*100
-func Roc(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	startIdx := inTimePeriod
-	outIdx := inTimePeriod
-	inIdx := startIdx
-	trailingIdx := startIdx - inTimePeriod
-
-	for inIdx < len(inReal) {
-		tempReal := inReal[trailingIdx]
-		if tempReal != 0.0 {
-			outReal[outIdx] = ((inReal[inIdx] / tempReal) - 1.0) * 100.0
-		} else {
-			outReal[outIdx] = 0.0
-		}
-		trailingIdx++
-		outIdx++
-		inIdx++
-	}
-	return outReal
-}
-
-// Rocr - Rate of change ratio: (price/prevPrice)
-func Rocr(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	startIdx := inTimePeriod
-	outIdx := inTimePeriod
-	inIdx := startIdx
-	trailingIdx := startIdx - inTimePeriod
-
-	for inIdx < len(inReal) {
-		tempReal := inReal[trailingIdx]
-		if tempReal != 0.0 {
-			outReal[outIdx] = (inReal[inIdx] / tempReal)
-		} else {
-			outReal[outIdx] = 0.0
-		}
-		trailingIdx++
-		outIdx++
-		inIdx++
-	}
-	return outReal
-}
-
-// Rocr100 - Rate of change ratio 100 scale: (price/prevPrice)*100
-func Rocr100(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	startIdx := inTimePeriod
-	outIdx := inTimePeriod
-	inIdx := startIdx
-	trailingIdx := startIdx - inTimePeriod
-
-	for inIdx < len(inReal) {
-		tempReal := inReal[trailingIdx]
-		if tempReal != 0.0 {
-			outReal[outIdx] = (inReal[inIdx] / tempReal) * 100.0
-		} else {
-			outReal[outIdx] = 0.0
-		}
-		trailingIdx++
-		outIdx++
-		inIdx++
-	}
-	return outReal
-}
-
-// Rsi - Relative strength index
-func Rsi(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	if inTimePeriod < 2 {
-		return outReal
-	}
-
-	// variable declarations
-	tempValue1 := 0.0
-	tempValue2 := 0.0
-	outIdx := inTimePeriod
-	today := 0
-	prevValue := inReal[today]
-	prevGain := 0.0
-	prevLoss := 0.0
-	today++
-
-	for i := inTimePeriod; i > 0; i-- {
-		tempValue1 = inReal[today]
-		today++
-		tempValue2 = tempValue1 - prevValue
-		prevValue = tempValue1
-		if tempValue2 < 0 {
-			prevLoss -= tempValue2
-		} else {
-			prevGain += tempValue2
-		}
-	}
-
-	prevLoss /= float64(inTimePeriod)
-	prevGain /= float64(inTimePeriod)
-
-	if today > 0 {
-
-		tempValue1 = prevGain + prevLoss
-		if !((-0.00000000000001 < tempValue1) && (tempValue1 < 0.00000000000001)) {
-			outReal[outIdx] = 100.0 * (prevGain / tempValue1)
-		} else {
-			outReal[outIdx] = 0.0
-		}
-		outIdx++
-
-	} else {
-
-		for today < 0 {
-			tempValue1 = inReal[today]
-			tempValue2 = tempValue1 - prevValue
-			prevValue = tempValue1
-			prevLoss *= float64(inTimePeriod - 1)
-			prevGain *= float64(inTimePeriod - 1)
-			if tempValue2 < 0 {
-				prevLoss -= tempValue2
-			} else {
-				prevGain += tempValue2
-			}
-			prevLoss /= float64(inTimePeriod)
-			prevGain /= float64(inTimePeriod)
-			today++
-		}
-	}
-
-	for today < len(inReal) {
-
-		tempValue1 = inReal[today]
-		today++
-		tempValue2 = tempValue1 - prevValue
-		prevValue = tempValue1
-		prevLoss *= float64(inTimePeriod - 1)
-		prevGain *= float64(inTimePeriod - 1)
-		if tempValue2 < 0 {
-			prevLoss -= tempValue2
-		} else {
-			prevGain += tempValue2
-		}
-		prevLoss /= float64(inTimePeriod)
-		prevGain /= float64(inTimePeriod)
-		tempValue1 = prevGain + prevLoss
-		if !((-0.00000000000001 < tempValue1) && (tempValue1 < 0.00000000000001)) {
-			outReal[outIdx] = 100.0 * (prevGain / tempValue1)
-		} else {
-			outReal[outIdx] = 0.0
-		}
-		outIdx++
-	}
-
-	return outReal
-}
-
-// Stoch - Stochastic
-func Stoch(inHigh []float64, inLow []float64, inClose []float64, inFastKPeriod int, inSlowKPeriod int, inSlowKMAType MaType, inSlowDPeriod int, inSlowDMAType MaType) ([]float64, []float64) {
-
-	outSlowK := make([]float64, len(inClose))
-	outSlowD := make([]float64, len(inClose))
-
-	lookbackK := inFastKPeriod - 1
-	lookbackKSlow := inSlowKPeriod - 1
-	lookbackDSlow := inSlowDPeriod - 1
-	lookbackTotal := lookbackK + lookbackDSlow + lookbackKSlow
-	startIdx := lookbackTotal
-	outIdx := 0
-	trailingIdx := startIdx - lookbackTotal
-	today := trailingIdx + lookbackK
-	lowestIdx, highestIdx := -1, -1
-	diff, highest, lowest := 0.0, 0.0, 0.0
-	tempBuffer := make([]float64, len(inClose)-today+1)
-	for today < len(inClose) {
-		tmp := inLow[today]
-		if lowestIdx < trailingIdx {
-			lowestIdx = trailingIdx
-			lowest = inLow[lowestIdx]
-			i := lowestIdx + 1
-			for i <= today {
-
-				tmp := inLow[i]
-				if tmp < lowest {
-					lowestIdx = i
-					lowest = tmp
-				}
-				i++
-			}
-			diff = (highest - lowest) / 100.0
-		} else if tmp <= lowest {
-			lowestIdx = today
-			lowest = tmp
-			diff = (highest - lowest) / 100.0
-		}
-		tmp = inHigh[today]
-		if highestIdx < trailingIdx {
-			highestIdx = trailingIdx
-			highest = inHigh[highestIdx]
-			i := highestIdx + 1
-			for i <= today {
-				tmp := inHigh[i]
-				if tmp > highest {
-					highestIdx = i
-					highest = tmp
-				}
-				i++
-			}
-			diff = (highest - lowest) / 100.0
-		} else if tmp >= highest {
-			highestIdx = today
-			highest = tmp
-			diff = (highest - lowest) / 100.0
-		}
-		if diff != 0.0 {
-			tempBuffer[outIdx] = (inClose[today] - lowest) / diff
-		} else {
-			tempBuffer[outIdx] = 0.0
-		}
-		outIdx++
-		trailingIdx++
-		today++
-	}
-
-	tempBuffer1 := Ma(tempBuffer, inSlowKPeriod, inSlowKMAType)
-	tempBuffer2 := Ma(tempBuffer1, inSlowDPeriod, inSlowDMAType)
-	//for i, j := lookbackK, lookbackTotal; j < len(inClose); i, j = i+1, j+1 {
-	for i, j := lookbackDSlow+lookbackKSlow, lookbackTotal; j < len(inClose); i, j = i+1, j+1 {
-		outSlowK[j] = tempBuffer1[i]
-		outSlowD[j] = tempBuffer2[i]
-	}
-
-	return outSlowK, outSlowD
-}
-
-// StochF - Stochastic Fast
-func StochF(inHigh []float64, inLow []float64, inClose []float64, inFastKPeriod int, inFastDPeriod int, inFastDMAType MaType) ([]float64, []float64) {
-
-	outFastK := make([]float64, len(inClose))
-	outFastD := make([]float64, len(inClose))
-
-	lookbackK := inFastKPeriod - 1
-	lookbackFastD := inFastDPeriod - 1
-	lookbackTotal := lookbackK + lookbackFastD
-	startIdx := lookbackTotal
-	outIdx := 0
-	trailingIdx := startIdx - lookbackTotal
-	today := trailingIdx + lookbackK
-	lowestIdx, highestIdx := -1, -1
-	diff, highest, lowest := 0.0, 0.0, 0.0
-	tempBuffer := make([]float64, (len(inClose) - today + 1))
-
-	for today < len(inClose) {
-		tmp := inLow[today]
-		if lowestIdx < trailingIdx {
-			lowestIdx = trailingIdx
-			lowest = inLow[lowestIdx]
-			i := lowestIdx
-			i++
-			for i <= today {
-				tmp = inLow[i]
-				if tmp < lowest {
-					lowestIdx = i
-					lowest = tmp
-				}
-				i++
-			}
-			diff = (highest - lowest) / 100.0
-		} else if tmp <= lowest {
-			lowestIdx = today
-			lowest = tmp
-			diff = (highest - lowest) / 100.0
-		}
-		tmp = inHigh[today]
-		if highestIdx < trailingIdx {
-			highestIdx = trailingIdx
-			highest = inHigh[highestIdx]
-			i := highestIdx
-			i++
-			for i <= today {
-				tmp = inHigh[i]
-				if tmp > highest {
-					highestIdx = i
-					highest = tmp
-				}
-				i++
-			}
-			diff = (highest - lowest) / 100.0
-		} else if tmp >= highest {
-			highestIdx = today
-			highest = tmp
-			diff = (highest - lowest) / 100.0
-		}
-		if diff != 0.0 {
-			tempBuffer[outIdx] = (inClose[today] - lowest) / diff
-
-		} else {
-			tempBuffer[outIdx] = 0.0
-		}
-		outIdx++
-		trailingIdx++
-		today++
-	}
-
-	tempBuffer1 := Ma(tempBuffer, inFastDPeriod, inFastDMAType)
-	for i, j := lookbackFastD, lookbackTotal; j < len(inClose); i, j = i+1, j+1 {
-		outFastK[j] = tempBuffer[i]
-		outFastD[j] = tempBuffer1[i]
-	}
-
-	return outFastK, outFastD
-}
-
-// StochRsi - Stochastic Relative Strength Index
-func StochRsi(inReal []float64, inTimePeriod int, inFastKPeriod int, inFastDPeriod int, inFastDMAType MaType) ([]float64, []float64) {
-
-	outFastK := make([]float64, len(inReal))
-	outFastD := make([]float64, len(inReal))
-
-	lookbackSTOCHF := (inFastKPeriod - 1) + (inFastDPeriod - 1)
-	lookbackTotal := inTimePeriod + lookbackSTOCHF
-	startIdx := lookbackTotal
-	tempRSIBuffer := Rsi(inReal, inTimePeriod)
-	tempk, tempd := StochF(tempRSIBuffer, tempRSIBuffer, tempRSIBuffer, inFastKPeriod, inFastDPeriod, inFastDMAType)
-
-	for i := startIdx; i < len(inReal); i++ {
-		outFastK[i] = tempk[i]
-		outFastD[i] = tempd[i]
-	}
-
-	return outFastK, outFastD
-}
-
-// Trix - 1-day Rate-Of-Change (ROC) of a Triple Smooth EMA
-func Trix(inReal []float64, inTimePeriod int) []float64 {
-
-	tmpReal := Ema(inReal, inTimePeriod)
-	tmpReal = Ema(tmpReal[inTimePeriod-1:], inTimePeriod)
-	tmpReal = Ema(tmpReal[inTimePeriod-1:], inTimePeriod)
-	tmpReal = Roc(tmpReal, 1)
-
-	outReal := make([]float64, len(inReal))
-	for i, j := inTimePeriod, ((inTimePeriod-1)*3)+1; j < len(outReal); i, j = i+1, j+1 {
-		outReal[j] = tmpReal[i]
-	}
-
-	return outReal
-}
-
-// UltOsc - Ultimate Oscillator
-func UltOsc(inHigh []float64, inLow []float64, inClose []float64, inTimePeriod1 int, inTimePeriod2 int, inTimePeriod3 int) []float64 {
-
-	outReal := make([]float64, len(inClose))
-
-	usedFlag := make([]int, 3)
-	periods := make([]int, 3)
-	sortedPeriods := make([]int, 3)
-
-	periods[0] = inTimePeriod1
-	periods[1] = inTimePeriod2
-	periods[2] = inTimePeriod3
-
-	for i := 0; i < 3; i++ {
-		longestPeriod := 0
-		longestIndex := 0
-		for j := 0; j < 3; j++ {
-			if (usedFlag[j] == 0) && (periods[j] > longestPeriod) {
-				longestPeriod = periods[j]
-				longestIndex = j
-			}
-		}
-		usedFlag[longestIndex] = 1
-		sortedPeriods[i] = longestPeriod
-	}
-	inTimePeriod1 = sortedPeriods[2]
-	inTimePeriod2 = sortedPeriods[1]
-	inTimePeriod3 = sortedPeriods[0]
-
-	lookbackTotal := 0
-	if inTimePeriod1 > inTimePeriod2 {
-		lookbackTotal = inTimePeriod1
-	}
-	if inTimePeriod3 > lookbackTotal {
-		lookbackTotal = inTimePeriod3
-	}
-	lookbackTotal++
-
-	startIdx := lookbackTotal - 1
-
-	a1Total := 0.0
-	b1Total := 0.0
-	for i := startIdx - inTimePeriod1 + 1; i < startIdx; i++ {
-
-		tempLT := inLow[i]
-		tempHT := inHigh[i]
-		tempCY := inClose[i-1]
-		trueLow := 0.0
-		if tempLT < tempCY {
-			trueLow = tempLT
-		} else {
-			trueLow = tempCY
-		}
-		closeMinusTrueLow := inClose[i] - trueLow
-		trueRange := tempHT - tempLT
-		tempDouble := math.Abs(tempCY - tempHT)
-		if tempDouble > trueRange {
-			trueRange = tempDouble
-		}
-		tempDouble = math.Abs(tempCY - tempLT)
-		if tempDouble > trueRange {
-			trueRange = tempDouble
-		}
-
-		a1Total += closeMinusTrueLow
-		b1Total += trueRange
-	}
-
-	a2Total := 0.0
-	b2Total := 0.0
-	for i := startIdx - inTimePeriod2 + 1; i < startIdx; i++ {
-
-		tempLT := inLow[i]
-		tempHT := inHigh[i]
-		tempCY := inClose[i-1]
-		trueLow := 0.0
-		if tempLT < tempCY {
-			trueLow = tempLT
-		} else {
-			trueLow = tempCY
-		}
-		closeMinusTrueLow := inClose[i] - trueLow
-		trueRange := tempHT - tempLT
-		tempDouble := math.Abs(tempCY - tempHT)
-		if tempDouble > trueRange {
-			trueRange = tempDouble
-		}
-		tempDouble = math.Abs(tempCY - tempLT)
-		if tempDouble > trueRange {
-			trueRange = tempDouble
-		}
-
-		a2Total += closeMinusTrueLow
-		b2Total += trueRange
-	}
-
-	a3Total := 0.0
-	b3Total := 0.0
-	for i := startIdx - inTimePeriod3 + 1; i < startIdx; i++ {
-
-		tempLT := inLow[i]
-		tempHT := inHigh[i]
-		tempCY := inClose[i-1]
-		trueLow := 0.0
-		if tempLT < tempCY {
-			trueLow = tempLT
-		} else {
-			trueLow = tempCY
-		}
-		closeMinusTrueLow := inClose[i] - trueLow
-		trueRange := tempHT - tempLT
-		tempDouble := math.Abs(tempCY - tempHT)
-		if tempDouble > trueRange {
-			trueRange = tempDouble
-		}
-		tempDouble = math.Abs(tempCY - tempLT)
-		if tempDouble > trueRange {
-			trueRange = tempDouble
-		}
-
-		a3Total += closeMinusTrueLow
-		b3Total += trueRange
-	}
-
-	//today := startIdx
-	//outIdx := startIdx
-	//trailingIdx1 := today - inTimePeriod1 + 1
-	//trailingIdx2 := today - inTimePeriod2 + 1
-	//trailingIdx3 := today - inTimePeriod3 + 1
-
-	today := startIdx
-	outIdx := startIdx
-	trailingIdx1 := today - inTimePeriod1 + 1
-	trailingIdx2 := today - inTimePeriod2 + 1
-	trailingIdx3 := today - inTimePeriod3 + 1
-
-	for today < len(inClose) {
-
-		tempLT := inLow[today]
-		tempHT := inHigh[today]
-		tempCY := inClose[today-1]
-		trueLow := 0.0
-		if tempLT < tempCY {
-			trueLow = tempLT
-		} else {
-			trueLow = tempCY
-		}
-		closeMinusTrueLow := inClose[today] - trueLow
-		trueRange := tempHT - tempLT
-		tempDouble := math.Abs(tempCY - tempHT)
-		if tempDouble > trueRange {
-			trueRange = tempDouble
-		}
-		tempDouble = math.Abs(tempCY - tempLT)
-		if tempDouble > trueRange {
-			trueRange = tempDouble
-		}
-
-		a1Total += closeMinusTrueLow
-		a2Total += closeMinusTrueLow
-		a3Total += closeMinusTrueLow
-		b1Total += trueRange
-		b2Total += trueRange
-		b3Total += trueRange
-		output := 0.0
-		if !(((-(0.00000000000001)) < b1Total) && (b1Total < (0.00000000000001))) {
-			output += 4.0 * (a1Total / b1Total)
-		}
-		if !(((-(0.00000000000001)) < b2Total) && (b2Total < (0.00000000000001))) {
-			output += 2.0 * (a2Total / b2Total)
-		}
-		if !(((-(0.00000000000001)) < b3Total) && (b3Total < (0.00000000000001))) {
-			output += a3Total / b3Total
-		}
-		tempLT = inLow[trailingIdx1]
-		tempHT = inHigh[trailingIdx1]
-		tempCY = inClose[trailingIdx1-1]
-		trueLow = 0.0
-		if tempLT < tempCY {
-			trueLow = tempLT
-		} else {
-			trueLow = tempCY
-		}
-		closeMinusTrueLow = inClose[trailingIdx1] - trueLow
-		trueRange = tempHT - tempLT
-		tempDouble = math.Abs(tempCY - tempHT)
-		if tempDouble > trueRange {
-			trueRange = tempDouble
-		}
-		tempDouble = math.Abs(tempCY - tempLT)
-		if tempDouble > trueRange {
-			trueRange = tempDouble
-		}
-
-		a1Total -= closeMinusTrueLow
-		b1Total -= trueRange
-		tempLT = inLow[trailingIdx2]
-		tempHT = inHigh[trailingIdx2]
-		tempCY = inClose[trailingIdx2-1]
-		trueLow = 0.0
-		if tempLT < tempCY {
-			trueLow = tempLT
-		} else {
-			trueLow = tempCY
-		}
-		closeMinusTrueLow = inClose[trailingIdx2] - trueLow
-		trueRange = tempHT - tempLT
-		tempDouble = math.Abs(tempCY - tempHT)
-		if tempDouble > trueRange {
-			trueRange = tempDouble
-		}
-		tempDouble = math.Abs(tempCY - tempLT)
-		if tempDouble > trueRange {
-			trueRange = tempDouble
-		}
-
-		a2Total -= closeMinusTrueLow
-		b2Total -= trueRange
-		tempLT = inLow[trailingIdx3]
-		tempHT = inHigh[trailingIdx3]
-		tempCY = inClose[trailingIdx3-1]
-		trueLow = 0.0
-		if tempLT < tempCY {
-			trueLow = tempLT
-		} else {
-			trueLow = tempCY
-		}
-		closeMinusTrueLow = inClose[trailingIdx3] - trueLow
-		trueRange = tempHT - tempLT
-		tempDouble = math.Abs(tempCY - tempHT)
-		if tempDouble > trueRange {
-			trueRange = tempDouble
-		}
-		tempDouble = math.Abs(tempCY - tempLT)
-		if tempDouble > trueRange {
-			trueRange = tempDouble
-		}
-
-		a3Total -= closeMinusTrueLow
-		b3Total -= trueRange
-		outReal[outIdx] = 100.0 * (output / 7.0)
-		outIdx++
-		today++
-		trailingIdx1++
-		trailingIdx2++
-		trailingIdx3++
-	}
-	return outReal
-}
-
-// WillR - Williams' %R
-func WillR(inHigh []float64, inLow []float64, inClose []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inClose))
-	nbInitialElementNeeded := (inTimePeriod - 1)
-	diff := 0.0
-	outIdx := inTimePeriod - 1
-	startIdx := inTimePeriod - 1
-	today := startIdx
-	trailingIdx := startIdx - nbInitialElementNeeded
-	highestIdx := -1
-	lowestIdx := -1
-	highest := 0.0
-	lowest := 0.0
-	i := 0
-	for today < len(inClose) {
-		tmp := inLow[today]
-		if lowestIdx < trailingIdx {
-			lowestIdx = trailingIdx
-			lowest = inLow[lowestIdx]
-			i = lowestIdx
-			i++
-			for i <= today {
-				tmp = inLow[i]
-				if tmp < lowest {
-					lowestIdx = i
-					lowest = tmp
-				}
-				i++
-			}
-			diff = (highest - lowest) / (-100.0)
-		} else if tmp <= lowest {
-			lowestIdx = today
-			lowest = tmp
-			diff = (highest - lowest) / (-100.0)
-		}
-		tmp = inHigh[today]
-		if highestIdx < trailingIdx {
-			highestIdx = trailingIdx
-			highest = inHigh[highestIdx]
-			i = highestIdx
-			i++
-			for i <= today {
-				tmp = inHigh[i]
-				if tmp > highest {
-					highestIdx = i
-					highest = tmp
-				}
-				i++
-			}
-			diff = (highest - lowest) / (-100.0)
-		} else if tmp >= highest {
-			highestIdx = today
-			highest = tmp
-			diff = (highest - lowest) / (-100.0)
-		}
-		if diff != 0.0 {
-			outReal[outIdx] = (highest - inClose[today]) / diff
-		} else {
-			outReal[outIdx] = 0.0
-		}
-		outIdx++
-		trailingIdx++
-		today++
-	}
-	return outReal
-}
-
-/* Volume Indicators */
-
-// Ad - Chaikin A/D Line
-func Ad(inHigh []float64, inLow []float64, inClose []float64, inVolume []float64) []float64 {
-
-	outReal := make([]float64, len(inClose))
-
-	startIdx := 0
-	nbBar := len(inClose) - startIdx
-	currentBar := startIdx
-	outIdx := 0
-	ad := 0.0
-	for nbBar != 0 {
-		high := inHigh[currentBar]
-		low := inLow[currentBar]
-		tmp := high - low
-		close := inClose[currentBar]
-		if tmp > 0.0 {
-			ad += (((close - low) - (high - close)) / tmp) * (inVolume[currentBar])
-		}
-		outReal[outIdx] = ad
-		outIdx++
-		currentBar++
-		nbBar--
-	}
-	return outReal
-}
-
-// AdOsc - Chaikin A/D Oscillator
-func AdOsc(inHigh []float64, inLow []float64, inClose []float64, inVolume []float64, inFastPeriod int, inSlowPeriod int) []float64 {
-
-	outReal := make([]float64, len(inClose))
-
-	if (inFastPeriod < 2) || (inSlowPeriod < 2) {
-		return outReal
-	}
-
-	slowestPeriod := 0
-	if inFastPeriod < inSlowPeriod {
-		slowestPeriod = inSlowPeriod
-	} else {
-		slowestPeriod = inFastPeriod
-	}
-	lookbackTotal := slowestPeriod - 1
-	startIdx := lookbackTotal
-	today := startIdx - lookbackTotal
-	ad := 0.0
-	fastk := (2.0 / (float64(inFastPeriod) + 1.0))
-	oneMinusfastk := 1.0 - fastk
-	slowk := (2.0 / (float64(inSlowPeriod) + 1.0))
-	oneMinusslowk := 1.0 - slowk
-	high := inHigh[today]
-	low := inLow[today]
-	tmp := high - low
-	close := inClose[today]
-	if tmp > 0.0 {
-		ad += (((close - low) - (high - close)) / tmp) * (inVolume[today])
-	}
-	today++
-	fastEMA := ad
-	slowEMA := ad
-
-	for today < startIdx {
-		high = inHigh[today]
-		low = inLow[today]
-		tmp = high - low
-		close = inClose[today]
-		if tmp > 0.0 {
-			ad += (((close - low) - (high - close)) / tmp) * (inVolume[today])
-		}
-		today++
-
-		fastEMA = (fastk * ad) + (oneMinusfastk * fastEMA)
-		slowEMA = (slowk * ad) + (oneMinusslowk * slowEMA)
-	}
-	outIdx := lookbackTotal
-	for today < len(inClose) {
-		high = inHigh[today]
-		low = inLow[today]
-		tmp = high - low
-		close = inClose[today]
-		if tmp > 0.0 {
-			ad += (((close - low) - (high - close)) / tmp) * (inVolume[today])
-		}
-		today++
-		fastEMA = (fastk * ad) + (oneMinusfastk * fastEMA)
-		slowEMA = (slowk * ad) + (oneMinusslowk * slowEMA)
-		outReal[outIdx] = fastEMA - slowEMA
-		outIdx++
-	}
-
-	return outReal
-}
-
-// Obv - On Balance Volume
-func Obv(inReal []float64, inVolume []float64) []float64 {
-
-	outReal := make([]float64, len(inReal))
-	startIdx := 0
-	prevOBV := inVolume[startIdx]
-	prevReal := inReal[startIdx]
-	outIdx := 0
-	for i := startIdx; i < len(inReal); i++ {
-		tempReal := inReal[i]
-		if tempReal > prevReal {
-			prevOBV += inVolume[i]
-		} else if tempReal < prevReal {
-			prevOBV -= inVolume[i]
-		}
-		outReal[outIdx] = prevOBV
-		prevReal = tempReal
-		outIdx++
-	}
-	return outReal
-}
-
-/* Volatility Indicators */
-
-// Atr - Average True Range
-func Atr(inHigh []float64, inLow []float64, inClose []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inClose))
-
-	inTimePeriodF := float64(inTimePeriod)
-
-	if inTimePeriod < 1 {
-		return outReal
-	}
-
-	if inTimePeriod <= 1 {
-		return TRange(inHigh, inLow, inClose)
-	}
-
-	outIdx := inTimePeriod
-	today := inTimePeriod + 1
-
-	tr := TRange(inHigh, inLow, inClose)
-	prevATRTemp := Sma(tr, inTimePeriod)
-	prevATR := prevATRTemp[inTimePeriod]
-	outReal[inTimePeriod] = prevATR
-
-	for outIdx = inTimePeriod + 1; outIdx < len(inClose); outIdx++ {
-		prevATR *= inTimePeriodF - 1.0
-		prevATR += tr[today]
-		prevATR /= inTimePeriodF
-		outReal[outIdx] = prevATR
-		today++
-	}
-
-	return outReal
-}
-
-// Natr - Normalized Average True Range
-func Natr(inHigh []float64, inLow []float64, inClose []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inClose))
-
-	if inTimePeriod < 1 {
-		return outReal
-	}
-
-	if inTimePeriod <= 1 {
-		return TRange(inHigh, inLow, inClose)
-	}
-
-	inTimePeriodF := float64(inTimePeriod)
-	outIdx := inTimePeriod
-	today := inTimePeriod
-
-	tr := TRange(inHigh, inLow, inClose)
-	prevATRTemp := Sma(tr, inTimePeriod)
-	prevATR := prevATRTemp[inTimePeriod]
-
-	tempValue := inClose[today]
-	if tempValue != 0.0 {
-		outReal[outIdx] = (prevATR / tempValue) * 100.0
-	} else {
-		outReal[outIdx] = 0.0
-	}
-
-	for outIdx = inTimePeriod + 1; outIdx < len(inClose); outIdx++ {
-		today++
-		prevATR *= inTimePeriodF - 1.0
-		prevATR += tr[today]
-		prevATR /= inTimePeriodF
-		tempValue = inClose[today]
-		if tempValue != 0.0 {
-			outReal[outIdx] = (prevATR / tempValue) * 100.0
-		} else {
-			outReal[0] = 0.0
-		}
-	}
-
-	return outReal
-}
-
-// TRange - True Range
-func TRange(inHigh []float64, inLow []float64, inClose []float64) []float64 {
-
-	outReal := make([]float64, len(inClose))
-
-	startIdx := 1
-	outIdx := startIdx
-	today := startIdx
-	for today < len(inClose) {
-		tempLT := inLow[today]
-		tempHT := inHigh[today]
-		tempCY := inClose[today-1]
-		greatest := tempHT - tempLT
-		val2 := math.Abs(tempCY - tempHT)
-		if val2 > greatest {
-			greatest = val2
-		}
-		val3 := math.Abs(tempCY - tempLT)
-		if val3 > greatest {
-			greatest = val3
-		}
-		outReal[outIdx] = greatest
-		outIdx++
-		today++
-	}
-
-	return outReal
-}
-
-/* Price Transform */
-
-// AvgPrice - Average Price (o+h+l+c)/4
-func AvgPrice(inOpen []float64, inHigh []float64, inLow []float64, inClose []float64) []float64 {
-
-	outReal := make([]float64, len(inClose))
-	outIdx := 0
-	startIdx := 0
-
-	for i := startIdx; i < len(inClose); i++ {
-		outReal[outIdx] = (inHigh[i] + inLow[i] + inClose[i] + inOpen[i]) / 4
-		outIdx++
-	}
-	return outReal
-}
-
-// MedPrice - Median Price (h+l)/2
-func MedPrice(inHigh []float64, inLow []float64) []float64 {
-
-	outReal := make([]float64, len(inHigh))
-	outIdx := 0
-	startIdx := 0
-
-	for i := startIdx; i < len(inHigh); i++ {
-		outReal[outIdx] = (inHigh[i] + inLow[i]) / 2.0
-		outIdx++
-	}
-	return outReal
-}
-
-// TypPrice - Typical Price (h+l+c)/3
-func TypPrice(inHigh []float64, inLow []float64, inClose []float64) []float64 {
-
-	outReal := make([]float64, len(inClose))
-	outIdx := 0
-	startIdx := 0
-
-	for i := startIdx; i < len(inClose); i++ {
-		outReal[outIdx] = (inHigh[i] + inLow[i] + inClose[i]) / 3.0
-		outIdx++
-	}
-	return outReal
-}
-
-// WclPrice - Weighted Close Price
-func WclPrice(inHigh []float64, inLow []float64, inClose []float64) []float64 {
-
-	outReal := make([]float64, len(inClose))
-	outIdx := 0
-	startIdx := 0
-
-	for i := startIdx; i < len(inClose); i++ {
-		outReal[outIdx] = (inHigh[i] + inLow[i] + (inClose[i] * 2.0)) / 4.0
-		outIdx++
-	}
-	return outReal
-}
-
-/* Cycle Indicators */
-
-// HtDcPeriod - Hilbert Transform - Dominant Cycle Period (lookback=32)
-func HtDcPeriod(inReal []float64) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	a := 0.0962
-	b := 0.5769
-	detrenderOdd := make([]float64, 3)
-	detrenderEven := make([]float64, 3)
-	q1Odd := make([]float64, 3)
-	q1Even := make([]float64, 3)
-	jIOdd := make([]float64, 3)
-	jIEven := make([]float64, 3)
-	jQOdd := make([]float64, 3)
-	jQEven := make([]float64, 3)
-	rad2Deg := 180.0 / (4.0 * math.Atan(1))
-	lookbackTotal := 32
-	startIdx := lookbackTotal
-	trailingWMAIdx := startIdx - lookbackTotal
-	today := trailingWMAIdx
-	tempReal := inReal[today]
-	today++
-	periodWMASub := tempReal
-	periodWMASum := tempReal
-	tempReal = inReal[today]
-	today++
-	periodWMASub += tempReal
-	periodWMASum += tempReal * 2.0
-	tempReal = inReal[today]
-	today++
-	periodWMASub += tempReal
-	periodWMASum += tempReal * 3.0
-	trailingWMAValue := 0.0
-	i := 9
-	smoothedValue := 0.0
-	for ok := true; ok; {
-		tempReal = inReal[today]
-		today++
-		periodWMASub += tempReal
-		periodWMASub -= trailingWMAValue
-		periodWMASum += tempReal * 4.0
-		trailingWMAValue = inReal[trailingWMAIdx]
-		trailingWMAIdx++
-		smoothedValue = periodWMASum * 0.1
-		periodWMASum -= periodWMASub
-		i--
-		ok = i != 0
-	}
-
-	hilbertIdx := 0
-	detrender := 0.0
-	prevDetrenderOdd := 0.0
-	prevDetrenderEven := 0.0
-	prevDetrenderInputOdd := 0.0
-	prevDetrenderInputEven := 0.0
-	q1 := 0.0
-	prevq1Odd := 0.0
-	prevq1Even := 0.0
-	prevq1InputOdd := 0.0
-	prevq1InputEven := 0.0
-	jI := 0.0
-	prevJIOdd := 0.0
-	prevJIEven := 0.0
-	prevJIInputOdd := 0.0
-	prevJIInputEven := 0.0
-	jQ := 0.0
-	prevJQOdd := 0.0
-	prevJQEven := 0.0
-	prevJQInputOdd := 0.0
-	prevJQInputEven := 0.0
-	period := 0.0
-	outIdx := 32
-	previ2 := 0.0
-	prevq2 := 0.0
-	Re := 0.0
-	Im := 0.0
-	i2 := 0.0
-	q2 := 0.0
-	i1ForOddPrev3 := 0.0
-	i1ForEvenPrev3 := 0.0
-	i1ForOddPrev2 := 0.0
-	i1ForEvenPrev2 := 0.0
-	smoothPeriod := 0.0
-	for today < len(inReal) {
-		adjustedPrevPeriod := (0.075 * period) + 0.54
-		todayValue := inReal[today]
-		periodWMASub += todayValue
-		periodWMASub -= trailingWMAValue
-		periodWMASum += todayValue * 4.0
-		trailingWMAValue = inReal[trailingWMAIdx]
-		trailingWMAIdx++
-		smoothedValue = periodWMASum * 0.1
-		periodWMASum -= periodWMASub
-		hilbertTempReal := 0.0
-		if (today % 2) == 0 {
-			hilbertTempReal = a * smoothedValue
-			detrender = -detrenderEven[hilbertIdx]
-			detrenderEven[hilbertIdx] = hilbertTempReal
-			detrender += hilbertTempReal
-			detrender -= prevDetrenderEven
-			prevDetrenderEven = b * prevDetrenderInputEven
-			detrender += prevDetrenderEven
-			prevDetrenderInputEven = smoothedValue
-			detrender *= adjustedPrevPeriod
-			hilbertTempReal = a * detrender
-			q1 = -q1Even[hilbertIdx]
-			q1Even[hilbertIdx] = hilbertTempReal
-			q1 += hilbertTempReal
-			q1 -= prevq1Even
-			prevq1Even = b * prevq1InputEven
-			q1 += prevq1Even
-			prevq1InputEven = detrender
-			q1 *= adjustedPrevPeriod
-			hilbertTempReal = a * i1ForEvenPrev3
-			jI = -jIEven[hilbertIdx]
-			jIEven[hilbertIdx] = hilbertTempReal
-			jI += hilbertTempReal
-			jI -= prevJIEven
-			prevJIEven = b * prevJIInputEven
-			jI += prevJIEven
-			prevJIInputEven = i1ForEvenPrev3
-			jI *= adjustedPrevPeriod
-			hilbertTempReal = a * q1
-			jQ = -jQEven[hilbertIdx]
-			jQEven[hilbertIdx] = hilbertTempReal
-			jQ += hilbertTempReal
-			jQ -= prevJQEven
-			prevJQEven = b * prevJQInputEven
-			jQ += prevJQEven
-			prevJQInputEven = q1
-			jQ *= adjustedPrevPeriod
-			hilbertIdx++
-			if hilbertIdx == 3 {
-				hilbertIdx = 0
-			}
-			q2 = (0.2 * (q1 + jI)) + (0.8 * prevq2)
-			i2 = (0.2 * (i1ForEvenPrev3 - jQ)) + (0.8 * previ2)
-			i1ForOddPrev3 = i1ForOddPrev2
-			i1ForOddPrev2 = detrender
-		} else {
-			hilbertTempReal = a * smoothedValue
-			detrender = -detrenderOdd[hilbertIdx]
-			detrenderOdd[hilbertIdx] = hilbertTempReal
-			detrender += hilbertTempReal
-			detrender -= prevDetrenderOdd
-			prevDetrenderOdd = b * prevDetrenderInputOdd
-			detrender += prevDetrenderOdd
-			prevDetrenderInputOdd = smoothedValue
-			detrender *= adjustedPrevPeriod
-			hilbertTempReal = a * detrender
-			q1 = -q1Odd[hilbertIdx]
-			q1Odd[hilbertIdx] = hilbertTempReal
-			q1 += hilbertTempReal
-			q1 -= prevq1Odd
-			prevq1Odd = b * prevq1InputOdd
-			q1 += prevq1Odd
-			prevq1InputOdd = detrender
-			q1 *= adjustedPrevPeriod
-			hilbertTempReal = a * i1ForOddPrev3
-			jI = -jIOdd[hilbertIdx]
-			jIOdd[hilbertIdx] = hilbertTempReal
-			jI += hilbertTempReal
-			jI -= prevJIOdd
-			prevJIOdd = b * prevJIInputOdd
-			jI += prevJIOdd
-			prevJIInputOdd = i1ForOddPrev3
-			jI *= adjustedPrevPeriod
-			hilbertTempReal = a * q1
-			jQ = -jQOdd[hilbertIdx]
-			jQOdd[hilbertIdx] = hilbertTempReal
-			jQ += hilbertTempReal
-			jQ -= prevJQOdd
-			prevJQOdd = b * prevJQInputOdd
-			jQ += prevJQOdd
-			prevJQInputOdd = q1
-			jQ *= adjustedPrevPeriod
-			q2 = (0.2 * (q1 + jI)) + (0.8 * prevq2)
-			i2 = (0.2 * (i1ForOddPrev3 - jQ)) + (0.8 * previ2)
-			i1ForEvenPrev3 = i1ForEvenPrev2
-			i1ForEvenPrev2 = detrender
-		}
-		Re = (0.2 * ((i2 * previ2) + (q2 * prevq2))) + (0.8 * Re)
-		Im = (0.2 * ((i2 * prevq2) - (q2 * previ2))) + (0.8 * Im)
-		prevq2 = q2
-		previ2 = i2
-		tempReal = period
-		if (Im != 0.0) && (Re != 0.0) {
-			period = 360.0 / (math.Atan(Im/Re) * rad2Deg)
-		}
-		tempReal2 := 1.5 * tempReal
-		if period > tempReal2 {
-			period = tempReal2
-		}
-		tempReal2 = 0.67 * tempReal
-		if period < tempReal2 {
-			period = tempReal2
-		}
-		if period < 6 {
-			period = 6
-		} else if period > 50 {
-			period = 50
-		}
-		period = (0.2 * period) + (0.8 * tempReal)
-		smoothPeriod = (0.33 * period) + (0.67 * smoothPeriod)
-		if today >= startIdx {
-			outReal[outIdx] = smoothPeriod
-			outIdx++
-		}
-		today++
-	}
-	return outReal
-}
-
-// HtDcPhase - Hilbert Transform - Dominant Cycle Phase (lookback=63)
-func HtDcPhase(inReal []float64) []float64 {
-
-	outReal := make([]float64, len(inReal))
-	a := 0.0962
-	b := 0.5769
-	detrenderOdd := make([]float64, 3)
-	detrenderEven := make([]float64, 3)
-	q1Odd := make([]float64, 3)
-	q1Even := make([]float64, 3)
-	jIOdd := make([]float64, 3)
-	jIEven := make([]float64, 3)
-	jQOdd := make([]float64, 3)
-	jQEven := make([]float64, 3)
-	smoothPriceIdx := 0
-	maxIdxSmoothPrice := (50 - 1)
-	smoothPrice := make([]float64, maxIdxSmoothPrice+1)
-	tempReal := math.Atan(1)
-	rad2Deg := 45.0 / tempReal
-	constDeg2RadBy360 := tempReal * 8.0
-	lookbackTotal := 63
-	startIdx := lookbackTotal
-	trailingWMAIdx := startIdx - lookbackTotal
-	today := trailingWMAIdx
-	tempReal = inReal[today]
-	today++
-	periodWMASub := tempReal
-	periodWMASum := tempReal
-	tempReal = inReal[today]
-	today++
-	periodWMASub += tempReal
-	periodWMASum += tempReal * 2.0
-	tempReal = inReal[today]
-	today++
-	periodWMASub += tempReal
-	periodWMASum += tempReal * 3.0
-	trailingWMAValue := 0.0
-	i := 34
-	smoothedValue := 0.0
-	for ok := true; ok; {
-		tempReal = inReal[today]
-		today++
-		periodWMASub += tempReal
-		periodWMASub -= trailingWMAValue
-		periodWMASum += tempReal * 4.0
-		trailingWMAValue = inReal[trailingWMAIdx]
-		trailingWMAIdx++
-		smoothedValue = periodWMASum * 0.1
-		periodWMASum -= periodWMASub
-		i--
-		ok = i != 0
-	}
-
-	hilbertIdx := 0
-	detrender := 0.0
-	prevDetrenderOdd := 0.0
-	prevDetrenderEven := 0.0
-	prevDetrenderInputOdd := 0.0
-	prevDetrenderInputEven := 0.0
-	q1 := 0.0
-	prevq1Odd := 0.0
-	prevq1Even := 0.0
-	prevq1InputOdd := 0.0
-	prevq1InputEven := 0.0
-	jI := 0.0
-	prevJIOdd := 0.0
-	prevJIEven := 0.0
-	prevJIInputOdd := 0.0
-	prevJIInputEven := 0.0
-	jQ := 0.0
-	prevJQOdd := 0.0
-	prevJQEven := 0.0
-	prevJQInputOdd := 0.0
-	prevJQInputEven := 0.0
-	period := 0.0
-	outIdx := 0
-	previ2 := 0.0
-	prevq2 := 0.0
-	Re := 0.0
-	Im := 0.0
-	i1ForOddPrev3 := 0.0
-	i1ForEvenPrev3 := 0.0
-	i1ForOddPrev2 := 0.0
-	i1ForEvenPrev2 := 0.0
-	smoothPeriod := 0.0
-	dcPhase := 0.0
-	q2 := 0.0
-	i2 := 0.0
-	for today < len(inReal) {
-		adjustedPrevPeriod := (0.075 * period) + 0.54
-		todayValue := inReal[today]
-		periodWMASub += todayValue
-		periodWMASub -= trailingWMAValue
-		periodWMASum += todayValue * 4.0
-		trailingWMAValue = inReal[trailingWMAIdx]
-		trailingWMAIdx++
-		smoothedValue = periodWMASum * 0.1
-		periodWMASum -= periodWMASub
-		hilbertTempReal := 0.0
-		smoothPrice[smoothPriceIdx] = smoothedValue
-		if (today % 2) == 0 {
-			hilbertTempReal = a * smoothedValue
-			detrender = -detrenderEven[hilbertIdx]
-			detrenderEven[hilbertIdx] = hilbertTempReal
-			detrender += hilbertTempReal
-			detrender -= prevDetrenderEven
-			prevDetrenderEven = b * prevDetrenderInputEven
-			detrender += prevDetrenderEven
-			prevDetrenderInputEven = smoothedValue
-			detrender *= adjustedPrevPeriod
-			hilbertTempReal = a * detrender
-			q1 = -q1Even[hilbertIdx]
-			q1Even[hilbertIdx] = hilbertTempReal
-			q1 += hilbertTempReal
-			q1 -= prevq1Even
-			prevq1Even = b * prevq1InputEven
-			q1 += prevq1Even
-			prevq1InputEven = detrender
-			q1 *= adjustedPrevPeriod
-			hilbertTempReal = a * i1ForEvenPrev3
-			jI = -jIEven[hilbertIdx]
-			jIEven[hilbertIdx] = hilbertTempReal
-			jI += hilbertTempReal
-			jI -= prevJIEven
-			prevJIEven = b * prevJIInputEven
-			jI += prevJIEven
-			prevJIInputEven = i1ForEvenPrev3
-			jI *= adjustedPrevPeriod
-			hilbertTempReal = a * q1
-			jQ = -jQEven[hilbertIdx]
-			jQEven[hilbertIdx] = hilbertTempReal
-			jQ += hilbertTempReal
-			jQ -= prevJQEven
-			prevJQEven = b * prevJQInputEven
-			jQ += prevJQEven
-			prevJQInputEven = q1
-			jQ *= adjustedPrevPeriod
-			hilbertIdx++
-			if hilbertIdx == 3 {
-				hilbertIdx = 0
-			}
-			q2 = (0.2 * (q1 + jI)) + (0.8 * prevq2)
-			i2 = (0.2 * (i1ForEvenPrev3 - jQ)) + (0.8 * previ2)
-			i1ForOddPrev3 = i1ForOddPrev2
-			i1ForOddPrev2 = detrender
-		} else {
-
-			hilbertTempReal = a * smoothedValue
-			detrender = -detrenderOdd[hilbertIdx]
-			detrenderOdd[hilbertIdx] = hilbertTempReal
-			detrender += hilbertTempReal
-			detrender -= prevDetrenderOdd
-			prevDetrenderOdd = b * prevDetrenderInputOdd
-			detrender += prevDetrenderOdd
-			prevDetrenderInputOdd = smoothedValue
-			detrender *= adjustedPrevPeriod
-			hilbertTempReal = a * detrender
-			q1 = -q1Odd[hilbertIdx]
-			q1Odd[hilbertIdx] = hilbertTempReal
-			q1 += hilbertTempReal
-			q1 -= prevq1Odd
-			prevq1Odd = b * prevq1InputOdd
-			q1 += prevq1Odd
-			prevq1InputOdd = detrender
-			q1 *= adjustedPrevPeriod
-			hilbertTempReal = a * i1ForOddPrev3
-			jI = -jIOdd[hilbertIdx]
-			jIOdd[hilbertIdx] = hilbertTempReal
-			jI += hilbertTempReal
-			jI -= prevJIOdd
-			prevJIOdd = b * prevJIInputOdd
-			jI += prevJIOdd
-			prevJIInputOdd = i1ForOddPrev3
-			jI *= adjustedPrevPeriod
-			hilbertTempReal = a * q1
-			jQ = -jQOdd[hilbertIdx]
-			jQOdd[hilbertIdx] = hilbertTempReal
-			jQ += hilbertTempReal
-			jQ -= prevJQOdd
-			prevJQOdd = b * prevJQInputOdd
-			jQ += prevJQOdd
-			prevJQInputOdd = q1
-			jQ *= adjustedPrevPeriod
-			q2 = (0.2 * (q1 + jI)) + (0.8 * prevq2)
-			i2 = (0.2 * (i1ForOddPrev3 - jQ)) + (0.8 * previ2)
-			i1ForEvenPrev3 = i1ForEvenPrev2
-			i1ForEvenPrev2 = detrender
-		}
-		Re = (0.2 * ((i2 * previ2) + (q2 * prevq2))) + (0.8 * Re)
-		Im = (0.2 * ((i2 * prevq2) - (q2 * previ2))) + (0.8 * Im)
-		prevq2 = q2
-		previ2 = i2
-		tempReal = period
-		if (Im != 0.0) && (Re != 0.0) {
-			period = 360.0 / (math.Atan(Im/Re) * rad2Deg)
-		}
-		tempReal2 := 1.5 * tempReal
-		if period > tempReal2 {
-			period = tempReal2
-		}
-		tempReal2 = 0.67 * tempReal
-		if period < tempReal2 {
-			period = tempReal2
-		}
-		if period < 6 {
-			period = 6
-		} else if period > 50 {
-			period = 50
-		}
-		period = (0.2 * period) + (0.8 * tempReal)
-		smoothPeriod = (0.33 * period) + (0.67 * smoothPeriod)
-		DCPeriod := smoothPeriod + 0.5
-		DCPeriodInt := math.Floor(DCPeriod)
-		realPart := 0.0
-		imagPart := 0.0
-		idx := smoothPriceIdx
-		for i := 0; i < int(DCPeriodInt); i++ {
-			tempReal = (float64(i) * constDeg2RadBy360) / (DCPeriodInt * 1.0)
-			tempReal2 = smoothPrice[idx]
-			realPart += math.Sin(tempReal) * tempReal2
-			imagPart += math.Cos(tempReal) * tempReal2
-			if idx == 0 {
-				idx = 50 - 1
-			} else {
-				idx--
-			}
-		}
-		tempReal = math.Abs(imagPart)
-		if tempReal > 0.0 {
-			dcPhase = math.Atan(realPart/imagPart) * rad2Deg
-		} else if tempReal <= 0.01 {
-			if realPart < 0.0 {
-				dcPhase -= 90.0
-			} else if realPart > 0.0 {
-				dcPhase += 90.0
-			}
-		}
-		dcPhase += 90.0
-		dcPhase += 360.0 / smoothPeriod
-		if imagPart < 0.0 {
-			dcPhase += 180.0
-		}
-		if dcPhase > 315.0 {
-			dcPhase -= 360.0
-		}
-		if today >= startIdx {
-			outReal[outIdx] = dcPhase
-			outIdx++
-		}
-		smoothPriceIdx++
-		if smoothPriceIdx > maxIdxSmoothPrice {
-			smoothPriceIdx = 0
-		}
-
-		today++
-	}
-	return outReal
-}
-
-// HtPhasor - Hibert Transform - Phasor Components (lookback=32)
-func HtPhasor(inReal []float64) ([]float64, []float64) {
-
-	outInPhase := make([]float64, len(inReal))
-	outQuadrature := make([]float64, len(inReal))
-
-	a := 0.0962
-	b := 0.5769
-	detrenderOdd := make([]float64, 3)
-	detrenderEven := make([]float64, 3)
-	q1Odd := make([]float64, 3)
-	q1Even := make([]float64, 3)
-	jIOdd := make([]float64, 3)
-	jIEven := make([]float64, 3)
-	jQOdd := make([]float64, 3)
-	jQEven := make([]float64, 3)
-	rad2Deg := 180.0 / (4.0 * math.Atan(1))
-	lookbackTotal := 32
-	startIdx := lookbackTotal
-	trailingWMAIdx := startIdx - lookbackTotal
-	today := trailingWMAIdx
-	tempReal := inReal[today]
-	today++
-	periodWMASub := tempReal
-	periodWMASum := tempReal
-	tempReal = inReal[today]
-	today++
-	periodWMASub += tempReal
-	periodWMASum += tempReal * 2.0
-	tempReal = inReal[today]
-	today++
-	periodWMASub += tempReal
-	periodWMASum += tempReal * 3.0
-	trailingWMAValue := 0.0
-	i := 9
-	smoothedValue := 0.0
-	for ok := true; ok; {
-		tempReal = inReal[today]
-		today++
-		periodWMASub += tempReal
-		periodWMASub -= trailingWMAValue
-		periodWMASum += tempReal * 4.0
-		trailingWMAValue = inReal[trailingWMAIdx]
-		trailingWMAIdx++
-		smoothedValue = periodWMASum * 0.1
-		periodWMASum -= periodWMASub
-		i--
-		ok = i != 0
-	}
-	hilbertIdx := 0
-	detrender := 0.0
-	prevDetrenderOdd := 0.0
-	prevDetrenderEven := 0.0
-	prevDetrenderInputOdd := 0.0
-	prevDetrenderInputEven := 0.0
-	q1 := 0.0
-	prevq1Odd := 0.0
-	prevq1Even := 0.0
-	prevq1InputOdd := 0.0
-	prevq1InputEven := 0.0
-	jI := 0.0
-	prevJIOdd := 0.0
-	prevJIEven := 0.0
-	prevJIInputOdd := 0.0
-	prevJIInputEven := 0.0
-	jQ := 0.0
-	prevJQOdd := 0.0
-	prevJQEven := 0.0
-	prevJQInputOdd := 0.0
-	prevJQInputEven := 0.0
-	period := 0.0
-	outIdx := 32
-	previ2 := 0.0
-	prevq2 := 0.0
-	Re := 0.0
-	Im := 0.0
-	i1ForOddPrev3 := 0.0
-	i1ForEvenPrev3 := 0.0
-	i1ForOddPrev2 := 0.0
-	i1ForEvenPrev2 := 0.0
-	i2 := 0.0
-	q2 := 0.0
-	for today < len(inReal) {
-		adjustedPrevPeriod := (0.075 * period) + 0.54
-		todayValue := inReal[today]
-		periodWMASub += todayValue
-		periodWMASub -= trailingWMAValue
-		periodWMASum += todayValue * 4.0
-		trailingWMAValue = inReal[trailingWMAIdx]
-		trailingWMAIdx++
-		smoothedValue = periodWMASum * 0.1
-		periodWMASum -= periodWMASub
-		hilbertTempReal := 0.0
-		if (today % 2) == 0 {
-			hilbertTempReal = a * smoothedValue
-			detrender = -detrenderEven[hilbertIdx]
-			detrenderEven[hilbertIdx] = hilbertTempReal
-			detrender += hilbertTempReal
-			detrender -= prevDetrenderEven
-			prevDetrenderEven = b * prevDetrenderInputEven
-			detrender += prevDetrenderEven
-			prevDetrenderInputEven = smoothedValue
-			detrender *= adjustedPrevPeriod
-			hilbertTempReal = a * detrender
-			q1 = -q1Even[hilbertIdx]
-			q1Even[hilbertIdx] = hilbertTempReal
-			q1 += hilbertTempReal
-			q1 -= prevq1Even
-			prevq1Even = b * prevq1InputEven
-			q1 += prevq1Even
-			prevq1InputEven = detrender
-			q1 *= adjustedPrevPeriod
-
-			if today >= startIdx {
-				outQuadrature[outIdx] = q1
-				outInPhase[outIdx] = i1ForEvenPrev3
-				outIdx++
-			}
-			hilbertTempReal = a * i1ForEvenPrev3
-			jI = -jIEven[hilbertIdx]
-			jIEven[hilbertIdx] = hilbertTempReal
-			jI += hilbertTempReal
-			jI -= prevJIEven
-			prevJIEven = b * prevJIInputEven
-			jI += prevJIEven
-			prevJIInputEven = i1ForEvenPrev3
-			jI *= adjustedPrevPeriod
-			hilbertTempReal = a * q1
-			jQ = -jQEven[hilbertIdx]
-			jQEven[hilbertIdx] = hilbertTempReal
-			jQ += hilbertTempReal
-			jQ -= prevJQEven
-			prevJQEven = b * prevJQInputEven
-			jQ += prevJQEven
-			prevJQInputEven = q1
-			jQ *= adjustedPrevPeriod
-			hilbertIdx++
-			if hilbertIdx == 3 {
-				hilbertIdx = 0
-			}
-			q2 = (0.2 * (q1 + jI)) + (0.8 * prevq2)
-			i2 = (0.2 * (i1ForEvenPrev3 - jQ)) + (0.8 * previ2)
-			i1ForOddPrev3 = i1ForOddPrev2
-			i1ForOddPrev2 = detrender
-		} else {
-
-			hilbertTempReal = a * smoothedValue
-			detrender = -detrenderOdd[hilbertIdx]
-			detrenderOdd[hilbertIdx] = hilbertTempReal
-			detrender += hilbertTempReal
-			detrender -= prevDetrenderOdd
-			prevDetrenderOdd = b * prevDetrenderInputOdd
-			detrender += prevDetrenderOdd
-			prevDetrenderInputOdd = smoothedValue
-			detrender *= adjustedPrevPeriod
-			hilbertTempReal = a * detrender
-			q1 = -q1Odd[hilbertIdx]
-			q1Odd[hilbertIdx] = hilbertTempReal
-			q1 += hilbertTempReal
-			q1 -= prevq1Odd
-			prevq1Odd = b * prevq1InputOdd
-			q1 += prevq1Odd
-			prevq1InputOdd = detrender
-			q1 *= adjustedPrevPeriod
-			if today >= startIdx {
-				outQuadrature[outIdx] = q1
-				outInPhase[outIdx] = i1ForOddPrev3
-				outIdx++
-			}
-			hilbertTempReal = a * i1ForOddPrev3
-			jI = -jIOdd[hilbertIdx]
-			jIOdd[hilbertIdx] = hilbertTempReal
-			jI += hilbertTempReal
-			jI -= prevJIOdd
-			prevJIOdd = b * prevJIInputOdd
-			jI += prevJIOdd
-			prevJIInputOdd = i1ForOddPrev3
-			jI *= adjustedPrevPeriod
-			hilbertTempReal = a * q1
-			jQ = -jQOdd[hilbertIdx]
-			jQOdd[hilbertIdx] = hilbertTempReal
-			jQ += hilbertTempReal
-			jQ -= prevJQOdd
-			prevJQOdd = b * prevJQInputOdd
-			jQ += prevJQOdd
-			prevJQInputOdd = q1
-			jQ *= adjustedPrevPeriod
-			q2 = (0.2 * (q1 + jI)) + (0.8 * prevq2)
-			i2 = (0.2 * (i1ForOddPrev3 - jQ)) + (0.8 * previ2)
-			i1ForEvenPrev3 = i1ForEvenPrev2
-			i1ForEvenPrev2 = detrender
-		}
-		Re = (0.2 * ((i2 * previ2) + (q2 * prevq2))) + (0.8 * Re)
-		Im = (0.2 * ((i2 * prevq2) - (q2 * previ2))) + (0.8 * Im)
-		prevq2 = q2
-		previ2 = i2
-		tempReal = period
-		if (Im != 0.0) && (Re != 0.0) {
-			period = 360.0 / (math.Atan(Im/Re) * rad2Deg)
-		}
-		tempReal2 := 1.5 * tempReal
-		if period > tempReal2 {
-			period = tempReal2
-		}
-		tempReal2 = 0.67 * tempReal
-		if period < tempReal2 {
-			period = tempReal2
-		}
-		if period < 6 {
-			period = 6
-		} else if period > 50 {
-			period = 50
-		}
-		period = (0.2 * period) + (0.8 * tempReal)
-		today++
-	}
-	return outInPhase, outQuadrature
-}
-
-// HtSine - Hilbert Transform - SineWave (lookback=63)
-func HtSine(inReal []float64) ([]float64, []float64) {
-
-	outSine := make([]float64, len(inReal))
-	outLeadSine := make([]float64, len(inReal))
-
-	a := 0.0962
-	b := 0.5769
-	detrenderOdd := make([]float64, 3)
-	detrenderEven := make([]float64, 3)
-	q1Odd := make([]float64, 3)
-	q1Even := make([]float64, 3)
-	jIOdd := make([]float64, 3)
-	jIEven := make([]float64, 3)
-	jQOdd := make([]float64, 3)
-	jQEven := make([]float64, 3)
-	smoothPriceIdx := 0
-	maxIdxSmoothPrice := (50 - 1)
-	smoothPrice := make([]float64, maxIdxSmoothPrice+1)
-	tempReal := math.Atan(1)
-	rad2Deg := 45.0 / tempReal
-	deg2Rad := 1.0 / rad2Deg
-	constDeg2RadBy360 := tempReal * 8.0
-	lookbackTotal := 63
-	startIdx := lookbackTotal
-	trailingWMAIdx := startIdx - lookbackTotal
-	today := trailingWMAIdx
-	tempReal = inReal[today]
-	today++
-	periodWMASub := tempReal
-	periodWMASum := tempReal
-	tempReal = inReal[today]
-	today++
-	periodWMASub += tempReal
-	periodWMASum += tempReal * 2.0
-	tempReal = inReal[today]
-	today++
-	periodWMASub += tempReal
-	periodWMASum += tempReal * 3.0
-	trailingWMAValue := 0.0
-	i := 34
-	smoothedValue := 0.0
-	for ok := true; ok; {
-		tempReal = inReal[today]
-		today++
-		periodWMASub += tempReal
-		periodWMASub -= trailingWMAValue
-		periodWMASum += tempReal * 4.0
-		trailingWMAValue = inReal[trailingWMAIdx]
-		trailingWMAIdx++
-		smoothedValue = periodWMASum * 0.1
-		periodWMASum -= periodWMASub
-		i--
-		ok = i != 0
-	}
-
-	hilbertIdx := 0
-	detrender := 0.0
-	prevDetrenderOdd := 0.0
-	prevDetrenderEven := 0.0
-	prevDetrenderInputOdd := 0.0
-	prevDetrenderInputEven := 0.0
-	q1 := 0.0
-	prevq1Odd := 0.0
-	prevq1Even := 0.0
-	prevq1InputOdd := 0.0
-	prevq1InputEven := 0.0
-	jI := 0.0
-	prevJIOdd := 0.0
-	prevJIEven := 0.0
-	prevJIInputOdd := 0.0
-	prevJIInputEven := 0.0
-	jQ := 0.0
-	prevJQOdd := 0.0
-	prevJQEven := 0.0
-	prevJQInputOdd := 0.0
-	prevJQInputEven := 0.0
-	period := 0.0
-	outIdx := 63
-	previ2 := 0.0
-	prevq2 := 0.0
-	Re := 0.0
-	Im := 0.0
-	i1ForOddPrev3 := 0.0
-	i1ForEvenPrev3 := 0.0
-	i1ForOddPrev2 := 0.0
-	i1ForEvenPrev2 := 0.0
-	smoothPeriod := 0.0
-	dcPhase := 0.0
-	hilbertTempReal := 0.0
-	q2 := 0.0
-	i2 := 0.0
-	for today < len(inReal) {
-		adjustedPrevPeriod := (0.075 * period) + 0.54
-		todayValue := inReal[today]
-		periodWMASub += todayValue
-		periodWMASub -= trailingWMAValue
-		periodWMASum += todayValue * 4.0
-		trailingWMAValue = inReal[trailingWMAIdx]
-		trailingWMAIdx++
-		smoothedValue = periodWMASum * 0.1
-		periodWMASum -= periodWMASub
-		smoothPrice[smoothPriceIdx] = smoothedValue
-		if (today % 2) == 0 {
-			hilbertTempReal = a * smoothedValue
-			detrender = -detrenderEven[hilbertIdx]
-			detrenderEven[hilbertIdx] = hilbertTempReal
-			detrender += hilbertTempReal
-			detrender -= prevDetrenderEven
-			prevDetrenderEven = b * prevDetrenderInputEven
-			detrender += prevDetrenderEven
-			prevDetrenderInputEven = smoothedValue
-			detrender *= adjustedPrevPeriod
-			hilbertTempReal = a * detrender
-			q1 = -q1Even[hilbertIdx]
-			q1Even[hilbertIdx] = hilbertTempReal
-			q1 += hilbertTempReal
-			q1 -= prevq1Even
-			prevq1Even = b * prevq1InputEven
-			q1 += prevq1Even
-			prevq1InputEven = detrender
-			q1 *= adjustedPrevPeriod
-			hilbertTempReal = a * i1ForEvenPrev3
-			jI = -jIEven[hilbertIdx]
-			jIEven[hilbertIdx] = hilbertTempReal
-			jI += hilbertTempReal
-			jI -= prevJIEven
-			prevJIEven = b * prevJIInputEven
-			jI += prevJIEven
-			prevJIInputEven = i1ForEvenPrev3
-			jI *= adjustedPrevPeriod
-			hilbertTempReal = a * q1
-			jQ = -jQEven[hilbertIdx]
-			jQEven[hilbertIdx] = hilbertTempReal
-			jQ += hilbertTempReal
-			jQ -= prevJQEven
-			prevJQEven = b * prevJQInputEven
-			jQ += prevJQEven
-			prevJQInputEven = q1
-			jQ *= adjustedPrevPeriod
-			hilbertIdx++
-			if hilbertIdx == 3 {
-				hilbertIdx = 0
-			}
-			q2 = (0.2 * (q1 + jI)) + (0.8 * prevq2)
-			i2 = (0.2 * (i1ForEvenPrev3 - jQ)) + (0.8 * previ2)
-			i1ForOddPrev3 = i1ForOddPrev2
-			i1ForOddPrev2 = detrender
-		} else {
-			hilbertTempReal = a * smoothedValue
-			detrender = -detrenderOdd[hilbertIdx]
-			detrenderOdd[hilbertIdx] = hilbertTempReal
-			detrender += hilbertTempReal
-			detrender -= prevDetrenderOdd
-			prevDetrenderOdd = b * prevDetrenderInputOdd
-			detrender += prevDetrenderOdd
-			prevDetrenderInputOdd = smoothedValue
-			detrender *= adjustedPrevPeriod
-			hilbertTempReal = a * detrender
-			q1 = -q1Odd[hilbertIdx]
-			q1Odd[hilbertIdx] = hilbertTempReal
-			q1 += hilbertTempReal
-			q1 -= prevq1Odd
-			prevq1Odd = b * prevq1InputOdd
-			q1 += prevq1Odd
-			prevq1InputOdd = detrender
-			q1 *= adjustedPrevPeriod
-			hilbertTempReal = a * i1ForOddPrev3
-			jI = -jIOdd[hilbertIdx]
-			jIOdd[hilbertIdx] = hilbertTempReal
-			jI += hilbertTempReal
-			jI -= prevJIOdd
-			prevJIOdd = b * prevJIInputOdd
-			jI += prevJIOdd
-			prevJIInputOdd = i1ForOddPrev3
-			jI *= adjustedPrevPeriod
-			hilbertTempReal = a * q1
-			jQ = -jQOdd[hilbertIdx]
-			jQOdd[hilbertIdx] = hilbertTempReal
-			jQ += hilbertTempReal
-			jQ -= prevJQOdd
-			prevJQOdd = b * prevJQInputOdd
-			jQ += prevJQOdd
-			prevJQInputOdd = q1
-			jQ *= adjustedPrevPeriod
-			q2 = (0.2 * (q1 + jI)) + (0.8 * prevq2)
-			i2 = (0.2 * (i1ForOddPrev3 - jQ)) + (0.8 * previ2)
-			i1ForEvenPrev3 = i1ForEvenPrev2
-			i1ForEvenPrev2 = detrender
-		}
-		Re = (0.2 * ((i2 * previ2) + (q2 * prevq2))) + (0.8 * Re)
-		Im = (0.2 * ((i2 * prevq2) - (q2 * previ2))) + (0.8 * Im)
-		prevq2 = q2
-		previ2 = i2
-		tempReal = period
-		if (Im != 0.0) && (Re != 0.0) {
-			period = 360.0 / (math.Atan(Im/Re) * rad2Deg)
-		}
-		tempReal2 := 1.5 * tempReal
-		if period > tempReal2 {
-			period = tempReal2
-		}
-		tempReal2 = 0.67 * tempReal
-		if period < tempReal2 {
-			period = tempReal2
-		}
-		if period < 6 {
-			period = 6
-		} else if period > 50 {
-			period = 50
-		}
-		period = (0.2 * period) + (0.8 * tempReal)
-		smoothPeriod = (0.33 * period) + (0.67 * smoothPeriod)
-		DCPeriod := smoothPeriod + 0.5
-		DCPeriodInt := math.Floor(DCPeriod)
-		realPart := 0.0
-		imagPart := 0.0
-		idx := smoothPriceIdx
-		for i := 0; i < int(DCPeriodInt); i++ {
-			tempReal = (float64(i) * constDeg2RadBy360) / (DCPeriodInt * 1.0)
-			tempReal2 = smoothPrice[idx]
-			realPart += math.Sin(tempReal) * tempReal2
-			imagPart += math.Cos(tempReal) * tempReal2
-			if idx == 0 {
-				idx = 50 - 1
-			} else {
-				idx--
-			}
-		}
-		tempReal = math.Abs(imagPart)
-		if tempReal > 0.0 {
-			dcPhase = math.Atan(realPart/imagPart) * rad2Deg
-		} else if tempReal <= 0.01 {
-			if realPart < 0.0 {
-				dcPhase -= 90.0
-			} else if realPart > 0.0 {
-				dcPhase += 90.0
-			}
-		}
-		dcPhase += 90.0
-		dcPhase += 360.0 / smoothPeriod
-		if imagPart < 0.0 {
-			dcPhase += 180.0
-		}
-		if dcPhase > 315.0 {
-			dcPhase -= 360.0
-		}
-		if today >= startIdx {
-			outSine[outIdx] = math.Sin(dcPhase * deg2Rad)
-			outLeadSine[outIdx] = math.Sin((dcPhase + 45) * deg2Rad)
-			outIdx++
-		}
-		smoothPriceIdx++
-		if smoothPriceIdx > maxIdxSmoothPrice {
-			smoothPriceIdx = 0
-		}
-
-		today++
-	}
-	return outSine, outLeadSine
-}
-
-// HtTrendMode - Hilbert Transform - Trend vs Cycle Mode (lookback=63)
-func HtTrendMode(inReal []float64) []float64 {
-
-	outReal := make([]float64, len(inReal))
-	a := 0.0962
-	b := 0.5769
-	detrenderOdd := make([]float64, 3)
-	detrenderEven := make([]float64, 3)
-	q1Odd := make([]float64, 3)
-	q1Even := make([]float64, 3)
-	jIOdd := make([]float64, 3)
-	jIEven := make([]float64, 3)
-	jQOdd := make([]float64, 3)
-	jQEven := make([]float64, 3)
-	smoothPriceIdx := 0
-	maxIdxSmoothPrice := (50 - 1)
-	smoothPrice := make([]float64, maxIdxSmoothPrice+1)
-	iTrend1 := 0.0
-	iTrend2 := 0.0
-	iTrend3 := 0.0
-	daysInTrend := 0
-	prevdcPhase := 0.0
-	dcPhase := 0.0
-	prevSine := 0.0
-	sine := 0.0
-	prevLeadSine := 0.0
-	leadSine := 0.0
-	tempReal := math.Atan(1)
-	rad2Deg := 45.0 / tempReal
-	deg2Rad := 1.0 / rad2Deg
-	constDeg2RadBy360 := tempReal * 8.0
-	lookbackTotal := 63
-	startIdx := lookbackTotal
-	trailingWMAIdx := startIdx - lookbackTotal
-	today := trailingWMAIdx
-	tempReal = inReal[today]
-	today++
-	periodWMASub := tempReal
-	periodWMASum := tempReal
-	tempReal = inReal[today]
-	today++
-	periodWMASub += tempReal
-	periodWMASum += tempReal * 2.0
-	tempReal = inReal[today]
-	today++
-	periodWMASub += tempReal
-	periodWMASum += tempReal * 3.0
-	trailingWMAValue := 0.0
-	i := 34
-
-	for ok := true; ok; {
-		tempReal = inReal[today]
-		today++
-		periodWMASub += tempReal
-		periodWMASub -= trailingWMAValue
-		periodWMASum += tempReal * 4.0
-		trailingWMAValue = inReal[trailingWMAIdx]
-		trailingWMAIdx++
-		//smoothedValue := periodWMASum * 0.1
-		periodWMASum -= periodWMASub
-		i--
-		ok = i != 0
-	}
-
-	hilbertIdx := 0
-	detrender := 0.0
-	prevDetrenderOdd := 0.0
-	prevDetrenderEven := 0.0
-	prevDetrenderInputOdd := 0.0
-	prevDetrenderInputEven := 0.0
-	q1 := 0.0
-	prevq1Odd := 0.0
-	prevq1Even := 0.0
-	prevq1InputOdd := 0.0
-	prevq1InputEven := 0.0
-	jI := 0.0
-	prevJIOdd := 0.0
-	prevJIEven := 0.0
-	prevJIInputOdd := 0.0
-	prevJIInputEven := 0.0
-	jQ := 0.0
-	prevJQOdd := 0.0
-	prevJQEven := 0.0
-	prevJQInputOdd := 0.0
-	prevJQInputEven := 0.0
-	period := 0.0
-	outIdx := 63
-	previ2 := 0.0
-	prevq2 := 0.0
-	Re := 0.0
-	Im := 0.0
-	i1ForOddPrev3 := 0.0
-	i1ForEvenPrev3 := 0.0
-	i1ForOddPrev2 := 0.0
-	i1ForEvenPrev2 := 0.0
-	smoothPeriod := 0.0
-	dcPhase = 0.0
-	smoothedValue := 0.0
-	hilbertTempReal := 0.0
-	q2 := 0.0
-	i2 := 0.0
-	for today < len(inReal) {
-		adjustedPrevPeriod := (0.075 * period) + 0.54
-		todayValue := inReal[today]
-		periodWMASub += todayValue
-		periodWMASub -= trailingWMAValue
-		periodWMASum += todayValue * 4.0
-		trailingWMAValue = inReal[trailingWMAIdx]
-		trailingWMAIdx++
-		smoothedValue = periodWMASum * 0.1
-		periodWMASum -= periodWMASub
-
-		smoothPrice[smoothPriceIdx] = smoothedValue
-		if (today % 2) == 0 {
-			hilbertTempReal = a * smoothedValue
-			detrender = -detrenderEven[hilbertIdx]
-			detrenderEven[hilbertIdx] = hilbertTempReal
-			detrender += hilbertTempReal
-			detrender -= prevDetrenderEven
-			prevDetrenderEven = b * prevDetrenderInputEven
-			detrender += prevDetrenderEven
-			prevDetrenderInputEven = smoothedValue
-			detrender *= adjustedPrevPeriod
-			hilbertTempReal = a * detrender
-			q1 = -q1Even[hilbertIdx]
-			q1Even[hilbertIdx] = hilbertTempReal
-			q1 += hilbertTempReal
-			q1 -= prevq1Even
-			prevq1Even = b * prevq1InputEven
-			q1 += prevq1Even
-			prevq1InputEven = detrender
-			q1 *= adjustedPrevPeriod
-			hilbertTempReal = a * i1ForEvenPrev3
-			jI = -jIEven[hilbertIdx]
-			jIEven[hilbertIdx] = hilbertTempReal
-			jI += hilbertTempReal
-			jI -= prevJIEven
-			prevJIEven = b * prevJIInputEven
-			jI += prevJIEven
-			prevJIInputEven = i1ForEvenPrev3
-			jI *= adjustedPrevPeriod
-			hilbertTempReal = a * q1
-			jQ = -jQEven[hilbertIdx]
-			jQEven[hilbertIdx] = hilbertTempReal
-			jQ += hilbertTempReal
-			jQ -= prevJQEven
-			prevJQEven = b * prevJQInputEven
-			jQ += prevJQEven
-			prevJQInputEven = q1
-			jQ *= adjustedPrevPeriod
-			hilbertIdx++
-			if hilbertIdx == 3 {
-				hilbertIdx = 0
-			}
-			q2 = (0.2 * (q1 + jI)) + (0.8 * prevq2)
-			i2 = (0.2 * (i1ForEvenPrev3 - jQ)) + (0.8 * previ2)
-			i1ForOddPrev3 = i1ForOddPrev2
-			i1ForOddPrev2 = detrender
-		} else {
-			hilbertTempReal = a * smoothedValue
-			detrender = -detrenderOdd[hilbertIdx]
-			detrenderOdd[hilbertIdx] = hilbertTempReal
-			detrender += hilbertTempReal
-			detrender -= prevDetrenderOdd
-			prevDetrenderOdd = b * prevDetrenderInputOdd
-			detrender += prevDetrenderOdd
-			prevDetrenderInputOdd = smoothedValue
-			detrender *= adjustedPrevPeriod
-			hilbertTempReal = a * detrender
-			q1 = -q1Odd[hilbertIdx]
-			q1Odd[hilbertIdx] = hilbertTempReal
-			q1 += hilbertTempReal
-			q1 -= prevq1Odd
-			prevq1Odd = b * prevq1InputOdd
-			q1 += prevq1Odd
-			prevq1InputOdd = detrender
-			q1 *= adjustedPrevPeriod
-			hilbertTempReal = a * i1ForOddPrev3
-			jI = -jIOdd[hilbertIdx]
-			jIOdd[hilbertIdx] = hilbertTempReal
-			jI += hilbertTempReal
-			jI -= prevJIOdd
-			prevJIOdd = b * prevJIInputOdd
-			jI += prevJIOdd
-			prevJIInputOdd = i1ForOddPrev3
-			jI *= adjustedPrevPeriod
-			hilbertTempReal = a * q1
-			jQ = -jQOdd[hilbertIdx]
-			jQOdd[hilbertIdx] = hilbertTempReal
-			jQ += hilbertTempReal
-			jQ -= prevJQOdd
-			prevJQOdd = b * prevJQInputOdd
-			jQ += prevJQOdd
-			prevJQInputOdd = q1
-			jQ *= adjustedPrevPeriod
-			q2 = (0.2 * (q1 + jI)) + (0.8 * prevq2)
-			i2 = (0.2 * (i1ForOddPrev3 - jQ)) + (0.8 * previ2)
-			i1ForEvenPrev3 = i1ForEvenPrev2
-			i1ForEvenPrev2 = detrender
-		}
-		Re = (0.2 * ((i2 * previ2) + (q2 * prevq2))) + (0.8 * Re)
-		Im = (0.2 * ((i2 * prevq2) - (q2 * previ2))) + (0.8 * Im)
-		prevq2 = q2
-		previ2 = i2
-		tempReal = period
-		if (Im != 0.0) && (Re != 0.0) {
-			period = 360.0 / (math.Atan(Im/Re) * rad2Deg)
-		}
-		tempReal2 := 1.5 * tempReal
-		if period > tempReal2 {
-			period = tempReal2
-		}
-		tempReal2 = 0.67 * tempReal
-		if period < tempReal2 {
-			period = tempReal2
-		}
-		if period < 6 {
-			period = 6
-		} else if period > 50 {
-			period = 50
-		}
-		period = (0.2 * period) + (0.8 * tempReal)
-		smoothPeriod = (0.33 * period) + (0.67 * smoothPeriod)
-		prevdcPhase = dcPhase
-		DCPeriod := smoothPeriod + 0.5
-		DCPeriodInt := math.Floor(DCPeriod)
-		realPart := 0.0
-		imagPart := 0.0
-		idx := smoothPriceIdx
-		for i := 0; i < int(DCPeriodInt); i++ {
-			tempReal = (float64(i) * constDeg2RadBy360) / (DCPeriodInt * 1.0)
-			tempReal2 = smoothPrice[idx]
-			realPart += math.Sin(tempReal) * tempReal2
-			imagPart += math.Cos(tempReal) * tempReal2
-			if idx == 0 {
-				idx = 50 - 1
-			} else {
-				idx--
-			}
-		}
-		tempReal = math.Abs(imagPart)
-		if tempReal > 0.0 {
-			dcPhase = math.Atan(realPart/imagPart) * rad2Deg
-		} else if tempReal <= 0.01 {
-			if realPart < 0.0 {
-				dcPhase -= 90.0
-			} else if realPart > 0.0 {
-				dcPhase += 90.0
-			}
-		}
-		dcPhase += 90.0
-		dcPhase += 360.0 / smoothPeriod
-		if imagPart < 0.0 {
-			dcPhase += 180.0
-		}
-		if dcPhase > 315.0 {
-			dcPhase -= 360.0
-		}
-		prevSine = sine
-		prevLeadSine = leadSine
-		sine = math.Sin(dcPhase * deg2Rad)
-		leadSine = math.Sin((dcPhase + 45) * deg2Rad)
-		DCPeriod = smoothPeriod + 0.5
-		DCPeriodInt = math.Floor(DCPeriod)
-		idx = today
-		tempReal = 0.0
-		for i := 0; i < int(DCPeriodInt); i++ {
-			tempReal += inReal[idx]
-			idx--
-		}
-		if DCPeriodInt > 0 {
-			tempReal = tempReal / (DCPeriodInt * 1.0)
-		}
-		trendline := (4.0*tempReal + 3.0*iTrend1 + 2.0*iTrend2 + iTrend3) / 10.0
-		iTrend3 = iTrend2
-		iTrend2 = iTrend1
-		iTrend1 = tempReal
-		trend := 1
-		if ((sine > leadSine) && (prevSine <= prevLeadSine)) || ((sine < leadSine) && (prevSine >= prevLeadSine)) {
-			daysInTrend = 0
-			trend = 0
-		}
-		daysInTrend++
-		if float64(daysInTrend) < (0.5 * smoothPeriod) {
-			trend = 0
-		}
-		tempReal = dcPhase - prevdcPhase
-		if (smoothPeriod != 0.0) && ((tempReal > (0.67 * 360.0 / smoothPeriod)) && (tempReal < (1.5 * 360.0 / smoothPeriod))) {
-			trend = 0
-		}
-		tempReal = smoothPrice[smoothPriceIdx]
-		if (trendline != 0.0) && (math.Abs((tempReal-trendline)/trendline) >= 0.015) {
-			trend = 1
-		}
-		if today >= startIdx {
-			outReal[outIdx] = float64(trend)
-			outIdx++
-		}
-		smoothPriceIdx++
-		if smoothPriceIdx > maxIdxSmoothPrice {
-			smoothPriceIdx = 0
-		}
-
-		today++
-	}
-	return outReal
-}
-
-/* Statistic Functions */
-
-// Beta - Beta
-func Beta(inReal0 []float64, inReal1 []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal0))
-
-	x := 0.0
-	y := 0.0
-	sSS := 0.0
-	sXY := 0.0
-	sX := 0.0
-	sY := 0.0
-	tmpReal := 0.0
-	n := 0.0
-	nbInitialElementNeeded := inTimePeriod
-	startIdx := nbInitialElementNeeded
-	trailingIdx := startIdx - nbInitialElementNeeded
-	trailingLastPriceX := inReal0[trailingIdx]
-	lastPriceX := trailingLastPriceX
-	trailingLastPriceY := inReal1[trailingIdx]
-	lastPriceY := trailingLastPriceY
-	trailingIdx++
-	i := trailingIdx
-	for i < startIdx {
-		tmpReal := inReal0[i]
-		x := 0.0
-		if !((-0.00000000000001 < lastPriceX) && (lastPriceX < 0.00000000000001)) {
-			x = (tmpReal - lastPriceX) / lastPriceX
-		}
-		lastPriceX = tmpReal
-		tmpReal = inReal1[i]
-		i++
-		y := 0.0
-		if !((-0.00000000000001 < lastPriceY) && (lastPriceY < 0.00000000000001)) {
-			y = (tmpReal - lastPriceY) / lastPriceY
-		}
-		lastPriceY = tmpReal
-		sSS += x * x
-		sXY += x * y
-		sX += x
-		sY += y
-	}
-	outIdx := inTimePeriod
-	n = float64(inTimePeriod)
-	for ok := true; ok; {
-		tmpReal = inReal0[i]
-		if !((-0.00000000000001 < lastPriceX) && (lastPriceX < 0.00000000000001)) {
-			x = (tmpReal - lastPriceX) / lastPriceX
-		} else {
-			x = 0.0
-		}
-		lastPriceX = tmpReal
-		tmpReal = inReal1[i]
-		i++
-		if !((-0.00000000000001 < lastPriceY) && (lastPriceY < 0.00000000000001)) {
-			y = (tmpReal - lastPriceY) / lastPriceY
-		} else {
-			y = 0.0
-		}
-		lastPriceY = tmpReal
-		sSS += x * x
-		sXY += x * y
-		sX += x
-		sY += y
-		tmpReal = inReal0[trailingIdx]
-		if !(((-(0.00000000000001)) < trailingLastPriceX) && (trailingLastPriceX < (0.00000000000001))) {
-			x = (tmpReal - trailingLastPriceX) / trailingLastPriceX
-		} else {
-			x = 0.0
-		}
-		trailingLastPriceX = tmpReal
-		tmpReal = inReal1[trailingIdx]
-		trailingIdx++
-		if !(((-(0.00000000000001)) < trailingLastPriceY) && (trailingLastPriceY < (0.00000000000001))) {
-			y = (tmpReal - trailingLastPriceY) / trailingLastPriceY
-		} else {
-			y = 0.0
-		}
-		trailingLastPriceY = tmpReal
-		tmpReal = (n * sSS) - (sX * sX)
-		if !(((-(0.00000000000001)) < tmpReal) && (tmpReal < (0.00000000000001))) {
-			outReal[outIdx] = ((n * sXY) - (sX * sY)) / tmpReal
-		} else {
-			outReal[outIdx] = 0.0
-		}
-		outIdx++
-		sSS -= x * x
-		sXY -= x * y
-		sX -= x
-		sY -= y
-		ok = i < len(inReal0)
-	}
-
-	return outReal
-}
-
-// Correl - Pearson's Correlation Coefficient (r)
-func Correl(inReal0 []float64, inReal1 []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal0))
-
-	inTimePeriodF := float64(inTimePeriod)
-	lookbackTotal := inTimePeriod - 1
-	startIdx := lookbackTotal
-	trailingIdx := startIdx - lookbackTotal
-	sumXY, sumX, sumY, sumX2, sumY2 := 0.0, 0.0, 0.0, 0.0, 0.0
-	today := trailingIdx
-	for today = trailingIdx; today <= startIdx; today++ {
-		x := inReal0[today]
-		sumX += x
-		sumX2 += x * x
-		y := inReal1[today]
-		sumXY += x * y
-		sumY += y
-		sumY2 += y * y
-	}
-	trailingX := inReal0[trailingIdx]
-	trailingY := inReal1[trailingIdx]
-	trailingIdx++
-	tempReal := (sumX2 - ((sumX * sumX) / inTimePeriodF)) * (sumY2 - ((sumY * sumY) / inTimePeriodF))
-	if !(tempReal < 0.00000000000001) {
-		outReal[inTimePeriod-1] = (sumXY - ((sumX * sumY) / inTimePeriodF)) / math.Sqrt(tempReal)
-	} else {
-		outReal[inTimePeriod-1] = 0.0
-	}
-	outIdx := inTimePeriod
-	for today < len(inReal0) {
-		sumX -= trailingX
-		sumX2 -= trailingX * trailingX
-		sumXY -= trailingX * trailingY
-		sumY -= trailingY
-		sumY2 -= trailingY * trailingY
-		x := inReal0[today]
-		sumX += x
-		sumX2 += x * x
-		y := inReal1[today]
-		today++
-		sumXY += x * y
-		sumY += y
-		sumY2 += y * y
-		trailingX = inReal0[trailingIdx]
-		trailingY = inReal1[trailingIdx]
-		trailingIdx++
-		tempReal = (sumX2 - ((sumX * sumX) / inTimePeriodF)) * (sumY2 - ((sumY * sumY) / inTimePeriodF))
-		if !(tempReal < (0.00000000000001)) {
-			outReal[outIdx] = (sumXY - ((sumX * sumY) / inTimePeriodF)) / math.Sqrt(tempReal)
-		} else {
-			outReal[outIdx] = 0.0
-		}
-		outIdx++
-	}
-	return outReal
-}
-
-// LinearReg - Linear Regression
-func LinearReg(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	inTimePeriodF := float64(inTimePeriod)
-	lookbackTotal := inTimePeriod
-	startIdx := lookbackTotal
-	outIdx := startIdx - 1
-	today := startIdx - 1
-	sumX := inTimePeriodF * (inTimePeriodF - 1) * 0.5
-	sumXSqr := inTimePeriodF * (inTimePeriodF - 1) * (2*inTimePeriodF - 1) / 6
-	divisor := sumX*sumX - inTimePeriodF*sumXSqr
-	//initialize values of sumY and sumXY over first (inTimePeriod) input values
-	sumXY := 0.0
-	sumY := 0.0
-	i := inTimePeriod
-	for i != 0 {
-		i--
-		tempValue1 := inReal[today-i]
-		sumY += tempValue1
-		sumXY += float64(i) * tempValue1
-	}
-	for today < len(inReal) {
-		//sumX and sumXY are already available for first output value
-		if today > startIdx-1 {
-			tempValue2 := inReal[today-inTimePeriod]
-			sumXY += sumY - inTimePeriodF*tempValue2
-			sumY += inReal[today] - tempValue2
-		}
-		m := (inTimePeriodF*sumXY - sumX*sumY) / divisor
-		b := (sumY - m*sumX) / inTimePeriodF
-		outReal[outIdx] = b + m*(inTimePeriodF-1)
-		outIdx++
-		today++
-	}
-	return outReal
-}
-
-// LinearRegAngle - Linear Regression Angle
-func LinearRegAngle(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	inTimePeriodF := float64(inTimePeriod)
-	lookbackTotal := inTimePeriod
-	startIdx := lookbackTotal
-	outIdx := startIdx - 1
-	today := startIdx - 1
-	sumX := inTimePeriodF * (inTimePeriodF - 1) * 0.5
-	sumXSqr := inTimePeriodF * (inTimePeriodF - 1) * (2*inTimePeriodF - 1) / 6
-	divisor := sumX*sumX - inTimePeriodF*sumXSqr
-	//initialize values of sumY and sumXY over first (inTimePeriod) input values
-	sumXY := 0.0
-	sumY := 0.0
-	i := inTimePeriod
-	for i != 0 {
-		i--
-		tempValue1 := inReal[today-i]
-		sumY += tempValue1
-		sumXY += float64(i) * tempValue1
-	}
-	for today < len(inReal) {
-		//sumX and sumXY are already available for first output value
-		if today > startIdx-1 {
-			tempValue2 := inReal[today-inTimePeriod]
-			sumXY += sumY - inTimePeriodF*tempValue2
-			sumY += inReal[today] - tempValue2
-		}
-		m := (inTimePeriodF*sumXY - sumX*sumY) / divisor
-		outReal[outIdx] = math.Atan(m) * (180.0 / math.Pi)
-		outIdx++
-		today++
-	}
-	return outReal
-}
-
-// LinearRegIntercept - Linear Regression Intercept
-func LinearRegIntercept(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	inTimePeriodF := float64(inTimePeriod)
-	lookbackTotal := inTimePeriod
-	startIdx := lookbackTotal
-	outIdx := startIdx - 1
-	today := startIdx - 1
-	sumX := inTimePeriodF * (inTimePeriodF - 1) * 0.5
-	sumXSqr := inTimePeriodF * (inTimePeriodF - 1) * (2*inTimePeriodF - 1) / 6
-	divisor := sumX*sumX - inTimePeriodF*sumXSqr
-	//initialize values of sumY and sumXY over first (inTimePeriod) input values
-	sumXY := 0.0
-	sumY := 0.0
-	i := inTimePeriod
-	for i != 0 {
-		i--
-		tempValue1 := inReal[today-i]
-		sumY += tempValue1
-		sumXY += float64(i) * tempValue1
-	}
-	for today < len(inReal) {
-		//sumX and sumXY are already available for first output value
-		if today > startIdx-1 {
-			tempValue2 := inReal[today-inTimePeriod]
-			sumXY += sumY - inTimePeriodF*tempValue2
-			sumY += inReal[today] - tempValue2
-		}
-		m := (inTimePeriodF*sumXY - sumX*sumY) / divisor
-		outReal[outIdx] = (sumY - m*sumX) / inTimePeriodF
-		outIdx++
-		today++
-	}
-	return outReal
-}
-
-// LinearRegSlope - Linear Regression Slope
-func LinearRegSlope(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	inTimePeriodF := float64(inTimePeriod)
-	lookbackTotal := inTimePeriod
-	startIdx := lookbackTotal
-	outIdx := startIdx - 1
-	today := startIdx - 1
-	sumX := inTimePeriodF * (inTimePeriodF - 1) * 0.5
-	sumXSqr := inTimePeriodF * (inTimePeriodF - 1) * (2*inTimePeriodF - 1) / 6
-	divisor := sumX*sumX - inTimePeriodF*sumXSqr
-	//initialize values of sumY and sumXY over first (inTimePeriod) input values
-	sumXY := 0.0
-	sumY := 0.0
-	i := inTimePeriod
-	for i != 0 {
-		i--
-		tempValue1 := inReal[today-i]
-		sumY += tempValue1
-		sumXY += float64(i) * tempValue1
-	}
-	for today < len(inReal) {
-		//sumX and sumXY are already available for first output value
-		if today > startIdx-1 {
-			tempValue2 := inReal[today-inTimePeriod]
-			sumXY += sumY - inTimePeriodF*tempValue2
-			sumY += inReal[today] - tempValue2
-		}
-		outReal[outIdx] = (inTimePeriodF*sumXY - sumX*sumY) / divisor
-		outIdx++
-		today++
-	}
-	return outReal
-}
-
-// StdDev - Standard Deviation
-func StdDev(inReal []float64, inTimePeriod int, inNbDev float64) []float64 {
-
-	outReal := Var(inReal, inTimePeriod)
-
-	if inNbDev != 1.0 {
-		for i := 0; i < len(inReal); i++ {
-			tempReal := outReal[i]
-			if !(tempReal < 0.00000000000001) {
-				outReal[i] = math.Sqrt(tempReal) * inNbDev
-			} else {
-				outReal[i] = 0.0
-			}
-		}
-	} else {
-		for i := 0; i < len(inReal); i++ {
-			tempReal := outReal[i]
-			if !(tempReal < 0.00000000000001) {
-				outReal[i] = math.Sqrt(tempReal)
-			} else {
-				outReal[i] = 0.0
-			}
-		}
-	}
-	return outReal
-}
-
-// Tsf - Time Series Forecast
-func Tsf(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	inTimePeriodF := float64(inTimePeriod)
-	lookbackTotal := inTimePeriod
-	startIdx := lookbackTotal
-	outIdx := startIdx - 1
-	today := startIdx - 1
-	sumX := inTimePeriodF * (inTimePeriodF - 1.0) * 0.5
-	sumXSqr := inTimePeriodF * (inTimePeriodF - 1) * (2*inTimePeriodF - 1) / 6
-	divisor := sumX*sumX - inTimePeriodF*sumXSqr
-	//initialize values of sumY and sumXY over first (inTimePeriod) input values
-	sumXY := 0.0
-	sumY := 0.0
-	i := inTimePeriod
-	for i != 0 {
-		i--
-		tempValue1 := inReal[today-i]
-		sumY += tempValue1
-		sumXY += float64(i) * tempValue1
-	}
-	for today < len(inReal) {
-		//sumX and sumXY are already available for first output value
-		if today > startIdx-1 {
-			tempValue2 := inReal[today-inTimePeriod]
-			sumXY += sumY - inTimePeriodF*tempValue2
-			sumY += inReal[today] - tempValue2
-		}
-		m := (inTimePeriodF*sumXY - sumX*sumY) / divisor
-		b := (sumY - m*sumX) / inTimePeriodF
-		outReal[outIdx] = b + m*inTimePeriodF
-		today++
-		outIdx++
-	}
-	return outReal
-}
-
-// Var - Variance
-func Var(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	nbInitialElementNeeded := inTimePeriod - 1
-	startIdx := nbInitialElementNeeded
-	periodTotal1 := 0.0
-	periodTotal2 := 0.0
-	trailingIdx := startIdx - nbInitialElementNeeded
-	i := trailingIdx
-	if inTimePeriod > 1 {
-		for i < startIdx {
-			tempReal := inReal[i]
-			periodTotal1 += tempReal
-			tempReal *= tempReal
-			periodTotal2 += tempReal
-			i++
-		}
-	}
-	outIdx := startIdx
-	for ok := true; ok; {
-		tempReal := inReal[i]
-		periodTotal1 += tempReal
-		tempReal *= tempReal
-		periodTotal2 += tempReal
-		meanValue1 := periodTotal1 / float64(inTimePeriod)
-		meanValue2 := periodTotal2 / float64(inTimePeriod)
-		tempReal = inReal[trailingIdx]
-		periodTotal1 -= tempReal
-		tempReal *= tempReal
-		periodTotal2 -= tempReal
-		outReal[outIdx] = meanValue2 - meanValue1*meanValue1
-		i++
-		trailingIdx++
-		outIdx++
-		ok = i < len(inReal)
-	}
-	return outReal
-}
-
-/* Math Transform Functions */
-
-// Acos - Vector Trigonometric ACOS
-func Acos(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Acos(inReal[i])
-	}
-	return outReal
-}
-
-// Asin - Vector Trigonometric ASIN
-func Asin(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Asin(inReal[i])
-	}
-	return outReal
-}
-
-// Atan - Vector Trigonometric ATAN
-func Atan(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Atan(inReal[i])
-	}
-	return outReal
-}
-
-// Ceil - Vector CEIL
-func Ceil(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Ceil(inReal[i])
-	}
-	return outReal
-}
-
-// Cos - Vector Trigonometric COS
-func Cos(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Cos(inReal[i])
-	}
-	return outReal
-}
-
-// Cosh - Vector Trigonometric COSH
-func Cosh(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Cosh(inReal[i])
-	}
-	return outReal
-}
-
-// Exp - Vector atrithmetic EXP
-func Exp(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Exp(inReal[i])
-	}
-	return outReal
-}
-
-// Floor - Vector FLOOR
-func Floor(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Floor(inReal[i])
-	}
-	return outReal
-}
-
-// Ln - Vector natural log LN
-func Ln(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Log(inReal[i])
-	}
-	return outReal
-}
-
-// Log10 - Vector LOG10
-func Log10(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Log10(inReal[i])
-	}
-	return outReal
-}
-
-// Sin - Vector Trigonometric SIN
-func Sin(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Sin(inReal[i])
-	}
-	return outReal
-}
-
-// Sinh - Vector Trigonometric SINH
-func Sinh(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Sinh(inReal[i])
-	}
-	return outReal
-}
-
-// Sqrt - Vector SQRT
-func Sqrt(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Sqrt(inReal[i])
-	}
-	return outReal
-}
-
-// Tan - Vector Trigonometric TAN
-func Tan(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Tan(inReal[i])
-	}
-	return outReal
-}
-
-// Tanh - Vector Trigonometric TANH
-func Tanh(inReal []float64) []float64 {
-	outReal := make([]float64, len(inReal))
-	for i := 0; i < len(inReal); i++ {
-		outReal[i] = math.Tanh(inReal[i])
-	}
-	return outReal
-}
-
-/* Math Operator Functions */
-
-// Add - Vector arithmetic addition
-func Add(inReal0 []float64, inReal1 []float64) []float64 {
-	outReal := make([]float64, len(inReal0))
-	for i := 0; i < len(inReal0); i++ {
-		outReal[i] = inReal0[i] + inReal1[i]
-	}
-	return outReal
-}
-
-// Div - Vector arithmetic division
-func Div(inReal0 []float64, inReal1 []float64) []float64 {
-	outReal := make([]float64, len(inReal0))
-	for i := 0; i < len(inReal0); i++ {
-		outReal[i] = inReal0[i] / inReal1[i]
-	}
-	return outReal
-}
-
-// Max - Highest value over a period
-func Max(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	if inTimePeriod < 2 {
-		return outReal
-	}
-
-	nbInitialElementNeeded := inTimePeriod - 1
-	startIdx := nbInitialElementNeeded
-	outIdx := startIdx
-	today := startIdx
-	trailingIdx := startIdx - nbInitialElementNeeded
-	highestIdx := -1
-	highest := 0.0
-
-	for today < len(outReal) {
-
-		tmp := inReal[today]
-
-		if highestIdx < trailingIdx {
-			highestIdx = trailingIdx
-			highest = inReal[highestIdx]
-			i := highestIdx + 1
-			for i <= today {
-				tmp = inReal[i]
-				if tmp > highest {
-					highestIdx = i
-					highest = tmp
-				}
-				i++
-			}
-		} else if tmp >= highest {
-			highestIdx = today
-			highest = tmp
-		}
-		outReal[outIdx] = highest
-		outIdx++
-		trailingIdx++
-		today++
-	}
-
-	return outReal
-}
-
-// MaxIndex - Index of highest value over a specified period
-func MaxIndex(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	if inTimePeriod < 2 {
-		return outReal
-	}
-
-	nbInitialElementNeeded := inTimePeriod - 1
-	startIdx := nbInitialElementNeeded
-	outIdx := startIdx
-	today := startIdx
-	trailingIdx := startIdx - nbInitialElementNeeded
-	highestIdx := -1
-	highest := 0.0
-	for today < len(inReal) {
-		tmp := inReal[today]
-		if highestIdx < trailingIdx {
-			highestIdx = trailingIdx
-			highest = inReal[highestIdx]
-			i := highestIdx + 1
-			for i <= today {
-				tmp := inReal[i]
-				if tmp > highest {
-					highestIdx = i
-					highest = tmp
-				}
-				i++
-			}
-		} else if tmp >= highest {
-			highestIdx = today
-			highest = tmp
-		}
-		outReal[outIdx] = float64(highestIdx)
-		outIdx++
-		trailingIdx++
-		today++
-	}
-
-	return outReal
-}
-
-// Min - Lowest value over a period
-func Min(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	if inTimePeriod < 2 {
-		return outReal
-	}
-
-	nbInitialElementNeeded := inTimePeriod - 1
-	startIdx := nbInitialElementNeeded
-	outIdx := startIdx
-	today := startIdx
-	trailingIdx := startIdx - nbInitialElementNeeded
-	lowestIdx := -1
-	lowest := 0.0
-	for today < len(outReal) {
-
-		tmp := inReal[today]
-
-		if lowestIdx < trailingIdx {
-			lowestIdx = trailingIdx
-			lowest = inReal[lowestIdx]
-			i := lowestIdx + 1
-			for i <= today {
-				tmp = inReal[i]
-				if tmp < lowest {
-					lowestIdx = i
-					lowest = tmp
-				}
-				i++
-			}
-		} else if tmp <= lowest {
-			lowestIdx = today
-			lowest = tmp
-		}
-		outReal[outIdx] = lowest
-		outIdx++
-		trailingIdx++
-		today++
-	}
-
-	return outReal
-}
-
-// MinIndex - Index of lowest value over a specified period
-func MinIndex(inReal []float64, inTimePeriod int) []float64 {
-
-	outReal := make([]float64, len(inReal))
-
-	if inTimePeriod < 2 {
-		return outReal
-	}
-
-	nbInitialElementNeeded := inTimePeriod - 1
-	startIdx := nbInitialElementNeeded
-	outIdx := startIdx
-	today := startIdx
-	trailingIdx := startIdx - nbInitialElementNeeded
-	lowestIdx := -1
-	lowest := 0.0
-	for today < len(inReal) {
-		tmp := inReal[today]
-		if lowestIdx < trailingIdx {
-			lowestIdx = trailingIdx
-			lowest = inReal[lowestIdx]
-			i := lowestIdx + 1
-			for i <= today {
-				tmp = inReal[i]
-				if tmp < lowest {
-					lowestIdx = i
-					lowest = tmp
-				}
-				i++
-			}
-		} else if tmp <= lowest {
-			lowestIdx = today
-			lowest = tmp
-		}
-		outReal[outIdx] = float64(lowestIdx)
-		outIdx++
-		trailingIdx++
-		today++
-	}
-	return outReal
-}
-
-// MinMax - Lowest and highest values over a specified period
-func MinMax(inReal []float64, inTimePeriod int) ([]float64, []float64) {
-
-	outMin := make([]float64, len(inReal))
-	outMax := make([]float64, len(inReal))
-
-	nbInitialElementNeeded := (inTimePeriod - 1)
-	startIdx := nbInitialElementNeeded
-	outIdx := startIdx
-	today := startIdx
-	trailingIdx := startIdx - nbInitialElementNeeded
-	highestIdx := -1
-	highest := 0.0
-	lowestIdx := -1
-	lowest := 0.0
-	for today < len(inReal) {
-		tmpLow, tmpHigh := inReal[today], inReal[today]
-		if highestIdx < trailingIdx {
-			highestIdx = trailingIdx
-			highest = inReal[highestIdx]
-			i := highestIdx
-			i++
-			for i <= today {
-				tmpHigh = inReal[i]
-				if tmpHigh > highest {
-					highestIdx = i
-					highest = tmpHigh
-				}
-				i++
-			}
-		} else if tmpHigh >= highest {
-			highestIdx = today
-			highest = tmpHigh
-		}
-		if lowestIdx < trailingIdx {
-			lowestIdx = trailingIdx
-			lowest = inReal[lowestIdx]
-			i := lowestIdx
-			i++
-			for i <= today {
-				tmpLow = inReal[i]
-				if tmpLow < lowest {
-					lowestIdx = i
-					lowest = tmpLow
-				}
-				i++
-			}
-		} else if tmpLow <= lowest {
-			lowestIdx = today
-			lowest = tmpLow
-		}
-		outMax[outIdx] = highest
-		outMin[outIdx] = lowest
-		outIdx++
-		trailingIdx++
-		today++
-	}
-	return outMin, outMax
-}
-
-// MinMaxIndex - Indexes of lowest and highest values over a specified period
-func MinMaxIndex(inReal []float64, inTimePeriod int) ([]float64, []float64) {
-
-	outMinIdx := make([]float64, len(inReal))
-	outMaxIdx := make([]float64, len(inReal))
-
-	nbInitialElementNeeded := (inTimePeriod - 1)
-	startIdx := nbInitialElementNeeded
-	outIdx := startIdx
-	today := startIdx
-	trailingIdx := startIdx - nbInitialElementNeeded
-	highestIdx := -1
-	highest := 0.0
-	lowestIdx := -1
-	lowest := 0.0
-	for today < len(inReal) {
-		tmpLow, tmpHigh := inReal[today], inReal[today]
-		if highestIdx < trailingIdx {
-			highestIdx = trailingIdx
-			highest = inReal[highestIdx]
-			i := highestIdx
-			i++
-			for i <= today {
-				tmpHigh = inReal[i]
-				if tmpHigh > highest {
-					highestIdx = i
-					highest = tmpHigh
-				}
-				i++
-			}
-		} else if tmpHigh >= highest {
-			highestIdx = today
-			highest = tmpHigh
-		}
-		if lowestIdx < trailingIdx {
-			lowestIdx = trailingIdx
-			lowest = inReal[lowestIdx]
-			i := lowestIdx
-			i++
-			for i <= today {
-				tmpLow = inReal[i]
-				if tmpLow < lowest {
-					lowestIdx = i
-					lowest = tmpLow
-				}
-				i++
-			}
-		} else if tmpLow <= lowest {
-			lowestIdx = today
-			lowest = tmpLow
-		}
-		outMaxIdx[outIdx] = float64(highestIdx)
-		outMinIdx[outIdx] = float64(lowestIdx)
-		outIdx++
-		trailingIdx++
-		today++
-	}
-	return outMinIdx, outMaxIdx
-}
-
-// Mult - Vector arithmetic multiply
-func Mult(inReal0 []float64, inReal1 []float64) []float64 {
-	outReal := make([]float64, len(inReal0))
-	for i := 0; i < len(inReal0); i++ {
-		outReal[i] = inReal0[i] * inReal1[i]
-	}
-	return outReal
-}
-
-// Sub - Vector arithmetic subtraction
-func Sub(inReal0 []float64, inReal1 []float64) []float64 {
-	outReal := make([]float64, len(inReal0))
-	for i := 0; i < len(inReal0); i++ {
-		outReal[i] = inReal0[i] - inReal1[i]
-	}
-	return outReal
-}
-
-// Sum - Vector summation
-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
-}
-
-// HeikinashiCandles - from candle values extracts heikinashi candle values.
-//
-// Returns highs, opens, closes and lows of the heikinashi candles (in this order).
-//
-//	NOTE: The number of Heikin-Ashi candles will always be one less than the number of provided candles, due to the fact
-//	      that a previous candle is necessary to calculate the Heikin-Ashi candle, therefore the first provided candle is not considered
-//	      as "current candle" in the algorithm, but only as "previous candle".
-func HeikinashiCandles(highs []float64, opens []float64, closes []float64, lows []float64) ([]float64, []float64, []float64, []float64) {
-	N := len(highs)
-
-	heikinHighs := make([]float64, N)
-	heikinOpens := make([]float64, N)
-	heikinCloses := make([]float64, N)
-	heikinLows := make([]float64, N)
-
-	for currentCandle := 1; currentCandle < N; currentCandle++ {
-		previousCandle := currentCandle - 1
-
-		heikinHighs[currentCandle] = math.Max(highs[currentCandle], math.Max(opens[currentCandle], closes[currentCandle]))
-		heikinOpens[currentCandle] = (opens[previousCandle] + closes[previousCandle]) / 2
-		heikinCloses[currentCandle] = (highs[currentCandle] + opens[currentCandle] + closes[currentCandle] + lows[currentCandle]) / 4
-		heikinLows[currentCandle] = math.Min(highs[currentCandle], math.Min(opens[currentCandle], closes[currentCandle]))
-	}
-
-	return heikinHighs, heikinOpens, heikinCloses, heikinLows
-}
-
-// Hlc3 returns the Hlc3 values
-//
-//	NOTE: Every Hlc item is defined as follows : (high + low + close) / 3
-//	      It is used as AvgPrice candle.
-func Hlc3(highs []float64, lows []float64, closes []float64) []float64 {
-	N := len(highs)
-	result := make([]float64, N)
-	for i := range highs {
-		result[i] = (highs[i] + lows[i] + closes[i]) / 3
-	}
-
-	return result
-}
-
-// Crossover returns true if series1 is crossing over series2.
-//
-//	NOTE: Usually this is used with Media Average Series to check if it crosses for buy signals.
-//	      It assumes first values are the most recent.
-//	      The crossover function does not use most recent value, since usually it's not a complete candle.
-//	      The second recent values and the previous are used, instead.
-func Crossover(series1 []float64, series2 []float64) bool {
-	if len(series1) < 3 || len(series2) < 3 {
-		return false
-	}
-
-	N := len(series1)
-
-	return series1[N-2] <= series2[N-2] && series1[N-1] > series2[N-1]
-}
-
-// Crossunder returns true if series1 is crossing under series2.
-//
-//	NOTE: Usually this is used with Media Average Series to check if it crosses for sell signals.
-func Crossunder(series1 []float64, series2 []float64) bool {
-	if len(series1) < 3 || len(series2) < 3 {
-		return false
-	}
-
-	N := len(series1)
-
-	return series1[N-1] <= series2[N-1] && series1[N-2] > series2[N-2]
-}
-
-// GroupCandles groups a set of candles in another set of candles, basing on a grouping factor.
-//
-// This is pretty useful if you want to transform, for example, 15min candles into 1h candles using same data.
-//
-// This avoid calling multiple times the exchange for multiple contexts.
-//
-// Example:
-//
-//	To transform 15 minute candles in 30 minutes candles you have a grouping factor = 2
-//
-//	To transform 15 minute candles in 1 hour candles you have a grouping factor = 4
-//
-//	To transform 30 minute candles in 1 hour candles you have a grouping factor = 2
-func GroupCandles(highs []float64, opens []float64, closes []float64, lows []float64, groupingFactor int) ([]float64, []float64, []float64, []float64, error) {
-	N := len(highs)
-	if groupingFactor == 0 {
-		return nil, nil, nil, nil, errors.New("Grouping factor must be > 0")
-	} else if groupingFactor == 1 {
-		return highs, opens, closes, lows, nil // no need to group in this case, return the parameters.
-	}
-	if N%groupingFactor > 0 {
-		return nil, nil, nil, nil, errors.New("Cannot group properly, need a groupingFactor which is a factor of the number of candles")
-	}
-
-	groupedN := N / groupingFactor
-
-	groupedHighs := make([]float64, groupedN)
-	groupedOpens := make([]float64, groupedN)
-	groupedCloses := make([]float64, groupedN)
-	groupedLows := make([]float64, groupedN)
-
-	lastOfCurrentGroup := groupingFactor - 1
-
-	k := 0
-	for i := 0; i < N; i += groupingFactor { // scan all param candles
-		groupedOpens[k] = opens[i]
-		groupedCloses[k] = closes[i+lastOfCurrentGroup]
-
-		groupedHighs[k] = highs[i]
-		groupedLows[k] = lows[i]
-
-		endOfCurrentGroup := i + lastOfCurrentGroup
-		for j := i + 1; j <= endOfCurrentGroup; j++ { // group high lows candles here
-			if lows[j] < groupedLows[k] {
-				groupedLows[k] = lows[j]
-			}
-			if highs[j] > groupedHighs[k] {
-				groupedHighs[k] = highs[j]
-			}
-		}
-		k++
-	}
-	return groupedHighs, groupedOpens, groupedCloses, groupedLows, nil
-}