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 RunTradingModelBuyHold(tm: TradingModel, ticker: str): currentPrices = tm.GetPriceSnapshot() if tm.verbose: print(currentPrices.snapShotDate, currentPrices.nextDayTarget) if not currentPrices == None: if tm.TranchesAvailable() > 0 and tm.FundsAvailable( ) > currentPrices.high: tm.PlaceBuy(ticker, currentPrices.low, True)
def RunTradingModelBuyHold(tm: TradingModel, ticker: str): #Baseline model, buy and hold currentPrices = tm.GetPriceSnapshot() if tm.verbose: print(currentPrices.snapShotDate, currentPrices.nextDayTarget) if not currentPrices == None: for i in range(tm._tranchCount): available, buyPending, sellPending, longPositions = tm.PositionSummary( ) if tm.TranchesAvailable() > 0 and tm.FundsAvailable( ) > currentPrices.high: tm.PlaceBuy(ticker, currentPrices.low, True) if available == 0: break
def RunTradingModelSeasonal(tm: TradingModel, ticker: str): SellMonth = 4 #April BuyMonth = 10 #October currentPrices = tm.GetPriceSnapshot() if not currentPrices == None: low = currentPrices.low high = currentPrices.high m = tm.currentDate.month available, buyPending, sellPending, longPositions = tm.PositionSummary( ) if m >= SellMonth and m <= BuyMonth: if longPositions > 0: tm.PlaceSell(ticker, high, True) else: if available > 0 and tm.FundsAvailable() > high: tm.PlaceBuy(ticker, low, True)
def RunTradingModelSeasonal(tm: TradingModel, ticker: str): #Buy in November, sell in May SellMonth = 5 BuyMonth = 11 currentPrices = tm.GetPriceSnapshot() if not currentPrices == None: low = currentPrices.low high = currentPrices.high m = tm.currentDate.month for i in range(tm._tranchCount): available, buyPending, sellPending, longPositions = tm.PositionSummary( ) if m >= SellMonth and m <= BuyMonth: if longPositions > 0: tm.PlaceSell(ticker, high, True) else: break else: if available > 0 and tm.FundsAvailable() > high: tm.PlaceBuy(ticker, low, True) else: break
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 RunTradingModelFirstHalfOfMonth(tm: TradingModel, ticker: str): #From Robert Ariel's observations, most gains are in the first half of the month BuyDay = 25 #Buy at the end of the month, after the 25th SellDay = 15 #Sell mid month, after the 15th currentPrices = tm.GetPriceSnapshot() if not currentPrices == None: low = currentPrices.low high = currentPrices.high d = tm.currentDate.day for i in range(tm._tranchCount): available, buyPending, sellPending, longPositions = tm.PositionSummary( ) if d >= BuyDay or d < 3: if available > 0 and tm.FundsAvailable() > high: tm.PlaceBuy(ticker, low, True) else: break elif d >= SellDay: if longPositions > 0: tm.PlaceSell(ticker, high, True) else: break else: break
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
def RunTradingModelSwingTrend(tm: TradingModel, ticker: str): #Combines trending model with targeted "swing" buys, attempting to gain better deals by anticipating daily price fluctuations minActionableSlope = 0.002 prevTrendState, trendDuration = tm.GetCustomValues() if prevTrendState == None: prevTrendState = '' if trendDuration == None: trendDuration = 0 p = tm.GetPriceSnapshot() if not p == None: for i in range(tm._tranchCount): available, buyPending, sellPending, longPositions = tm.PositionSummary( ) 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 tm.SetCustomValues(prevTrendState, trendDuration)
def RunTradingModelTrending(tm: TradingModel, ticker: str): #This compares the slope of short term (6 day) and long term (18 day) exponential moving averages to determine buying opportunities. Positive, negative, or flat slopes #trend states: ++,--,+-,-+,Flat minActionableSlope = 0.002 prevTrendState, trendDuration = tm.GetCustomValues() if prevTrendState == None: prevTrendState = '' if trendDuration == None: trendDuration = 0 p = tm.GetPriceSnapshot() if not p == None: available, buyPending, sellPending, longPositions = tm.PositionSummary( ) maxPositions = available + buyPending + sellPending + longPositions targetBuy = p.nextDayTarget * (1 + p.fiveDayDeviation / 2) targetSell = p.nextDayTarget * (1 - p.fiveDayDeviation / 2) for i in range(tm._tranchCount): if p.longEMASlope >= minActionableSlope and p.shortEMASlope >= minActionableSlope: #++ Positive trend, 100% long trendState = '++' if p.low > p.channelHigh: #Over Bought pass 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, True) if buyPending < 5 and longPositions < maxPositions: tm.PlaceBuy(ticker, targetBuy, False, 3) 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 * .98, 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, get out 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, possible early up pass else: if trendDuration > 2: if sellPending < 5 and longPositions > 5: tm.PlaceSell(ticker, targetSell, True) if sellPending < 5 and longPositions > 0: 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 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 if buyPending < 3 and longPositions < 6: tm.PlaceBuy(ticker, targetBuy * .95, False, 2) else: pass else: #flat, aim for 70% long trendState = 'Flat' if p.low > p.channelHigh: #Over Bought pass 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 buyPending < 3 and longPositions < maxPositions: tm.PlaceBuy(ticker, targetBuy, False, 5) tm.SetCustomValues(trendState, trendDuration) if trendState == prevTrendState: trendDuration = trendDuration + 1 else: trendDuration = 0 tm.SetCustomValues(prevTrendState, trendDuration)
def RunTradingModelSwingTrend(tm: TradingModel, ticker: str): #Give it a date range, some money, and a stock, it will execute a strategy and return the results #minDeviationToTrade = .025 minActionableSlope = 0.002 prevTrendState, trendDuration = tm.GetCustomValues() if prevTrendState == None: prevTrendState = '' if trendDuration == None: trendDuration = 0 p = tm.GetPriceSnapshot() if not p == None: available, buyPending, sellPending, longPositions = tm.PositionSummary( ) 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 tm.SetCustomValues(prevTrendState, trendDuration)