def RunTradingModelBuyHold(ticker: str,
                           startDate: str,
                           durationInYears: int,
                           totalFunds: int,
                           verbose: bool = False,
                           saveHistoryToFile: bool = True,
                           returndailyValues: bool = False):
    modelName = 'BuyHold' + '_' + ticker
    tm = TradingModel(modelName, ticker, startDate, durationInYears,
                      totalFunds, verbose)
    if not tm.modelReady:
        print('Unable to initialize price history for model for ' +
              str(startDate))
        if returndailyValues: return pandas.DataFrame()
        else: return totalFunds
    else:
        while not tm.ModelCompleted():
            tm.ProcessDay()
            currentPrices = tm.GetPriceSnapshot()
            if not currentPrices == None:
                if tm.TraunchesAvailable(
                ) and tm.FundsAvailable() > currentPrices.high:
                    tm.PlaceBuy(ticker, currentPrices.low, True)
            if tm.AccountingError(): break
        if returndailyValues:
            tm.CloseModel(verbose, saveHistoryToFile)
            return tm.GetdailyValue()  #return daily value
        else:
            return tm.CloseModel(verbose,
                                 saveHistoryToFile)  #return closing value
def RunTradingModelQLearn(ticker: str,
                          startDate: str,
                          durationInYears: int,
                          totalFunds: int,
                          verbose: bool = False,
                          saveHistoryToFile: bool = True,
                          returndailyValues: bool = False):
    Actions = [
        'Hold', 'BuyMarket', 'BuyAgressiveLeve10', 'BuyAgressiveLeve11',
        'BuyAgressiveLeve12', 'SellMarket', 'SellAgressiveLeve10',
        'SellAgressiveLeve11', 'SellAgressiveLeve12'
    ]
    modelName = 'QLearn' + '_' + ticker
    tm = TradingModel(modelName, ticker, startDate, durationInYears,
                      totalFunds, verbose)
    if not tm.modelReady:
        print('Unable to initialize price history for model for ' +
              str(startDate))
        if returndailyValues: return pandas.DataFrame()
        else: return totalFunds
    else:
        while not tm.ModelCompleted():
            tm.ProcessDay()
            currentPrices = tm.GetPriceSnapshot()
            if not currentPrices == None:
                pass
                #do stuff
        if returndailyValues:
            tm.CloseModel(verbose, saveHistoryToFile)
            return tm.GetdailyValue()  #return daily value
        else:
            return tm.CloseModel(verbose,
                                 saveHistoryToFile)  #return closing value
def RunTradingModelSeasonal(ticker: str,
                            startDate: str,
                            durationInYears: int,
                            totalFunds: int,
                            verbose: bool = False,
                            saveHistoryToFile: bool = True,
                            returndailyValues: bool = False):
    modelName = 'Seasonal' + '_' + ticker
    tm = TradingModel(modelName, ticker, startDate, durationInYears,
                      totalFunds, verbose)
    if not tm.modelReady:
        print('Unable to initialize price history for model for ' +
              str(startDate))
        if returndailyValues: return pandas.DataFrame()
        else: return totalFunds
    else:
        while not tm.ModelCompleted():
            tm.ProcessDay()
            currentPrices = tm.GetPriceSnapshot()
            if not currentPrices == None:
                low = currentPrices.low
                high = currentPrices.high
                m = tm.currentDate.month
                available, buyPending, sellPending, longPositions = tm.GetPositionSummary(
                )
                if m >= 11 or m <= 4:  #Buy if Nov through April, else sell
                    if available > 0 and tm.FundsAvailable() > high:
                        tm.PlaceBuy(ticker, low, True)
                else:
                    if longPositions > 0: tm.PlaceSell(ticker, high, True)
            if tm.AccountingError(): break
        if returndailyValues:
            tm.CloseModel(verbose, saveHistoryToFile)
            return tm.GetdailyValue()  #return daily value
        else:
            return tm.CloseModel(verbose,
                                 saveHistoryToFile)  #return closing value
def RunTradingModelSwingTrend(ticker: str,
                              startDate: str,
                              durationInYears: int,
                              totalFunds: int,
                              verbose: bool = False,
                              saveHistoryToFile: bool = True,
                              returndailyValues: bool = False):
    #Give it a date range, some money, and a stock, it will execute a strategy and return the results
    #minDeviationToTrade = .025
    minActionableSlope = 0.002
    trendState = 'Flat'  #++,--,+-,-+,Flat
    prevTrendState = ''
    trendDuration = 0

    modelName = 'SwingTrend' + '_' + ticker
    tm = TradingModel(modelName, ticker, startDate, durationInYears,
                      totalFunds, verbose)
    if not tm.modelReady:
        print('Unable to initialize price history for model for ' +
              str(startDate))
        if returndailyValues: return pandas.DataFrame()
        else: return totalFunds
    else:
        while not tm.ModelCompleted():
            tm.ProcessDay()
            p = tm.GetPriceSnapshot()
            if not p == None:
                available, buyPending, sellPending, longPositions = tm.GetPositionSummary(
                )
                maxPositions = available + buyPending + sellPending + longPositions
                targetBuy = p.nextDayTarget * (1 + p.fiveDayDeviation / 2)
                targetSell = p.nextDayTarget * (1 - p.fiveDayDeviation / 2)
                if p.longEMASlope >= minActionableSlope and p.shortEMASlope >= minActionableSlope:  #++	Positive trend, 70% long
                    trendState = '++'
                    if p.low > p.channelHigh:  #Over Bought
                        if sellPending < 3 and longPositions > 7:
                            tm.PlaceSell(ticker, targetSell * (1.03), False,
                                         10)
                    elif p.low < p.channelLow:  #Still early
                        if buyPending < 3 and longPositions < 6:
                            tm.PlaceBuy(ticker, targetBuy, True)
                        if trendDuration > 1 and buyPending < 3:
                            tm.PlaceBuy(ticker, targetBuy, True)
                    else:
                        if buyPending < 3 and longPositions < 6:
                            tm.PlaceBuy(ticker, targetBuy, False)
                    if buyPending < 5 and longPositions < maxPositions:
                        tm.PlaceBuy(ticker, targetBuy, False)
                elif p.longEMASlope >= minActionableSlope and p.shortEMASlope < minActionableSlope:  #+- Correction or early downturn
                    trendState = '+-'
                    if p.low > p.channelHigh:  #Over Bought, try to get out
                        if sellPending < 3 and longPositions > 7:
                            tm.PlaceSell(ticker, targetSell, False, 3)
                    elif p.low < p.channelLow and p.high > p.channelLow:  #Deep correction
                        if sellPending < 3 and longPositions > 7:
                            tm.PlaceSell(ticker, targetSell, False, 3)
                    else:
                        pass
                elif p.longEMASlope < -minActionableSlope and p.shortEMASlope < -minActionableSlope:  #-- Negative trend, aim for < 30% long
                    trendState = '--'
                    if p.high < p.channelLow:  #Over sold
                        if buyPending < 3 and longPositions < 6:
                            tm.PlaceBuy(ticker, targetBuy * .95, False, 2)
                    elif p.low < p.channelLow and p.high > p.channelLow:  #Straddle Low, early down or up
                        pass
                    else:
                        if sellPending < 5 and longPositions > 3:
                            tm.PlaceSell(ticker, targetSell, True)
                            if trendDuration > 1:
                                tm.PlaceSell(ticker, targetSell, True)
                    if sellPending < 5 and longPositions > 3:
                        tm.PlaceSell(ticker, targetSell, False, 2)
                        tm.PlaceSell(ticker, targetSell, False, 2)
                elif p.longEMASlope < (
                        -1 * minActionableSlope) and p.shortEMASlope < (
                            -1 *
                            minActionableSlope):  #-+ Bounce or early recovery
                    trendState = '-+'
                    if p.high < p.channelLow:  #Over sold
                        pass
                    elif p.low < p.channelLow and p.high > p.channelLow:  #Straddle Low
                        if sellPending < 3 and longPositions > 3:
                            tm.PlaceSell(ticker, targetSell, False, 3)
                    else:
                        pass
                else:  #flat, aim for 70% long
                    trendState = 'Flat'
                    if p.low > p.channelHigh:  #Over Bought
                        if sellPending < 3 and longPositions > 7:
                            tm.PlaceSell(ticker, targetSell * (1.03), False,
                                         10)
                    elif p.high < p.channelLow:  #Over sold
                        if buyPending < 3 and longPositions < 8:
                            tm.PlaceBuy(ticker, targetBuy, False, 5)
                        if buyPending < 4:
                            tm.PlaceBuy(ticker, targetBuy, False, 5)
                    else:
                        pass
                    if sellPending < 3 and longPositions > 7:
                        tm.PlaceSell(ticker, targetSell, False, 5)
                    if buyPending < 3 and longPositions < maxPositions:
                        tm.PlaceBuy(ticker, targetBuy, False, 5)
                if trendState == prevTrendState:
                    trendDuration = trendDuration + 1
                else:
                    trendDuration = 0
            if tm.AccountingError(): break
        if returndailyValues:
            tm.CloseModel(verbose, saveHistoryToFile)
            return tm.GetdailyValue()  #return daily value
        else:
            return tm.CloseModel(verbose,
                                 saveHistoryToFile)  #return closing value