def load_settings_from_args(): with open("settings/defaults.json") as f: settings = json.load(f) settingsPath = sys.argv[1] if len(sys.argv) > 1 else None if not settingsPath: return None print("Importing settings from %s" % settingsPath) with open(settingsPath) as f: userSettings = json.load(f) settings.update(userSettings) settings = dotdict(settings) if settings.LOG_LEVEL == "ERROR": settings.LOG_LEVEL = logging.ERROR elif settings.LOG_LEVEL == "WARN": settings.LOG_LEVEL = logging.WARN elif settings.LOG_LEVEL == "INFO": settings.LOG_LEVEL = logging.INFO elif settings.LOG_LEVEL == "DEBUG": settings.LOG_LEVEL = logging.DEBUG else: settings.LOG_LEVEL = logging.INFO return settings
def run(settings): signal.signal(signal.SIGTERM, term_handler) signal.signal(signal.SIGINT, term_handler) atexit.register(stop_all_and_exit) if not settings: print("error: no settings defined. nothing to do. exiting") sys.exit() logger.info("###### loading %i bots #########" % len(settings.bots)) if settings.bots is not None: sets = settings.bots[:] del settings.bots # settings is now just the meta settings for botSetting in sets: usedSettings = dict(settings) usedSettings = dotdict(usedSettings) usedSettings.update(botSetting) if len(usedSettings.API_KEY) == 0 or len( usedSettings.API_SECRET) == 0: logger.error( "You have to put in apiKey and secret before starting!") else: logger.info("starting " + usedSettings.id) activeThreads.append(start_bot(usedSettings)) logger.info("init done") if len(activeThreads) > 0: failures = 0 lastError = 0 while True: sleep(1) toRestart = [] toRemove = [] for thread in activeThreads: if not thread.is_alive() or not thread.bot.alive: logger.info("%s died. stopping" % thread.bot.id) toRestart.append(thread.originalSettings) thread.bot.exit() toRemove.append(thread) failures = failures + 1 lastError = time() for thread in toRemove: activeThreads.remove(thread) if time() - lastError > 60 * 15: failures = 0 # reset errorCount after 15 minutes. only restart if more than 5 errors in 15 min if failures > 5: logger.info("too many failures, restart the whole thing") stop_all_and_exit() break for usedSettings in toRestart: logger.info("restarting " + usedSettings.id) sleep(10) activeThreads.append(start_bot(usedSettings)) write_dashboard(settings.DASHBOARD_FILE) else: logger.warn("no bots defined. nothing to do")
def run(settings): signal.signal(signal.SIGTERM, term_handler) signal.signal(signal.SIGINT, term_handler) atexit.register(stop_all_and_exit) if not settings: print("error: no settings defined. nothing to do. exiting") sys.exit() logger.info("###### loading %i bots #########" % len(settings.bots)) if settings.bots is not None: sets = settings.bots[:] del settings.bots # settings is now just the meta settings for botSetting in sets: usedSettings = dict(settings) usedSettings = dotdict(usedSettings) usedSettings.update(botSetting) if len(usedSettings.API_KEY) == 0 or len( usedSettings.API_SECRET) == 0: logger.error( "You have to put in apiKey and secret before starting!") else: logger.info("starting " + usedSettings.id) activeThreads.append(start_bot(usedSettings)) logger.info("init done") if len(activeThreads) > 0: while True: sleep(1) allActive = True for thread in activeThreads: if not thread.is_alive() or not thread.bot.alive: allActive = False logger.info("%s died." % thread.bot.id) break if not allActive: stop_all_and_exit() break write_dashboard(settings.DASHBOARD_FILE) else: logger.warn("no bots defined. nothing to do")
def __init__(self, settings, logger): self.settings = settings self.exchanges = {} self.logger = logger self.m1Data = {} self.logger.info("### Starting up the Aggregator ###") base = self.settings.dataPath try: os.makedirs(base) except Exception: pass # read last data # init exchanges from settings self.read_data() for exset in settings.exchanges: exset = dotdict(exset) self.load_exchange(exset) self.logger.info("initial load of exchanges done")
def read_data_file(self, filename): try: with open(filename, 'r') as file: data = json.load(file) for entry in data: d = VolubaData(entry['tstamp']) for exchange, bar in entry['barsByExchange'].items(): bar = dotdict(bar) b = Bar(tstamp=bar.tstamp, open=bar.open, high=bar.high, low=bar.low, close=bar.close, volume=bar.volume) b.buyVolume = bar.buyVolume b.sellVolume = bar.sellVolume d.barsByExchange[exchange] = b self.m1Data[entry['tstamp']] = d except Exception as e: self.logger.error("Error reading data " + str(e))
def set_data_from_json(bar: Bar, jsonData): if "modules" not in bar.bot_data.keys(): bar.bot_data['modules'] = {} for key in jsonData.keys(): if len(jsonData[key].keys()) > 0: bar.bot_data['modules'][key] = dotdict(jsonData[key])
def start_bot(botSettings, telegram: TelegramBot = None): bot = MultiStrategyBot() originalSettings = dotdict(dict(botSettings)) if "strategies" in botSettings.keys(): risk_reference = 1 if "RISK_REFERENCE" in botSettings.keys(): risk_reference = botSettings.RISK_REFERENCE if risk_reference <= 0: logger.error( "if you don't want to risk money, you shouldn't even run this bot!" ) bot.risk_reference = risk_reference strategies = dict(botSettings.strategies) del botSettings.strategies # settings is now just the meta settings for stratId in strategies.keys(): stratSettings = dict(botSettings) stratSettings = dotdict(stratSettings) stratSettings.update(strategies[stratId]) if stratSettings.KB_RISK_FACTOR <= 0: logger.error( "if you don't want to risk money, you shouldn't even run this bot!" ) continue if stratId == "macross": strat = MACross(fastMA=stratSettings.MAC_FAST_MA, slowMA=stratSettings.MAC_SLOW_MA, swingBefore=stratSettings.MAC_SWING_BEFORE, swingAfter=stratSettings.MAC_SWING_AFTER) elif stratId == "kuegi": strat = KuegiStrategy(min_channel_size_factor=stratSettings.KB_MIN_CHANNEL_SIZE_FACTOR, max_channel_size_factor=stratSettings.KB_MAX_CHANNEL_SIZE_FACTOR, entry_tightening=stratSettings.KB_ENTRY_TIGHTENING, bars_till_cancel_triggered=stratSettings.KB_BARS_TILL_CANCEL_TRIGGERED, limit_entry_offset_perc=stratSettings.KB_LIMIT_OFFSET, delayed_entry=stratSettings.KB_DELAYED_ENTRY, delayed_cancel=stratSettings.KB_DELAYED_CANCEL, cancel_on_filter=stratSettings.KB_CANCEL_ON_FILTER, tp_fac=stratSettings.KB_TP_FAC) \ .withChannel(max_look_back=stratSettings.KB_MAX_LOOK_BACK, threshold_factor=stratSettings.KB_THRESHOLD_FACTOR, buffer_factor=stratSettings.KB_BUFFER_FACTOR, max_dist_factor=stratSettings.KB_MAX_DIST_FACTOR, max_swing_length=stratSettings.KB_MAX_SWING_LENGTH) if "KB_TRAIL_TO_SWING" in stratSettings.keys(): strat.withTrail( trail_to_swing=stratSettings.KB_TRAIL_TO_SWING, delayed_swing=stratSettings.KB_DELAYED_ENTRY, trail_back=stratSettings.KB_ALLOW_TRAIL_BACK) elif stratId == "sfp": strat = SfpStrategy(min_stop_diff_perc=stratSettings.SFP_MIN_STOP_DIFF, init_stop_type=stratSettings.SFP_STOP_TYPE, stop_buffer_fac=stratSettings.SFP_STOP_BUFFER_FAC, tp_fac=stratSettings.SFP_TP_FAC, min_wick_fac=stratSettings.SFP_MIN_WICK_FAC, min_air_wick_fac=stratSettings.SFP_MIN_AIR_WICK_FAC, min_wick_to_body=stratSettings.SFP_MIN_WICK_TO_BODY, min_swing_length=stratSettings.SFP_MIN_SWING_LENGTH, range_length=stratSettings.SFP_RANGE_LENGTH, min_rej_length=stratSettings.SFP_MIN_REJ_LENGTH, range_filter_fac=stratSettings.SFP_RANGE_FILTER_FAC, close_on_opposite=stratSettings.SFP_CLOSE_ON_OPPOSITE, tp_use_atr = stratSettings.SFP_USE_ATR, ignore_on_tight_stop = stratSettings.SFP_IGNORE_TIGHT_STOP, entries = stratSettings.SFP_ENTRIES) \ .withChannel(max_look_back=stratSettings.KB_MAX_LOOK_BACK, threshold_factor=stratSettings.KB_THRESHOLD_FACTOR, buffer_factor=stratSettings.KB_BUFFER_FACTOR, max_dist_factor=stratSettings.KB_MAX_DIST_FACTOR, max_swing_length=stratSettings.KB_MAX_SWING_LENGTH) if "KB_TRAIL_TO_SWING" in stratSettings.keys(): strat.withTrail( trail_to_swing=stratSettings.KB_TRAIL_TO_SWING, delayed_swing=stratSettings.KB_DELAYED_ENTRY, trail_back=stratSettings.KB_ALLOW_TRAIL_BACK) else: strat = None logger.warning("unkown strategy: " + stratId) if strat is not None: strat.with_telegram(telegram) strat.withRM(risk_factor=stratSettings.KB_RISK_FACTOR * risk_reference, risk_type=stratSettings.KB_RISK_TYPE, max_risk_mul=stratSettings.KB_MAX_RISK_MUL, atr_factor=stratSettings.KB_RISK_ATR_FAC) if "KB_BE_FACTOR" in stratSettings.keys(): strat.withExitModule( SimpleBE(factor=stratSettings.KB_BE_FACTOR, buffer=stratSettings.KB_BE_BUFFER)) for i in range(1, 8): factorKey = "KB_BE" + str(i) + "_FACTOR" bufferKey = "KB_BE" + str(i) + "_BUFFER" if factorKey in stratSettings.keys(): strat.withExitModule( SimpleBE(factor=stratSettings[factorKey], buffer=stratSettings[bufferKey])) if "EM_PARA_INIT" in stratSettings.keys(): resetToCurrent = False if "EM_PARA_RESET" in stratSettings.keys(): resetToCurrent = stratSettings.EM_PARA_RESET strat.withExitModule( ParaTrail(accInit=stratSettings.EM_PARA_INIT, accInc=stratSettings.EM_PARA_INC, accMax=stratSettings.EM_PARA_MAX, resetToCurrent=resetToCurrent)) if "FILTER_DAYWEEK" in stratSettings.keys(): strat.withEntryFilter( DayOfWeekFilter(stratSettings.FILTER_DAYWEEK)) bot.add_strategy(strat) else: logger.error("only multistrat bot supported") live = LiveTrading(settings=botSettings, trading_bot=bot, telegram=telegram) t = threading.Thread(target=live.run_loop) t.bot: LiveTrading = live t.originalSettings = originalSettings t.start() return t
def start_bot(botSettings): bot = MultiStrategyBot() if "strategies" in botSettings.keys(): strategies = dict(botSettings.strategies) del botSettings.strategies # settings is now just the meta settings for stratId in strategies.keys(): stratSettings = dict(botSettings) stratSettings = dotdict(stratSettings) stratSettings.update(strategies[stratId]) if stratSettings.KB_RISK_FACTOR <= 0: logger.error( "if you don't want to risk money, you shouldn't even run this bot!" ) continue if stratId == "kuegi": strat = KuegiStrategy(min_channel_size_factor=stratSettings.KB_MIN_CHANNEL_SIZE_FACTOR, max_channel_size_factor=stratSettings.KB_MAX_CHANNEL_SIZE_FACTOR, entry_tightening=stratSettings.KB_ENTRY_TIGHTENING, bars_till_cancel_triggered=stratSettings.KB_BARS_TILL_CANCEL_TRIGGERED, stop_entry=stratSettings.KB_STOP_ENTRY, delayed_entry=stratSettings.KB_DELAYED_ENTRY, delayed_cancel=stratSettings.KB_DELAYED_CANCEL, cancel_on_filter=stratSettings.KB_CANCEL_ON_FILTER) \ .withChannel(max_look_back=stratSettings.KB_MAX_LOOK_BACK, threshold_factor=stratSettings.KB_THRESHOLD_FACTOR, buffer_factor=stratSettings.KB_BUFFER_FACTOR, max_dist_factor=stratSettings.KB_MAX_DIST_FACTOR, max_swing_length=stratSettings.KB_MAX_SWING_LENGTH) if "KB_TRAIL_TO_SWING" in stratSettings.keys(): strat.withTrail( trail_to_swing=stratSettings.KB_TRAIL_TO_SWING, delayed_swing=stratSettings.KB_DELAYED_ENTRY, trail_back=stratSettings.KB_ALLOW_TRAIL_BACK) elif stratId == "sfp": strat = SfpStrategy(init_stop_type=stratSettings.SFP_STOP_TYPE, tp_fac=stratSettings.SFP_TP_FAC, min_wick_fac=stratSettings.SFP_MIN_WICK_FAC, min_swing_length=stratSettings.SFP_MIN_SWING_LENGTH, range_length=stratSettings.SFP_RANGE_LENGTH, min_rej_length=stratSettings.SFP_MIN_REJ_LENGTH, range_filter_fac=stratSettings.SFP_RANGE_FILTER_FAC, close_on_opposite=stratSettings.SFP_CLOSE_ON_OPPOSITE) \ .withChannel(max_look_back=stratSettings.KB_MAX_LOOK_BACK, threshold_factor=stratSettings.KB_THRESHOLD_FACTOR, buffer_factor=stratSettings.KB_BUFFER_FACTOR, max_dist_factor=stratSettings.KB_MAX_DIST_FACTOR, max_swing_length=stratSettings.KB_MAX_SWING_LENGTH) if "KB_TRAIL_TO_SWING" in stratSettings.keys(): strat.withTrail( trail_to_swing=stratSettings.KB_TRAIL_TO_SWING, delayed_swing=stratSettings.KB_DELAYED_ENTRY, trail_back=stratSettings.KB_ALLOW_TRAIL_BACK) else: strat = None logger.warn("unkown strategy: " + stratId) if strat is not None: strat.withRM(risk_factor=stratSettings.KB_RISK_FACTOR, risk_type=stratSettings.KB_RISK_TYPE, max_risk_mul=stratSettings.KB_MAX_RISK_MUL, atr_factor=stratSettings.KB_RISK_ATR_FAC) if "KB_BE_FACTOR" in stratSettings.keys(): strat.withExitModule( SimpleBE(factor=stratSettings.KB_BE_FACTOR, buffer=stratSettings.KB_BE_BUFFER)) if "KB_BE2_FACTOR" in stratSettings.keys(): strat.withExitModule( SimpleBE(factor=stratSettings.KB_BE2_FACTOR, buffer=stratSettings.KB_BE2_BUFFER)) if "EM_PARA_INIT" in stratSettings.keys(): strat.withExitModule( ParaTrail(accInit=stratSettings.EM_PARA_INIT, accInc=stratSettings.EM_PARA_INC, accMax=stratSettings.EM_PARA_MAX)) if "FILTER_DAYWEEK" in stratSettings.keys(): strat.withEntryFilter( DayOfWeekFilter(stratSettings.FILTER_DAYWEEK)) bot.add_strategy(strat) else: if botSettings.KB_RISK_FACTOR <= 0: logger.error( "if you don't want to risk money, you shouldn't even run this bot!" ) else: bot.add_strategy( KuegiStrategy( min_channel_size_factor=botSettings. KB_MIN_CHANNEL_SIZE_FACTOR, max_channel_size_factor=botSettings. KB_MAX_CHANNEL_SIZE_FACTOR, entry_tightening=botSettings.KB_ENTRY_TIGHTENING, bars_till_cancel_triggered=botSettings. KB_BARS_TILL_CANCEL_TRIGGERED, stop_entry=botSettings.KB_STOP_ENTRY, delayed_entry=botSettings.KB_DELAYED_ENTRY, delayed_cancel=botSettings.KB_DELAYED_CANCEL, cancel_on_filter=botSettings.KB_CANCEL_ON_FILTER). withChannel( max_look_back=botSettings.KB_MAX_LOOK_BACK, threshold_factor=botSettings.KB_THRESHOLD_FACTOR, buffer_factor=botSettings.KB_BUFFER_FACTOR, max_dist_factor=botSettings.KB_MAX_DIST_FACTOR, max_swing_length=botSettings.KB_MAX_SWING_LENGTH).withRM( risk_factor=botSettings.KB_RISK_FACTOR, risk_type=botSettings.KB_RISK_TYPE, max_risk_mul=botSettings.KB_MAX_RISK_MUL, atr_factor=botSettings.KB_RISK_ATR_FAC).withExitModule( SimpleBE(factor=botSettings.KB_BE_FACTOR, buffer=botSettings.KB_BE_BUFFER)). withTrail(trail_to_swing=botSettings.KB_TRAIL_TO_SWING, delayed_swing=botSettings.KB_DELAYED_ENTRY, trail_back=botSettings.KB_ALLOW_TRAIL_BACK)) live = LiveTrading(settings=botSettings, trading_bot=bot) t = threading.Thread(target=live.run_loop) t.bot: LiveTrading = live t.start() return t