// NewMfiForStream creates a Money Flow Index Indicator (Mfi) for online usage with a source data stream
172974
func NewMfiForStream(priceStream gotrade.DOHLCVStreamSubscriber, timePeriod int) (indicator *Mfi, err error) {
	ind, err := NewMfi(timePeriod)
	priceStream.AddTickSubscription(ind)
	return ind, err
}
119348
func NewPlusDmForStreamWithSrcLen(sourceLength uint, priceStream gotrade.DOHLCVStreamSubscriber, timePeriod int) (indicator *PlusDm, err error) {
	ind, err := NewPlusDmWithSrcLen(sourceLength, timePeriod)
	priceStream.AddTickSubscription(ind)
	return ind, err
}
90149
func NewDefaultLinRegSlpForStream(priceStream gotrade.DOHLCVStreamSubscriber) (indicator *LinRegSlp, err error) {
	ind, err := NewDefaultLinRegSlp()
	priceStream.AddTickSubscription(ind)
	return ind, err
}
943985
func NewDefaultCciForStreamWithSrcLen(sourceLength uint, priceStream gotrade.DOHLCVStreamSubscriber) (indicator *Cci, err error) {
	ind, err := NewDefaultCciWithSrcLen(sourceLength)
	priceStream.AddTickSubscription(ind)
	return ind, err
}
551884
func NewDefaultMinusDiForStreamWithSrcLen(sourceLength uint, priceStream gotrade.DOHLCVStreamSubscriber) (indicator *MinusDi, err error) {
	ind, err := NewDefaultMinusDiWithSrcLen(sourceLength)
	priceStream.AddTickSubscription(ind)
	return ind, err
}
1012365
func NewDefaultPlusDmForStreamWithSrcLen(sourceLength uint, priceStream gotrade.DOHLCVStreamSubscriber) (indicator *PlusDm, err error) {
	ind, err := NewDefaultPlusDmWithSrcLen(sourceLength)
	priceStream.AddTickSubscription(ind)
	return ind, err
}
1191511
func NewMomForStream(priceStream gotrade.DOHLCVStreamSubscriber, timePeriod int, selectData gotrade.DOHLCVDataSelectionFunc) (indicator *Mom, err error) {
	newMom, err := NewMom(timePeriod, selectData)
	priceStream.AddTickSubscription(newMom)
	return newMom, err
}
316233
func NewDefaultWillRForStreamWithSrcLen(sourceLength uint, priceStream gotrade.DOHLCVStreamSubscriber) (indicator *WillR, err error) {
	ind, err := NewDefaultWillRWithSrcLen(sourceLength)
	priceStream.AddTickSubscription(ind)
	return ind, err
}
443370
func NewDefaultLinRegAngForStream(priceStream gotrade.DOHLCVStreamSubscriber) (indicator *LinRegAng, err error) {
	ind, err := NewDefaultLinRegAng()
	priceStream.AddTickSubscription(ind)
	return ind, err
}
1169347
func NewDefaultMomForStreamWithSrcLen(sourceLength uint, priceStream gotrade.DOHLCVStreamSubscriber) (indicator *Mom, err error) {
	ind, err := NewDefaultMomWithSrcLen(sourceLength)
	priceStream.AddTickSubscription(ind)
	return ind, err
}
1157217
func NewMfiWithoutStorage(timePeriod int, valueAvailableAction ValueAvailableActionFloat) (indicator *MfiWithoutStorage, err error) {

	// an indicator without storage MUST have a value available action
	if valueAvailableAction == nil {
		return nil, ErrValueAvailableActionIsNil
	}

	// the minimum timeperiod for this indicator is 2
	if timePeriod < 2 {
		return nil, errors.New("timePeriod is less than the minimum (2)")
	}

	// check the maximum timeperiod
	if timePeriod > MaximumLookbackPeriod {
		return nil, errors.New("timePeriod is greater than the maximum (100000)")
	}

	lookback := timePeriod
	ind := MfiWithoutStorage{
		baseIndicatorWithFloatBounds: newBaseIndicatorWithFloatBounds(lookback, valueAvailableAction),
		periodCounter:                (timePeriod * -1) - 1,
		positiveHistory:              list.New(),
		negativeHistory:              list.New(),
		positiveMoneyFlow:            0.0,
		negativeMoneyFlow:            0.0,
		currentVolume:                0.0,
		previousTypPrice:             0.0,
		timePeriod:                   timePeriod,
	}

	ind.typicalPrice, err = NewTypPriceWithoutStorage(func(dataItem float64, streamBarIndex int) {
		ind.periodCounter += 1

		if ind.periodCounter > (ind.timePeriod * -1) {
			moneyFlow := dataItem * ind.currentVolume

			if ind.periodCounter <= 0 {
				if dataItem > ind.previousTypPrice {
					ind.positiveMoneyFlow += moneyFlow
					ind.positiveHistory.PushBack(moneyFlow)
					ind.negativeHistory.PushBack(0.0)
				} else if dataItem < ind.previousTypPrice {
					ind.negativeMoneyFlow += moneyFlow
					ind.positiveHistory.PushBack(0.0)
					ind.negativeHistory.PushBack(moneyFlow)
				} else {
					ind.positiveHistory.PushBack(0.0)
					ind.negativeHistory.PushBack(0.0)
				}
			}

			if ind.periodCounter == 0 {

				result := 100.0 * (ind.positiveMoneyFlow / (ind.positiveMoneyFlow + ind.negativeMoneyFlow))

				ind.UpdateIndicatorWithNewValue(result, streamBarIndex)
			}
			if ind.periodCounter > 0 {
				firstPositive := ind.positiveHistory.Front().Value.(float64)
				ind.positiveMoneyFlow -= firstPositive

				firstNegative := ind.negativeHistory.Front().Value.(float64)
				ind.negativeMoneyFlow -= firstNegative

				if dataItem > ind.previousTypPrice {
					ind.positiveMoneyFlow += moneyFlow
					ind.positiveHistory.PushBack(moneyFlow)
					ind.negativeHistory.PushBack(0.0)
				} else if dataItem < ind.previousTypPrice {
					ind.negativeMoneyFlow += moneyFlow
					ind.positiveHistory.PushBack(0.0)
					ind.negativeHistory.PushBack(moneyFlow)
				} else {
					ind.positiveHistory.PushBack(0.0)
					ind.negativeHistory.PushBack(0.0)
				}

				result := 100.0 * (ind.positiveMoneyFlow / (ind.positiveMoneyFlow + ind.negativeMoneyFlow))

				ind.UpdateIndicatorWithNewValue(result, streamBarIndex)
			}

		}
		ind.previousTypPrice = dataItem

		if ind.positiveHistory.Len() > ind.timePeriod {
			first := ind.positiveHistory.Front()
			ind.positiveHistory.Remove(first)
		}

		if ind.negativeHistory.Len() > ind.timePeriod {
			first := ind.negativeHistory.Front()
			ind.negativeHistory.Remove(first)
		}
	})

	return &ind, err
}
339377
func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) {
	return cc.NewStream(ctx, desc, method, opts...)
}
1044214
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
}
767305
func NewDefaultPlusDiForStreamWithSrcLen(sourceLength uint, priceStream gotrade.DOHLCVStreamSubscriber) (indicator *PlusDi, err error) {
	ind, err := NewDefaultPlusDiWithSrcLen(sourceLength)
	priceStream.AddTickSubscription(ind)
	return ind, err
}
732997
func NewDefaultWmaForStream(priceStream gotrade.DOHLCVStreamSubscriber) (indicator *Wma, err error) {
	ind, err := NewDefaultWma()
	priceStream.AddTickSubscription(ind)
	return ind, err
}
713565
func NewEmaForStreamWithSrcLen(sourceLength uint, priceStream gotrade.DOHLCVStreamSubscriber, timePeriod int, selectData gotrade.DOHLCVDataSelectionFunc) (indicator *Ema, err error) {
	ind, err := NewEmaWithSrcLen(sourceLength, timePeriod, selectData)
	priceStream.AddTickSubscription(ind)
	return ind, err
}
314823
func NewMacdForStream(priceStream gotrade.DOHLCVStreamSubscriber, fastTimePeriod int, slowTimePeriod int, signalTimePeriod int, selectData gotrade.DOHLCVDataSelectionFunc) (indicator *Macd, err error) {
	ind, err := NewMacd(fastTimePeriod, slowTimePeriod, signalTimePeriod, selectData)
	priceStream.AddTickSubscription(ind)
	return ind, err
}