def __init__(self, startingBalance: float, data: list, strategies: list, strategyInterval: Union[str, None] = None, symbol: str = None, marginEnabled: bool = True, startDate: datetime = None, endDate: datetime = None, precision: int = 4, outputTrades: bool = True): super().__init__(symbol=symbol, precision=precision, startingBalance=startingBalance) self.commissionsPaid = 0 self.marginEnabled = marginEnabled self.outputTrades: bool = outputTrades # Boolean that'll determine whether trades are outputted to file or not. convert_all_dates_to_datetime(data) self.data = data self.check_data() self.interval = self.get_interval() self.intervalMinutes = get_interval_minutes(self.interval) self.profit = 0 self.startTime = None self.endTime = None self.inLongPosition = False self.inShortPosition = False self.currentPeriod = None self.minPeriod = 0 self.pastActivity = [ ] # We'll add previous data here when hovering through graph in GUI. if len(strategyInterval.split()) == 1: strategyInterval = convert_small_interval(strategyInterval) self.strategyInterval = self.interval if strategyInterval is None else strategyInterval self.strategyIntervalMinutes = get_interval_minutes( self.strategyInterval) self.intervalGapMinutes = self.strategyIntervalMinutes - self.intervalMinutes self.intervalGapMultiplier = self.strategyIntervalMinutes // self.intervalMinutes if self.intervalMinutes > self.strategyIntervalMinutes: raise RuntimeError( "Your strategy interval can't be smaller than the data interval." ) self.ema_dict = {} self.rsi_dictionary = {} set_up_strategies(self, strategies) self.startDateIndex = self.get_start_index(startDate) self.endDateIndex = self.get_end_index(endDate)
def __init__(self, startingBalance: float, data: list, strategies: list, strategyInterval: Union[str, None] = None, symbol: str = None, marginEnabled: bool = True, startDate: datetime = None, endDate: datetime = None, drawdownPercentage: int = 100, precision: int = 4, outputTrades: bool = True, logger: Logger = None): super().__init__(symbol=symbol, precision=precision, startingBalance=startingBalance, marginEnabled=marginEnabled) convert_all_dates_to_datetime(data) self.data = data self.check_data() self.outputTrades: bool = outputTrades # Boolean that'll determine whether trades are outputted to file or not. self.interval = self.get_interval() self.intervalMinutes = get_interval_minutes(self.interval) self.pastActivity = [ ] # We'll add previous data here when hovering through graph in GUI. self.drawdownPercentageDecimal = drawdownPercentage / 100 # Percentage of loss at which bot exits backtest. self.optimizerRows = [] self.logger = logger if len(strategyInterval.split()) == 1: strategyInterval = convert_small_interval(strategyInterval) self.allStrategies = get_strategies_dictionary( Strategy.__subclasses__()) self.strategyInterval = self.interval if strategyInterval is None else strategyInterval self.strategyIntervalMinutes = get_interval_minutes( self.strategyInterval) self.intervalGapMinutes = self.strategyIntervalMinutes - self.intervalMinutes self.intervalGapMultiplier = self.strategyIntervalMinutes // self.intervalMinutes if self.intervalMinutes > self.strategyIntervalMinutes: raise RuntimeError( f"Your strategy interval ({self.strategyIntervalMinutes} minute(s)) can't be smaller " f"than the data interval ({self.intervalMinutes} minute(s)).") self.ema_dict = {} self.rsi_dictionary = {} self.setup_strategies(strategies) self.startDateIndex = self.get_start_index(startDate) self.endDateIndex = self.get_end_index(endDate)
def load_interval_combo_boxes(config_obj): """ This function currently only handles combo boxes for backtester/optimizer interval logic. It'll update the strategy interval combo-box depending on what the data interval combo-box has as its current value. :param config_obj: Configuration QDialog object (from configuration.py) """ intervals = helpers.get_interval_strings(startingIndex=0) config_obj.intervalComboBox.addItems(intervals) config_obj.simulationIntervalComboBox.addItems(intervals) config_obj.backtestStrategyIntervalCombobox.addItems(intervals) config_obj.backtestIntervalComboBox.addItems(intervals) config_obj.backtestIntervalComboBox.currentTextChanged.connect(lambda: reset_strategy_interval_comboBox( strategy_combobox=config_obj.backtestStrategyIntervalCombobox, interval_combobox=config_obj.backtestIntervalComboBox )) config_obj.optimizerStrategyIntervalCombobox.addItems(intervals) config_obj.optimizerIntervalComboBox.addItems(intervals) config_obj.optimizerStrategyIntervalEndCombobox.addItems(intervals) config_obj.optimizerIntervalComboBox.currentTextChanged.connect(lambda: reset_strategy_interval_comboBox( strategy_combobox=config_obj.optimizerStrategyIntervalCombobox, interval_combobox=config_obj.optimizerIntervalComboBox )) config_obj.optimizerStrategyIntervalCombobox.currentTextChanged.connect(lambda: reset_strategy_interval_comboBox( strategy_combobox=config_obj.optimizerStrategyIntervalEndCombobox, interval_combobox=config_obj.optimizerStrategyIntervalCombobox, start_index=config_obj.optimizerIntervalComboBox.currentIndex(), divisor=helpers.get_interval_minutes(config_obj.optimizerIntervalComboBox.currentText()) ))
def get_starting_timestamp(self, multiplier: int = 1) -> int: current_timestamp = self.get_current_timestamp() * 1000 period_minutes = get_interval_minutes(self.long_interval) period_microseconds = period_minutes * 60 * 1000 * ( self.periods + 1) # Using +1 for safety. return int(current_timestamp - period_microseconds * multiplier)
def get_starting_timestamp(self, multiplier: int = 1) -> int: """ Get starting timestamp for the snooping. :param multiplier: Multiplier to use for the starting timestamp. The bigger, the further back the timestamp. :return: Starting timestamp in an integer format. """ current_timestamp = self.get_current_timestamp() * 1000 period_minutes = get_interval_minutes(self.long_interval) period_microseconds = period_minutes * 60 * 1000 * ( self.periods + 1) # Using +1 for safety. return int(current_timestamp - period_microseconds * multiplier)
def reset_strategy_interval_comboBox(strategy_combobox: QComboBox, interval_combobox: QComboBox, start_index: int = 0, filter_intervals: bool = True, divisor: int = None): """ This function will reset the strategy combobox based on what interval is picked in the interval combobox. :param strategy_combobox: Combobox to modify based on the interval combobox. :param interval_combobox: Interval combobox that will trigger this function. :param start_index: Optional start index to start from when getting interval strings. :param filter_intervals: Boolean on whether to filter tickers or not. :param divisor: Divisor to use for filtering intervals. If none is provided, it will use data interval minutes. """ dataInterval = interval_combobox.currentText() if not dataInterval: return # Means text is empty, so just return. dataIntervalMinutes = get_interval_minutes(dataInterval) dataIndex = interval_combobox.currentIndex() strategyInterval = strategy_combobox.currentText() intervals = get_interval_strings(startingIndex=start_index + dataIndex) if filter_intervals: divisor = divisor if divisor is not None else dataIntervalMinutes intervals = [ interval for interval in intervals if get_interval_minutes(interval) % divisor == 0 ] strategy_combobox.clear() strategy_combobox.addItems(intervals) previousStrategyIntervalIndex = strategy_combobox.findText( strategyInterval) if previousStrategyIntervalIndex != -1: strategy_combobox.setCurrentIndex(previousStrategyIntervalIndex)
def change_strategy_interval(self, interval: str): """ Changes strategy interval to the one provided. :param interval: Interval to update strategy interval with. """ if len(interval.split()) == 1: interval = convert_small_interval(interval) self.strategyInterval = self.interval if interval is None else interval self.strategyIntervalMinutes = get_interval_minutes( self.strategyInterval) self.intervalGapMinutes = self.strategyIntervalMinutes - self.intervalMinutes self.intervalGapMultiplier = self.strategyIntervalMinutes // self.intervalMinutes if self.intervalMinutes > self.strategyIntervalMinutes: raise RuntimeError( "Your strategy interval can't be smaller than the data interval." )