Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
from clr import AddReference AddReference("QuantConnect.Research") #clr.AddReference('QuantConnect.Research') from QuantConnect.Research import QuantBook import statistics import pandas as pd import numpy as np import math import time as tm from sklearn.linear_model import LinearRegression import statsmodels.formula.api as smf import statsmodels.api as sm import copy from scipy.stats import zscore import funcs class TachyonMultidimensionalChamber(QCAlgorithm): def Initialize(self): self.SetStartDate(2021, 10, 19) # Set Start Date self.SetEndDate(2021, 10, 19) # Set End Date self.symbol = "" #set this to "" and it will do all symbols self.SetCash(400000) # Set Strategy Cash self.AddUniverse(self.CoarseSelectionFunction) self.SetSecurityInitializer(self.SecurityInitializer) self.UniverseSettings.ExtendedMarketHours = True self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) self.UniverseSettings.Leverage = 4 self.UniverseSettings.Resolution = Resolution.Second #can comment/change this out #self.SetWarmUp(5) for s in self.Securities: self.Debug(self.Securities[s]) ###variables to keep track of self.sd = {} #all symbol data self.initVars() def initVars(self): self.pastNoPre = {} self.moves = {} #this has both PM and RH moves self.ranges = {} self.curr_ranges = {} #ranges for a certain day, for updateRangesMultiple() self.pastSixty = {} self.models = {} #pm self.pmHigh = {} self.pmVol = {} self.pmNonZeroVol = {} self.everBelowOneDollar = set() self.PM_atSelection = {} # self.prevVWMA = {} self.prevVWAP = {} self.end = tm.time() self.start = tm.time() self.dailyLevels = {} self.hod = {} self.lod = {} self.hod_level = {} #hod and lod for calculating daily range self.lod_level = {} self.open = {} self.minutes = {} #n minutes of data for each symbol self.everPosition = {} self.buffer = 0 #only enter trades after N buffer after open (prob just 1 minute) #error reports self.max_arg_empty_seq = set() self.calc_EMA_error = set() self.VWMA_vol_zero = set() self.EMAwPMerror = set() self.EMAerrorLong = set() self.EMAerrorShort = set() self.EODmodelErr = set() self.avgdevoob = set() self.notInPMHigh = set() #prevPrices, for EMA calc -- if they are the same, don't need to recalculate EMA self.prevPrices = {} self.prevPrices["ab"] = {} self.prevPrices["ab_wPM"] = {} self.prevPrices["bc"] = {} self.prevPrices["cd"] = {} self.prevPrices["postbreak"] = {} self.prevPrices["ab_inpos"] = {} self.prevStartPeriod = {} self.prevStartPeriod["ab"] = {} self.prevStartPeriod["ab_wPM"] = {} self.prevStartPeriod["bc"] = {} self.prevStartPeriod["cd"] = {} self.prevStartPeriod["postbreak"] = {} self.prevStartPeriod["ab_inpos"] = {} #EOD model things self.EODmodels = {} self.EODmodels_entry = {} #times (just regular hours), debugging self.times = {} self.s_times = {} #end day early self.stop_trading = 0 self.stop_entering = 0 #check these on shorter tf than 1 minute self.staging = {} def SecurityInitializer(self, security): security.SetLeverage(4) def CoarseSelectionFunction(self, universe): selected = [] blacklist = set() #blacklist = set(["IBM", "WMT", "IST", "MNDL", "FCAU", "TEVIY", "P", "HSGX", "CLNP", "PSTH"]) #PSTH takes so long for some reason for coarse in universe: #if coarse.Volume > 5000000 and coarse.Value > 1 and coarse.HasFundamentalData: if self.symbol != "": if coarse.Symbol.Value == self.symbol: symbol = coarse.Symbol selected.append(symbol) elif coarse.Volume > 20000000 and coarse.Value > .90 and coarse.HasFundamentalData: if coarse.Symbol.Value not in blacklist: symbol = coarse.Symbol selected.append(symbol) return selected #list of objects of type Symbol def OnSecuritiesChanged(self, changed): for security in changed.AddedSecurities: symbol = security.Symbol if symbol not in self.sd: self.sd[symbol] = SymbolData(self, symbol) for security in changed.RemovedSecurities: symbol = security.Symbol self.sd.pop(symbol, None) ###reset these every day def OnEndOfDay(self): for s in self.sd: self.sd[s].vwap.Reset() self.initVars() ################ # functions # ################ #green or doji --> green def red_or_green(o, h, l, c): if c >= o: return "g" elif c < o: return "r" #add to "candle_halves", every half of candle def updateCandleHalves(self, s, mins, opened, high, low, close, vol, typeOfCandle, t): #new point every 20 seconds #change between earlier high or low depending on if candle red or green #init new move if "candle_halves" not in self.moves[s][t] or typeOfCandle == "low": self.moves[s][t]["candle_halves"] = {} self.moves[s][t]["candle_halves"]["Price"] = [] self.moves[s][t]["candle_halves"]["Volume"] = [] self.moves[s][t]["candle_halves"]["Time"] = [] self.moves[s][t]["candle_halves"]["Time_wall"] = [] #add first candle, start at low self.moves[s][t]["candle_halves"]["Price"].append(low) self.moves[s][t]["candle_halves"]["Volume"].append(vol / 3.0) self.moves[s][t]["candle_halves"]["Time_wall"].append(str(self.Time).split()[1]) if close >= opened: self.moves[s][t]["candle_halves"]["Price"].append(high) self.moves[s][t]["candle_halves"]["Volume"].append(vol / 3.0) self.moves[s][t]["candle_halves"]["Time"].append(mins - .667) self.moves[s][t]["candle_halves"]["Time_wall"].append(str(self.Time).split()[1]) self.moves[s][t]["candle_halves"]["Time"].append(mins - .333) #always add the close self.moves[s][t]["candle_halves"]["Price"].append(close) self.moves[s][t]["candle_halves"]["Volume"].append(vol / 6.0) self.moves[s][t]["candle_halves"]["Time"].append(mins) self.moves[s][t]["candle_halves"]["Time_wall"].append(str(self.Time).split()[1]) else: #add new 1/3 candles #add 1/6 of volume to old close #1/3 to low, 1/3 to high #1/6 to current close self.moves[s][t]["candle_halves"]["Price"][-1] = (self.moves[s][t]["candle_halves"]["Price"][-1] + opened) / 2.0 self.moves[s][t]["candle_halves"]["Volume"][-1] += vol / 6.0 if close >= opened: self.moves[s][t]["candle_halves"]["Price"].append(low) self.moves[s][t]["candle_halves"]["Price"].append(high) elif close < opened: self.moves[s][t]["candle_halves"]["Price"].append(high) self.moves[s][t]["candle_halves"]["Price"].append(low) #these are always the same self.moves[s][t]["candle_halves"]["Price"].append(close) self.moves[s][t]["candle_halves"]["Volume"].append(vol / 3.0) self.moves[s][t]["candle_halves"]["Volume"].append(vol / 3.0) self.moves[s][t]["candle_halves"]["Volume"].append(vol / 6.0) self.moves[s][t]["candle_halves"]["Time"].append(mins - .667) self.moves[s][t]["candle_halves"]["Time"].append(mins - .333) self.moves[s][t]["candle_halves"]["Time"].append(mins) self.moves[s][t]["candle_halves"]["Time_wall"].append(str(self.Time).split()[1]) self.moves[s][t]["candle_halves"]["Time_wall"].append(str(self.Time).split()[1]) self.moves[s][t]["candle_halves"]["Time_wall"].append(str(self.Time).split()[1]) return 0 #get high and low of move, volume #and convert candles to 1/4 candles def updateMoves(self, s, opened, high, low, close, vol, t): #t = time = "PM" or "RH" #init for either t if s not in self.moves: self.moves[s] = {} ############################## # ignition and consolidation # ############################## mins = self.timeInMin(str(self.Time).split()[1]) #new low, reset everything if (t in self.moves[s] and low < self.moves[s][t]["low"]) or t not in self.moves[s]: #update HOD #it's the highest high of all previous moves ##so, can only exist if there is a new move if t == "RH" and t in self.moves[s]: #if s not in self.hod_level or self.moves[s]["RH"]["high"] > self.hod_level[s]: if s not in self.hod_level or self.hod[s] > self.hod_level[s]: #self.Debug("update hod_level") #self.Debug(self.Time) #self.Debug(self.moves[s]["RH"]["high"]) #self.hod_level[s] = self.moves[s]["RH"]["high"] self.hod_level[s] = self.hod[s] #update move self.moves[s][t] = {} self.moves[s][t]["low"] = low self.moves[s][t]["consol_low"] = "NA" #self.moves[s][t]["ign_vol"] = vol #self.moves[s][t]["consol_vol"] = 0 self.moves[s][t]["candles"] = {} #reset all candles #half candles self.updateCandleHalves(s, mins, opened, high, low, close, vol, "low", t) #if first candle is red and is max of move, then high won't exist in candle_halves self.moves[s][t]["high"] = max(self.moves[s][t]["candle_halves"]["Price"]) #if self.Time.hour == 9 and 30 < self.Time.minute < 40: # self.Debug(self.Time) # self.Debug(self.moves[s][t]["candle_halves"]["Price"]) #new high (post new low) elif high > self.moves[s][t]["high"]: self.moves[s][t]["high"] = high #self.moves[s][t]["ign_vol"] += vol + self.moves[s][t]["consol_vol"] self.moves[s][t]["consol_low"] = "NA" #self.moves[s][t]["consol_vol"] = 0 #half candles self.updateCandleHalves(s, mins, opened, high, low, close, vol, "high", t) #consolidation (no new high) else: #self.moves[s][t]["consol_vol"] += vol #new low of consolidation if self.moves[s][t]["consol_low"] == "NA" or low < self.moves[s][t]["consol_low"]: self.moves[s][t]["consol_low"] = low self.updateCandleHalves(s, mins, opened, high, low, close, vol, "consol_low", t) #always add new candle if "o" not in self.moves[s][t]["candles"]: self.moves[s][t]["candles"]["o"] = [] self.moves[s][t]["candles"]["h"] = [] self.moves[s][t]["candles"]["l"] = [] self.moves[s][t]["candles"]["c"] = [] self.moves[s][t]["candles"]["v"] = [] self.moves[s][t]["candles"]["dv"] = [] self.moves[s][t]["candles"]["o"].append(opened) self.moves[s][t]["candles"]["h"].append(high) self.moves[s][t]["candles"]["l"].append(low) self.moves[s][t]["candles"]["c"].append(close) self.moves[s][t]["candles"]["v"].append(vol) self.moves[s][t]["candles"]["dv"].append(vol*close) return 0 def enter(self, s, close): ############## # above VWAP # ############## vwap = self.sd[s].vwap.Current.Value if not (close > vwap): return #above VWAP #doesn't need to break VWAP, just be above it ###################### # resolution too low # ###################### if not (len(self.moves[s]["RH"]["candles"]["o"]) >= 4): return ################################### # enough volume, or dollar volume # ################################### if not (statistics.median(self.moves[s]["RH"]["candles"]["v"]) > 10000 or statistics.median(self.moves[s]["RH"]["candles"]["dv"]) > 1000000): return ################## # not just cents # ################## if not ((self.moves[s]["RH"]["high"] - self.moves[s]["RH"]["low"]) >= .10): return ######### # print # ######### self.Debug("LONG\t\t" + str(self.Time).split()[1] + "\t" + str(s.Value)) return #time is premarket or not #time of format: HH:MM:SS def isPM(self, clock): hour, minute, sec = clock.split(":") if int(hour) < 9: return 1 if int(hour) == 9 and int(minute) < 31: return 1 return 0 def isAH(self, clock): hour, minute, sec = clock.split(":") if int(hour) > 16 or (int(hour) == 16 and int(minute) > 0): return 1 return 0 #time in minutes (since midnight) def timeInMin(self, clock): hour, minute, sec = clock.split(":") return (int(hour)*60) + int(minute) ########### # on data # ########### def OnData(self, data): '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. Arguments: data: Slice object keyed by symbol containing the stock data ''' #stop trading at whatever time e.g., noon #then, after market closes, allow trading again for the next day if self.stop_trading != 0: return if self.Time.hour == 4 and self.Time.minute == 1 and self.Time.second == 1: self.initVars() self.Debug("Number of symbols: ") self.Debug(len(self.sd)) #every minute: #check if below 1, if so remove #only do this in PM (?) #reset list of symbols to stage if self.Time.second == 1: for s in self.everBelowOneDollar: if s in self.ranges: del self.ranges[s] if s in self.sd: del self.sd[s] self.staging = {} if (self.Time.hour >= 10) or (self.Time.hour == 9 and self.Time.minute > 30): self.Debug("Direction\tTime\t\tSymbol\tPropPredMove\tPredPrice\tMed_1min_vol\tGRP\tPredRange") #remove stocks without premarket action if self.Time.hour == 9 and self.Time.minute == 11 and self.Time.second == 1: self.Debug("stocks before pm removal: " + str(len(self.sd))) toremove = set() for s in self.sd: if s in self.pmVol and s in self.pmNonZeroVol: if self.pmVol[s] < 5000 or self.pmNonZeroVol[s] < 25: #dollar volume > $100000? toremove.add(s) elif s not in self.pmHigh: toremove.add(s) for s in toremove: if s in self.sd: del self.sd[s] self.Debug("stocks after pm removal: " + str(len(self.sd))) for s in self.sd: if s in self.pmVol and s in self.pmNonZeroVol: #self.Debug(str(s)) #self.Debug(self.pmVol[s]) #self.Debug(self.pmNonZeroVol[s]) self.PM_atSelection[s] = {} self.PM_atSelection[s]["pmvol"] = self.pmVol[s] self.PM_atSelection[s]["pm_nonzero"] = self.pmNonZeroVol[s] for s in self.sd: start = tm.time() if data.ContainsKey(s) and data.Bars.ContainsKey(s) and self.Time.hour < 16: second = data.Bars if s not in self.pastSixty: self.pastSixty[s] = {} self.pastSixty[s]["o"] = second[s].Open self.pastSixty[s]["h"] = second[s].High self.pastSixty[s]["l"] = second[s].Low self.pastSixty[s]["v"] = second[s].Volume else: #update if second[s].Open > self.pastSixty[s]["h"]: self.pastSixty[s]["h"] = second[s].High if second[s].Low < self.pastSixty[s]["l"]: self.pastSixty[s]["l"] = second[s].Low self.pastSixty[s]["v"] += second[s].Volume if self.Time.second == 1: #should this be 1 actually? #add 1 more minute for this symbol if s not in self.minutes: self.minutes[s] = 1 else: self.minutes[s] += 1 #if s in self.positions: # self.Debug(self.Portfolio[s].Quantity) ############################################################ # store ohlcv for past self.keepPast candles, with premarket # ############################################################ ###consolidate past 60 seconds opened = self.pastSixty[s]["o"] high = self.pastSixty[s]["h"] low = self.pastSixty[s]["l"] close = second[s].Close vol = self.pastSixty[s]["v"] currRange = self.pastSixty[s]["h"] - self.pastSixty[s]["l"] #re-init with current second self.pastSixty[s]["o"] = second[s].Open self.pastSixty[s]["h"] = second[s].High self.pastSixty[s]["l"] = second[s].Low self.pastSixty[s]["v"] = second[s].Volume #save pmHigh #put this in a function if not self.IsMarketOpen(s): if s not in self.pmHigh: self.pmHigh[s] = high self.pmVol[s] = vol self.pmNonZeroVol[s] = 0 if high > self.pmHigh[s]: self.pmHigh[s] = high self.pmVol[s] += vol if vol != 0: self.pmNonZeroVol[s] += 1 if low < 1: self.everBelowOneDollar.add(s) #update moves self.updateMoves(s, opened, high, low, close, vol, "PM") #market is open now if self.IsMarketOpen(s) and self.buffer == 1 and self.stop_entering == 0: #if self.Time.hour < 10 and self.Time.minute < 40: # self.Debug(self.Time) #9:31:00 is first if s not in self.open: self.open[s] = opened ########################################################## # save ohlcv of intraday candles (save range separately) # ########################################################## if s not in self.pastNoPre: self.pastNoPre[s] = {} self.pastNoPre[s]["o"] = [] self.pastNoPre[s]["h"] = [] self.pastNoPre[s]["l"] = [] self.pastNoPre[s]["c"] = [] self.pastNoPre[s]["v"] = [] self.pastNoPre[s]["o"].append(opened) self.pastNoPre[s]["h"].append(high) self.pastNoPre[s]["l"].append(low) self.pastNoPre[s]["c"].append(close) self.pastNoPre[s]["v"].append(vol) #if s in self.hod_level: # self.Debug(self.Time) # self.Debug(self.hod_level[s]) ################################ # price, volume, time of moves # # ranges # # levels # # EMAs (trend) # ################################ #if self.Time.hour == 9 and 29 < self.Time.minute < 40: # self.Debug(self.Time) # self.Debug(low) self.updateMoves(s, opened, high, low, close, vol, "RH") ####################### # HOD and LOD, for range calc # # these are not necessarily levels # literally just HOD and LOD ####################### if s not in self.hod or (s in self.hod and high > self.hod[s]): self.hod[s] = high if s not in self.lod or (s in self.lod and low < self.lod[s]): self.lod[s] = low ######### # entry # ######### self.enter(s, close) #if self.Time.hour == 10 and self.Time.minute == 0: # funcs.minuteHistory(self, s) ################### # previous values # ################### self.prevVWAP[s] = self.sd[s].vwap.Current.Value ############################## # debugging # # print things out for test # ############################## #if self.Time.hour == 10 and self.Time.minute == 0: # self.printCandleHalves(s) #if self.Time.hour == 11 and self.Time.minute == 19: # if s in self.positions: # self.printCandleHalvesCurr(s) #count total time for each ticker end = tm.time() if s not in self.times: self.times[s] = 0 self.times[s] += (end - start) if ((self.Time.hour == 10 and self.Time.minute >= 0) or self.Time.hour >= 11) and self.stop_entering != 1: #if self.Time.hour >= 12 and self.stop_entering != 1: self.stop_entering = 1 if ((self.Time.hour == 10 and self.Time.minute >= 0) or self.Time.hour >= 11) and self.stop_trading == 0: #if self.Time.hour >= 12 and self.stop_trading == 0 and not self.positions: self.Debug("Stopping, 10:00 stop") self.Debug("max() arg is empty sequence:") for s in self.max_arg_empty_seq: self.Debug(s.Value) self.Debug("Volume in VWMA is 0:") for s in self.VWMA_vol_zero: self.Debug(s.Value) self.Debug("calc EMA error:") for s in self.calc_EMA_error: self.Debug(s.Value) self.Debug("calc EMA wPM error:") for s in self.EMAwPMerror: self.Debug(s.Value) self.Debug("calc EMA long error:") for s in self.EMAerrorLong: self.Debug(s.Value) self.Debug("EOD model:") for s in self.EODmodelErr: self.Debug(str(s.Value)) self.Debug("avg dev ign ind oob:") for s in self.avgdevoob: self.Debug(str(s.Value)) profit_s = {} for s in self.everPosition: profit_s[self.Portfolio[s].NetProfit] = s for profit in sorted(profit_s): self.Debug("net profit " + profit_s[profit].Value + ": " + str(profit)) #end the day self.initVars() self.stop_trading = 1 #close all at 3:55 if any positions are open #should change this to time to market close #use BeforeMarketClose() if self.Time.hour >= 15 and self.Time.minute >= 55: self.Debug("Stopping, 3:55 stop") self.Liquidate() #first minute has passed if self.sd and self.IsMarketOpen(s) and self.buffer == 0 and self.Time.minute == 31: #if self.Time.hour == 9 and self.Time.minute == 31 and self.buffer == 0: self.buffer = 1 class SymbolData: def __init__(self, algorithm, symbol): self.vwap = algorithm.VWAP(symbol, 2000, Resolution.Minute) #60*24 = 1440 minutes in a day prehist = algorithm.History(symbol, 10, Resolution.Minute) if not prehist.empty: hist = prehist.loc[symbol] if 'volume' not in prehist.columns: algorithm.Log(f"No volume: {symbol}") return for idx, bar in hist.iterrows(): tradeBar = TradeBar(idx, symbol, bar.open, bar.high, bar.low, bar.close, bar.volume, timedelta(minutes=1)) self.vwap.Update(tradeBar)
import statistics from sklearn.linear_model import LinearRegression from scipy.stats import norm import time as tm import statsmodels.formula.api as smf import talib import pandas def green_red_prop_any(self, opened, high, low, close): green = 0 red = 0 #doji if opened == close: return .50 #green elif close > opened: green += abs(close - opened) #wicks green += abs(high - close) + abs(low - opened) red += abs(high - close) + abs(low - opened) #red elif close < opened: red += abs(close - opened) #wicks green += abs(high - opened) + abs(low - close) red += abs(high - opened) + abs(low - close) if (green + red) != 0: return green / (green + red) else: return "NA" #for the candle that is high of ign, exclude/include wicks depending on if red or green candle def red_volume_high_of_ign(self, opened, high, low, close, volume): green = 0 red = 0 #doji if opened == close: return .50*volume #green elif close > opened: green += abs(close - opened) #wicks green += abs(high - close) red += abs(high - close) + abs(low - opened) #red volume return (abs(close - high) / (green + red))*volume #red elif close < opened: red += abs(close - opened) #wicks green += abs(high - opened) + abs(low - close) red += abs(high - opened) + abs(low - close) #red volume return ( (green + red - abs(high - opened)) / (green + red))*volume else: return "NA" #for the candle that is high of ign, exclude/include wicks depending on if red or green candle def green_volume_low_of_ign(self, opened, high, low, close, volume): green = 0 red = 0 #doji if opened == close: return .50*volume #green elif close > opened: green += abs(close - opened) #wicks green += abs(high - close) red += abs(high - close) + abs(low - opened) #green volume return ( (green + red - abs(high - opened)) / (green + red))*volume #red elif close < opened: red += abs(close - opened) #wicks green += abs(high - opened) + abs(low - close) red += abs(high - opened) + abs(low - close) #green volume return (abs(close - low) / (green + red))*volume else: return "NA" def angles(self, s, close): ab = (self.moves[s]["high"] - self.moves[s]["low"]) / self.moves[s]["ign_time"] bd = (self.moves[s]["high"] - close) / (self.moves[s]["ign_time"] + self.moves[s]["consol_time"]) if abs(ab) > abs(bd): return 1 return 0 def get_currhigh_ind(s, prices): ind = "NA" max_price = max(prices) for i in range(0, len(prices)): if prices[i] < max_price: return i def calc_z(self, x, mu, sd): return (x - mu) / sd def x_from_z(self, z, mu, sd): return (z*sd) + mu #index of consol low def get_consol_low_ind(self, prices, high, curr_consol_low): consol_low_ind = "NA" hit_high = 0 for i in range(0, len(prices)): if prices[i] == high: hit_high = 1 if hit_high == 1 and prices[i] == curr_consol_low: consol_low_ind = i break return consol_low_ind #index of ignition high def ign_high_ind(self, prices, high): for i in range(0, len(prices)): if prices[i] == high: return i #Returns a value rounded down to a specific number of decimal places. #https://kodify.net/python/math/round-decimals/ def round_decimals_down(self, number:float, decimals:int=2): if not isinstance(decimals, int): raise TypeError("decimal places must be an integer") elif decimals < 0: raise ValueError("decimal places has to be 0 or more") elif decimals == 0: return math.floor(number) factor = 10 ** decimals return math.floor(number * factor) / factor #running simple moving average def calcSMA(self, vals): count = 1.0 running_sum = 0.0 SMAs = [] for v in vals: running_sum += v SMAs.append(running_sum / count) count += 1 return SMAs #thinkorswim also includes 4 lookback periods #the earliest are first def calcEMA(self, s, closes, period): currEMA = 0 EMAs = [] alpha = 2.0 / (float(period)+1.0) for i in range(0, len(closes)): if i == 0: currEMA = closes[0] else: try: currEMA = alpha*closes[i] + (1.0-alpha)*currEMA except: self.calc_EMA_error.add(s) return 0, 0 EMAs.append(currEMA) return currEMA, EMAs
#print out table of ranges def print_ranges(self, s): #self.Debug("Period\tOpen\tHigh\tLow\tClose\tVolume\tDistance\tMins_since_first\tTime\tDate") self.Debug("Period\tClose_minus_open\tVolume\tMins_since_first") #start is Mins_since_first - Period for date in self.ranges[s]: for period in sorted(self.ranges[s][date]): for i in range (0, len(self.ranges[s][date][period]["high"])): #self.Debug(str(period) + "\t" + str(round(self.ranges[s][period]["open"][i], 2)) + "\t" + str(round(self.ranges[s][period]["high"][i], 2)) + "\t" + str(round(self.ranges[s][period]["low"][i], 2)) + "\t" + str(round(self.ranges[s][period]["close"][i], 2)) + "\t" + str(self.ranges[s][period]["vol"][i]) + "\t" + str(self.ranges[s][period]["time"][i])) #self.Debug(str(period) + "\t" + str(round(self.ranges[s][date][period]["open"][i], 2)) + "\t" + str(round(self.ranges[s][date][period]["high"][i], 2)) + "\t" + str(round(self.ranges[s][date][period]["low"][i], 2)) + "\t" + str(round(self.ranges[s][date][period]["close"][i], 2)) + "\t" + str(self.ranges[s][date][period]["vol"][i]) + "\t" + str(round(self.ranges[s][date][period]["dist"][i], 2)) + "\t" + str(self.ranges[s][date][period]["minute"][i]) + "\t" + str(self.ranges[s][date][period]["time"][i]) + "\t" + date) self.Debug(str(period) + "\t" + str(round(self.ranges[s][date][period]["close"][i] - self.ranges[s][date][period]["open"][i], 2)) + "\t" + str(self.ranges[s][date][period]["vol"][i]) + "\t" + str(self.ranges[s][date][period]["minute"][i])) ''' #low of consolidation to current price, postbreak #so, use movesCurr def calc_consolEMA(self, s): #get consol low to current price consol_low_prices = [] hit_high = 0 consol_low = 2000000000 for p in self.moves[s]["RH"]["candle_halves"]["Price"]: #consolidating, get the low if hit_high == 1: #if new low, reset if p < consol_low: consol_low = p consol_low_prices = [] consol_low_prices.append(p) #past high of the move elif p == self.moves[s]["RH"]["high"]: hit_high = 1 if len(consol_low_prices) == 0: return "NAN" #midpoint, and low of consolidation to high of consolidation post-low midpoint_consol = ((max(consol_low_prices) + min(consol_low_prices)) / 2.0) consol_low_to_high = [] for p in consol_low_prices: consol_low_to_high.append(p) if p == max(consol_low_prices): break #only need to recalc if it's going to be different start_consol = "N" EMA_period_consol = "A" if s not in self.prevStartPeriod["cd"] or consol_low_to_high != self.prevPrices["cd"][s]: start_consol, EMA_period_consol = EMA_midpoint(self, s, consol_low_to_high, midpoint_consol) self.prevStartPeriod["cd"][s] = str(start_consol) + " " + str(EMA_period_consol) self.prevPrices["cd"][s] = consol_low_to_high else: start_consol, EMA_period_consol = self.prevStartPeriod["cd"][s].split() if not (start_consol != "N" and EMA_period_consol != "A"): self.Debug("is NA") return adj_closes_EMA_consol = [] try: adj_closes_EMA_consol = consol_low_prices[int(start_consol):] except: self.Debug("adj_closes_EMA_consol error") self.Debug(s) adj_closes_EMA_consol[0] = consol_low_prices[0] currEMA_consol, EMAs_consol = self.calcEMA(s, adj_closes_EMA_consol, EMA_period_consol) return currEMA_consol, EMAs_consol, start_consol '''