def _g_json(cls, path): name = os.path.split(path)[-1][:-5] json_dict = sltm.g_config(path) scraper = Scraper(**json_dict['scraper']) if json_dict.get('logger'): scraper.logger = sltc.EasyObj.select_type(**json_dict['logger']) return scraper, name
def RESOURCE(cls, r, c, x): '''Loads a resource Args: x (str ): resource name. Returns: dict : The dict loaded from the JSON resource. ''' resource_path = join(slst.RESOURCE_FOLDER, x + '.json') return sltm.g_config(resource_path)
def set_params(root='./'): settings_dict = sltm.g_config(join(root, '__settings.json')) _params_list = { 'EXTRACTORS_SEPARATOR': '-->', 'KWARGS_SEPARATOR': '<->', 'ESC_OPEN': '<(', 'ESC_CLOSE': ')>', 'LIST_SEPARATOR': '!!', 'COLLECTIONS_SEPARATOR': '|=|', } for param, def_value in _params_list.items(): set_param(param, settings_dict.get('parameters', {}).get(param, def_value)) set_param('RESOURCE_FOLDER', join(root, 'resources'))
def run_scraper(cls, path, url=None, settings_path=None, is_join=True): cls._load_customs(path) settings_path = cls._g_settings_path(path, settings_path) settings = sltm.g_config(settings_path) if path.split('.')[-1] == 'json': scraper, name = cls._g_json(path) elif path.split('.')[-1] == 'py': scraper, name = cls._g_py(path) if url != None: scraper.start_tasks.clear() scraper.add_request(url) scraper.is_single_request = True try: cls._start_scraper(name, scraper, settings, is_join) except Exception as e: print(traceback.format_exc())
import mplfinance import matplotlib.dates as mdates import saltools.misc as sltm import matplotlib.pyplot as plt import pandas as pd import traceback import engine import random import json import sys register_matplotlib_converters() CONFIG_PATH = "ui_config.json" CONFIGS = sltm.g_config(CONFIG_PATH) def plot_ohlc(df, axes=None): show = False if not axes: show = True fig = plt.figure(figsize=(5, 4), dpi=100) axes = fig.add_subplot(111) df = df.reset_index() df["date"] = df["date"].apply(mdates.date2num) axes.xaxis_date() axes.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H')) axes.tick_params(labelrotation=45, labelsize=7) cl = candlestick_ohlc(ax=axes,
def run(self): result = {} results = {} result['Trade Direction'] = self.direction result['High Time Frame'] = self.time_frame result['Ticker'] = self.ticker clist = [] if self.ticker != '': # If we have supplied a ticker use it pairs = [self.ticker] else: # Or do for all tickers in config.json pairs = sltm.g_config()['pairs'] if self.s_date == '': self.s_date = datetime.utcnow() try: for pair in pairs: # for each ticker in list pairs AT_HL = False HTFscore = 0 ITFscore = 0 logging.info({'HTF Parsing DataFrame HTF': pair}) # Get Data from CSV or DB try: df = parseCSV(str(self.ticker) + '_HTF.csv') except FileNotFoundError as e: logging.info('Could not load data.') logging.info( 'File {} was not found in current directory, exiting..' .format(self.ticker + '.csv')) exit() time.sleep(0.3) logging.info('\t+ DataFrame loaded') time.sleep(0.1) for row in df.iterrows(): cl = Candle(row, self.htf_params ) # Import each row of DF as a new Candle item clist.append(cl) # Add each new Candle to a list ## HTF SCAN ## ## ## HTF = Area(clist, self.htf_params, logging) logging.info('{} scan HTF..'.format(self.direction)) TradingZone = HTF.HTFfindTradingZone(self.direction) if TradingZone: logging.info("\t+ Trading Zone ") if self.direction == 'Long': logging.info("\t+ Demand Zone at " + TradingZone[0] + ' - ' + TradingZone[1] + '\n') TDZTop = TradingZone[3] # Higher Frame Demand Zone TOP BOTTOM HTFDZBOT = TradingZone[2] HTFDZTOP = TradingZone[3] Now = TradingZone[4] elif self.direction == 'Short': logging.info("\t+ Supply Zone at " + TradingZone[0] + ' - ' + TradingZone[1] + '\n') TSZBot = TradingZone[2] # Higher Frame Supply Zone TOP BOTTOM HTFSZBOT = TradingZone[2] HTFSZTOP = TradingZone[3] Now = TradingZone[4] else: logging.info("\t+ No Trading Zone found..") logging.info("\t+ Exiting..") return results OpposingZone = HTF.HTFfindOpposingZone(self.direction) if OpposingZone: # If we find Opposing Zone logging.info("\t+ Opposing Zone ") if self.direction == 'Long': logging.info("\t+ Supply Zone at " + OpposingZone[0] + ' - ' + OpposingZone[1] + '\n') OSZBot = OpposingZone[2] Now = TradingZone[4] elif self.direction == 'Short': logging.info("\t+ Demand Zone at " + OpposingZone[0] + ' - ' + OpposingZone[1] + '\n') ODZTop = OpposingZone[3] Now = TradingZone[4] else: # If we dont find Opposing Zone look for ATH/ATL logging.info(" No Opposing Zone found.") logging.info("\t+ Now scanning for All-time High/Low..") if self.direction == 'Long': OSZBot = HTF.findAT(self.direction) # SZBot logging.info("\t+ Found all-time High " + str(OSZBot)) AT_HL = True elif self.direction == 'Short': OSZTop = HTF.findAT(self.direction) # DZTop logging.info("\t+ Found all-time Low " + str(OSZTop)) AT_HL = True ## ## ## ## ## ## ## ## HTF SCORING ## ## ## if self.direction == 'Long': curve = {} for i in range(1, 6): curve[i] = (i * (OSZBot - TDZTop) / 5) + TDZTop if Now < curve[2] and Now > curve[1]: logging.info( "Current price is Very Low on the curve. Score = 2" ) result['Curve Level'] = 'Very Low' HTFscore = 2 elif Now < curve[3] and Now > curve[2]: logging.info( "Current price is Low on the curve. Score = 1") result['Curve Level'] = 'Low' HTFscore = 1 else: result['Curve Level'] = 'High/Very High Score 0' #logging.info("\n Price {}\n SZBot {}\n DZTop {}\n Score {}\n".format(Now, OSZBot, TDZTop, HTFscore)) elif self.direction == 'Short': curve = {} for i in range(1, 6): curve[i] = (i * (TSZBot - ODZTop) / 5) + ODZTop if Now < curve[5] and Now > curve[4]: logging.info( "Current price is Very High on the curve. Score = 2" ) result['Curve Level'] = 'Very High' HTFscore = 2 elif Now < curve[4] and Now > curve[3]: logging.info( "Current price is High on the curve. Score = 1") result['Curve Level'] = 'High' HTFscore = 1 else: result['Curve Level'] = 'Low/Very Low Score 0' ## ## ## ## ## ## ## ######## ITF ######## # If checkbox is enabled do ITF if self.checkitf: # Reset results (except score) to proceed with ITF clist.clear() clist = [] logging.info({'ITF Parsing DataFrame ITF': pair}) # Get Data from CSV or DB try: df = parseCSV(str(self.ticker) + '_ITF.csv') except FileNotFoundError as e: logging.info('Could not load data.') logging.info( 'File {} was not found in current directory, exiting..' .format(self.ticker + '_ITF.csv')) exit() time.sleep(0.3) logging.info('\t+ DataFrame loaded') time.sleep(0.1) # Calculate SMA EMA df['sma'] = df['Close'].rolling(20).mean() df['ema'] = df['Close'].ewm(5).mean() if self.direction == 'Long': if self.time_frame == 'Monthly' or self.time_frame == 'Weekly': if df['ema'][0] > df['sma'][0]: result['ITF Score'] = '5EMA > 20SMA Score = 1' ITFscore = 1 else: result['ITF Score'] = '5EMA < 20SMA Score = 0' ITFscore = 0 else: if df['Close'][0] > df['sma'][0]: result[ 'ITF Score'] = 'ClosePrice > 20SMA Score = 1' ITFscore = 1 else: result[ 'ITF Score'] = 'ClosePrice < 20SMA Score = 0' ITFscore = 0 elif self.direction == 'Short': if self.time_frame == 'Monthly' or self.time_frame == 'Weekly': if df['ema'][0] < df['sma'][0]: result['ITF Score'] = '5EMA < 20SMA Score = 1' ITFscore = 1 else: result['ITF Score'] = '5EMA > 20SMA Score = 0' ITFscore = 0 else: if df['Close'][0] < df['sma'][0]: result[ 'ITF Score'] = 'ClosePrice < 20SMA Score = 1' ITFscore = 1 else: result[ 'ITF Score'] = 'ClosePrice > 20SMA Score = 0' ITFscore = 0 # Reset results (except score) to proceed with LTF clist.clear() clist = [] logging.info({'LTF Parsing DataFrame LTF': pair}) # Get Data from CSV or DB try: df = parseCSV(str(self.ticker) + '_LTF.csv') except FileNotFoundError as e: logging.info('Could not load data.') logging.info( 'File {} was not found in current directory, exiting..' .format(self.ticker + '.csv')) exit() time.sleep(0.3) logging.info('\t+ DataFrame loaded') time.sleep(0.1) for row in df.iterrows(): cl = Candle(row, self.htf_params ) # Import each row of DF as a new Candle item clist.append(cl) # Add each new Candle to a list AT_HL = False startFrom = 0 # LTF multiple trading-zone support ## LTF SCAN ## ## ## LTF = Area(clist, self.ltf_params, logging) logging.info('{} scan LTF..'.format(self.direction)) while True: FINscore = 0 result['Zone Overlap'] = False TradingZone = LTF.LTFfindTradingZone( self.direction, startFrom) if TradingZone: startFrom = TradingZone[ 6] # Next run begin from previous zone's end logging.info("\t+ Trading Zone ") if self.direction == 'Long': logging.info("\t+ Demand Zone at " + TradingZone[0] + ' - ' + TradingZone[1] + '\n') TDZTop = TradingZone[3] TDZBot = TradingZone[2] # TDZBot for RRR Now = TradingZone[4] FINscore = FINscore + TradingZone[5] result['Entry Price at LTF Zone'] = TDZTop result[ 'Date/Time of LO at LTF Zone'] = TradingZone[0] #logging.info("\n Price {}\n TDZTop {}\n Score {}\n".format(Now, TDZTop, FINscore)) elif self.direction == 'Short': logging.info("\t+ Supply Zone at " + TradingZone[0] + ' - ' + TradingZone[1] + '\n') TSZBot = TradingZone[2] TSZTop = TradingZone[3] # TSZTop for RRR Now = TradingZone[4] FINscore = FINscore + TradingZone[5] result['Entry Price at LTF Zone'] = TSZBot result[ 'Date/Time of LO at LTF Zone'] = TradingZone[0] #logging.info("\n Price {}\n TSZBot {}\n Score {}\n".format(Now, TSZBot, FINscore)) OpposingZone = LTF.LTFfindOpposingZone(self.direction) if OpposingZone: # If we find Opposing Zone logging.info("\t+ Opposing Zone ") if self.direction == 'Long': logging.info("\t+ Supply Zone at " + OpposingZone[0] + ' - ' + OpposingZone[1] + '\n') OSZBot = OpposingZone[2] Now = TradingZone[4] RRR = (OSZBot - TDZTop) / (TDZTop - TDZBot ) # Reward / Risk elif self.direction == 'Short': logging.info("\t+ Demand Zone at " + OpposingZone[0] + ' - ' + OpposingZone[1] + '\n') ODZTop = OpposingZone[3] Now = TradingZone[4] #print("Here TradingZone SupplyZone Bot = ", TSZBot) #print("Here TradingZone SupplyZone Top = ", TSZTop) #print("Here OpposinZone DemandZone Top = ", ODZTop) RRR = (TSZBot - ODZTop) / (TSZTop - TSZBot ) # Reward / Risk else: # If we dont find Opposing Zone look for ATH/ATL logging.info("\t+ No Opposing Zone found.") logging.info( "\t+ Now scanning for All-time High/Low..") if self.direction == 'Long': OSZBot = HTF.findAT(self.direction) # SZBot logging.info("\t+ Found all-time High " + str(OSZBot)) AT_HL = True RRR = (OSZBot - TDZTop) / (TDZTop - TDZBot ) # Reward / Risk elif self.direction == 'Short': OSZTop = HTF.findAT(self.direction) # DZTop logging.info("\t+ Found all-time Low " + str(OSZTop)) AT_HL = True RRR = (ODZTop - TSZBot) / (TSZTop - TSZBot ) # Reward / Risk # Add ZoneOnZone score if self.direction == 'Long': if TDZTop < HTFDZTOP and TDZBot > HTFDZBOT: FINscore = FINscore + 2 result['Zone Overlap'] = True elif self.direction == 'Short': if TSZTop < HTFSZTOP and TSZBot > HTFSZBOT: FINscore = FINscore + 2 result['Zone Overlap'] = True # Add RRR score if RRR > 3: FINscore = FINscore + 1 elif RRR > 2 and RRR < 3: FINscore = FINscore + 0.5 result['RRR'] = RRR # Add HTF score FINscore = FINscore + HTFscore + ITFscore result['Score'] = FINscore result['Leg Out Gap'] = LTF.LOgap result['# of base Candles'] = LTF.Basings result['Leg out Rank'] = LTF.LOrank print(json.dumps(result, indent=4)) else: #logging.info("\t+ No Trading Zone found.\n") break ## ## ## ## ## ## ## # Dereference all Candles and Ranges with __del__ # Go To LTF.. except KeyboardInterrupt: raise (KeyboardInterrupt) except Exception as e: print(e) traceback.print_exc() pass return results