def __init__(self, sys_config: SystemConfiguration): self.sys_config = sys_config self.exchange_config = self.sys_config.exchange_config self.trade_optimizer = self.sys_config.trade_strategy_optimizer self.trade_process = self.sys_config.runtime_config.actual_trade_process self._trade_client_crypto = MyBitfinexTradeClient(self.exchange_config) self._trade_client_shares = MyIBKRTradeClient( self.sys_config.shares_config) self.stock_db = self.sys_config.db_stock self.ticker_id_list = [] self.pattern_trade_dict = {} self.balances = None # list of actual balances self.process = '' self.trade_candidate_controller = TradeCandidateController( self.exchange_config, self.trade_optimizer, self.trade_process) self.news_handler = NewsHandler() self.value_total_start = 0 self._last_wave_tick_for_test = None self._time_stamp_for_actual_check = 0 self._pattern_trade_for_replay = None self._replay_status = RST.REPLAY
def __get_news_handler__(): return NewsHandler(' \n', '')
class PatternTradeHandler: def __init__(self, sys_config: SystemConfiguration): self.sys_config = sys_config self.exchange_config = self.sys_config.exchange_config self.trade_optimizer = self.sys_config.trade_strategy_optimizer self.trade_process = self.sys_config.runtime_config.actual_trade_process self._trade_client_crypto = MyBitfinexTradeClient(self.exchange_config) self._trade_client_shares = MyIBKRTradeClient( self.sys_config.shares_config) self.stock_db = self.sys_config.db_stock self.ticker_id_list = [] self.pattern_trade_dict = {} self.balances = None # list of actual balances self.process = '' self.trade_candidate_controller = TradeCandidateController( self.exchange_config, self.trade_optimizer, self.trade_process) self.news_handler = NewsHandler() self.value_total_start = 0 self._last_wave_tick_for_test = None self._time_stamp_for_actual_check = 0 self._pattern_trade_for_replay = None self._replay_status = RST.REPLAY @property def is_simulation(self): return not (self.trade_process == TP.ONLINE and self.exchange_config.automatic_trading_on) @property def replay_status(self): return self._replay_status def __get_trade_client_for_symbol__(self, symbol: str): if self.trade_process == TP.ONLINE: if self.sys_config.index_config.is_symbol_crypto(symbol): return self._trade_client_crypto return self._trade_client_shares return None def get_pattern_trade_by_id(self, trade_id: str) -> PatternTrade: for pattern_trade in self.pattern_trade_dict.values(): if pattern_trade.id == trade_id: return pattern_trade @property def trade_numbers(self) -> int: return len(self.pattern_trade_dict) @property def trade_numbers_active(self) -> int: return len(self.__get_pattern_trade_dict_by_status__(PTS.EXECUTED)) @property def pattern_trade_for_replay(self) -> PatternTrade: return self._pattern_trade_for_replay def get_real_trade_numbers_active_for_dashboard(self): return self.__get_trade_numbers_active_for_dashboard__( is_simulation=False) def get_simulation_trade_numbers_active_for_dashboard(self): return self.__get_trade_numbers_active_for_dashboard__( is_simulation=True) def __get_trade_numbers_active_for_dashboard__(self, is_simulation: bool) -> str: trade_dict = { key: trade for key, trade in self.pattern_trade_dict.items() if trade.status == PTS.EXECUTED and trade.is_simulation == is_simulation } number = len(trade_dict) result_pct = 0 if number == 0 else statistics.mean( [trade.trade_result_pct for trade in trade_dict.values()]) return '{}/{:+.2f}%'.format(number, result_pct) def get_balance_total(self): if self.balances is None: return 0 return sum([balance.current_value for balance in self.balances]) def get_current_price_for_ticker_id(self, ticker_id: str) -> float: return self.__get_current_wave_tick_for_ticker_id__(ticker_id).close def get_balance_as_asset_data_frame(self): if self.balances is None: return None ts = MyDate.get_epoch_seconds_from_datetime() dt_str = MyDate.get_date_time_from_epoch_seconds_as_string(ts) dict_for_data_frame = {} for balance in self.balances: data_dict = AssetDataDictionary( ).get_data_dict_for_target_table_for_balance(balance, ts, dt_str) for key, value in data_dict.items(): if key not in dict_for_data_frame: dict_for_data_frame[key] = [value] else: dict_for_data_frame[key].append(value) return pd.DataFrame.from_dict(dict_for_data_frame) def get_balances_with_current_values(self): return self._trade_client_crypto.get_balances_with_current_values() def add_pattern_list_for_trade(self, pattern_list: list): if self.sys_config.runtime_config.actual_trade_process == TP.BACK_TESTING: trade_able_pattern_list = pattern_list else: trade_able_pattern_list = self.trade_optimizer.get_trade_able_pattern_from_pattern_list( pattern_list) if len(trade_able_pattern_list) > 0: self.trade_candidate_controller.add_new_pattern_list( trade_able_pattern_list) self.__process_trade_candidates__() self._pattern_trade_for_replay = self.__get_pattern_trade_for_replay__( ) def simulate_trading_for_one_pattern(self, pattern: Pattern): tick_list = pattern.get_back_testing_wave_ticks() for wave_tick in tick_list: self.check_actual_trades(wave_tick) # wave_tick self.enforce_sell_at_end(tick_list[-1]) def check_actual_trades(self, last_wave_tick=None): if last_wave_tick is not None: self._last_wave_tick_for_test = last_wave_tick self._time_stamp_for_actual_check = MyDate.get_epoch_seconds_from_datetime( ) if self.trade_process == TP.ONLINE: self.__remove_finished_pattern_trades__() self.__process_trade_candidates__( ) # take care of old patterns in queue if self.trade_numbers == 0: return self.__print_details_for_check_actual_trades__() self.process = 'Ticker' self.__add_tickers_for_actual_time_stamp_to_pattern_trades__() self.__adjust_stops_and_limits__() self.__calculate_wave_tick_values_for_trade_subprocess__() self.__handle_sell_triggers__() self.__handle_wrong_breakout__() self.__handle_buy_triggers__() self.__calculate_xy_values__() self.__update_ticker_lists__() # some entries could be deleted self.process = '' def __print_details_for_check_actual_trades__(self): print('check_actual_trades: {}'.format(self.trade_numbers)) for pattern_trade in self.pattern_trade_dict.values(): print('...pattern_trade.id = {}'.format(pattern_trade.id)) print('') def check_actual_trades_for_replay(self, wave_tick: WaveTick): self._last_wave_tick_for_test = wave_tick self._time_stamp_for_actual_check = MyDate.get_epoch_seconds_from_datetime( ) if self.trade_numbers == 0: return self.process = 'Replay' self.__add_tickers_for_actual_time_stamp_to_pattern_trades__() self.__adjust_stops_and_limits__() self.__calculate_wave_tick_values_for_trade_subprocess__() self.__handle_sell_triggers__() self.__set_limit_stop_loss_to_replay_values__() self.__handle_wrong_breakout__() self.__handle_buy_triggers__() self.__calculate_xy_values__( ) # ToDo - what if _calculate_xy_values is before??? self.__calculate_replay_status__() self.process = '' def get_latest_tickers_as_wave_tick_list(self, ticker_id: str) -> WaveTickList: trade_client = self.__get_trade_client_for_symbol__(ticker_id) if trade_client: return trade_client.get_latest_tickers_as_wave_tick_list( ticker_id, self.sys_config.period, self.sys_config.period_aggregation) def get_rows_for_dash_data_table(self): return_list = [] for pattern_trade in self.pattern_trade_dict.values(): return_list.append(pattern_trade.get_row_for_dash_data_table()) return return_list def remove_trade_from_dash_data_table(self, pattern_trade_id: str): pattern_trade = self.pattern_trade_dict[pattern_trade_id] if pattern_trade.status == PTS.EXECUTED: self.__handle_trade_cancellation__(pattern_trade) self.__delete_entries_from_pattern_trade_dict__([pattern_trade_id], PDR.TRADE_CANCELLED) def __calculate_replay_status__(self): for pattern_trade in self.pattern_trade_dict.values(): if pattern_trade.is_wrong_breakout: self._replay_status = RST.STOP def __set_limit_stop_loss_to_replay_values__(self): for pattern_trade in self.pattern_trade_dict.values(): pattern_trade.set_limit_stop_loss_to_replay_values() def __get_pattern_trade_for_replay__(self): for pattern_trade in self.pattern_trade_dict.values(): return pattern_trade def get_pattern_trade_data_frame_for_replay(self): if self._pattern_trade_for_replay is not None: return self._pattern_trade_for_replay.get_data_frame_for_replay() def enforce_sell_at_end( self, last_wave_tick: WaveTick): # it is used for back-testing self._last_wave_tick_for_test = last_wave_tick for pattern_trade in self.__get_pattern_trade_dict_by_status__( PTS.EXECUTED).values(): pattern_trade.print_state_details_for_actual_wave_tick( PTHP.HANDLE_SELL_TRIGGERS) self.__handle_sell_trigger__(pattern_trade, ST.PATTERN_END) def __process_trade_candidates__(self): if self.process != '': return self.process = 'HandleTradeCandidates' for trade_candidate in self.trade_candidate_controller.get_pattern_trade_candidates_for_processing( ): self.__process_trade_candidate__(trade_candidate) self.__remove_outdated_pattern_trades_in_status_new__() self.process = '' def __process_trade_candidate__(self, trade_candidate: TradeCandidate): pattern_trade = trade_candidate.pattern_trade if self.__is_similar_trade_already_available__(pattern_trade): self.trade_candidate_controller.add_pattern_trade_to_black_buy_trigger_list( pattern_trade, BLR.SIMILAR_AVAILABLE) return pattern_trade.was_candidate_for_real_trading = trade_candidate.is_candidate_for_real_trading print('{}: candidate_for_real_trading: {}'.format( pattern_trade.id, pattern_trade.was_candidate_for_real_trading)) if trade_candidate.is_candidate_for_real_trading: pattern_trade.is_simulation = False # REAL Trading print('Trade was initiated by is_candidate_for_real_trading: {}'. format(pattern_trade.id)) elif pattern_trade.buy_trigger in self.exchange_config.default_trade_strategy_dict: buy_trigger = pattern_trade.buy_trigger if pattern_trade.trade_strategy == self.exchange_config.default_trade_strategy_dict[ buy_trigger]: pattern_trade.is_simulation = False # REAL Trading print( 'Trade was initiated by default_trade_strategy: {}'.format( pattern_trade.id)) self.__add_pattern_trade_to_trade_dict__(pattern_trade) @staticmethod def __print_details_after_setting_to_real_trade__( self, prefix: str, pattern_trade: PatternTrade): print('Trade was initiated by default_trade_strategy for {}'.format( pattern_trade.id)) def __is_similar_trade_already_available__( self, trade_comp: PatternTrade) -> bool: for pattern_trade in self.pattern_trade_dict.values(): if pattern_trade.pattern.pattern_type == trade_comp.pattern.pattern_type: if pattern_trade.pattern.ticker_id == trade_comp.pattern.ticker_id: return True return False def __add_pattern_trade_to_trade_dict__(self, pattern_trade: PatternTrade): if pattern_trade.pattern.ticker_id not in self.ticker_id_list: self.ticker_id_list.append(pattern_trade.pattern.ticker_id) pattern_trade.pattern.print_nearest_neighbor_collection() if pattern_trade.id in self.pattern_trade_dict: pass # if self.pattern_trade_dict[pattern_trade.id].status == PTS.NEW: # replace with new version # self.pattern_trade_dict[pattern_trade.id] = pattern_trade # self.__print_details_after_adding_to_trade_dict(pattern_trade, 'Replace') else: pattern_trade.trade_client = self.__get_trade_client_for_symbol__( pattern_trade.ticker_id) self.pattern_trade_dict[pattern_trade.id] = pattern_trade self.__print_details_after_adding_to_trade_dict__( pattern_trade, 'Add') def __print_details_after_adding_to_trade_dict__( self, pattern_trade: PatternTrade, scope: str): time_now = MyDate.get_time_str_from_datetime() prefix = 'Adding to trade_dict' if scope == 'Add' else 'Replacing in trade_dict' print('{}: {}{}...: {}'.format(time_now, prefix, pattern_trade.id_suffix, pattern_trade.id)) self.sys_config.file_log.log_trade(pattern_trade.id_for_logging, process='Trade_Handler', process_step=scope) def __remove_outdated_pattern_trades_in_status_new__(self): # remove trades which doesn't belong to an actual pattern anymore if self.sys_config.exchange_config.delete_vanished_patterns_from_trade_dict: deletion_key_list = [ key for key, trades in self.__get_pattern_trade_dict_by_status__( PTS.NEW).items() if trades.pattern.id not in self.trade_candidate_controller.actual_pattern_id_list ] self.__delete_entries_from_pattern_trade_dict__( deletion_key_list, PDR.PATTERN_VANISHED) def sell_on_fibonacci_cluster_top(self): self._trade_client_crypto.delete_all_orders() self._trade_client_crypto.sell_all_assets() self.__clear_internal_lists__() def __get_current_wave_tick_for_ticker_id__(self, ticker_id: str) -> WaveTick: if self._last_wave_tick_for_test: return self._last_wave_tick_for_test else: trade_client = self.__get_trade_client_for_symbol__(ticker_id) print('__get_current_wave_tick_for_ticker_id__: ticker_id='.format( ticker_id)) return trade_client.get_current_wave_tick( ticker_id, self.sys_config.period, self.sys_config.period_aggregation) def __get_balance_by_symbol__(self, symbol: str): trade_client = self.__get_trade_client_for_symbol__(symbol) return trade_client.get_balance(symbol) def __clear_internal_lists__(self): self.ticker_id_list = [] self.pattern_trade_dict = {} def __add_tickers_for_actual_time_stamp_to_pattern_trades__(self): for pattern_trade in self.pattern_trade_dict.values(): wave_tick = self.__get_current_wave_tick_for_ticker_id__( pattern_trade.ticker_id) pattern_trade.add_ticker(wave_tick) print('{}: add_tickers_for_actual_time_stamp_to_pattern_trades: END'. format(MyDate.get_time_from_datetime())) # ToDo - remove after checks def __handle_sell_triggers__(self): # print('__handle_sell_triggers__.sys_config.config.save_trade_data={}'.format( # self.sys_config.config.save_trade_data)) for pattern_trade in self.__get_pattern_trade_dict_by_status__( PTS.EXECUTED).values(): ticker_last_price = pattern_trade.ticker_actual.last_price pattern_trade.print_state_details_for_actual_ticker( PTHP.HANDLE_SELL_TRIGGERS) if pattern_trade.are_forecast_ticks_sell_triggers( ticker_last_price) and False: # ToDo - too early.... self.__handle_sell_trigger__(pattern_trade, ST.FORECAST_TICKS) if pattern_trade.stop_loss_current > ticker_last_price: self.__handle_sell_trigger__(pattern_trade, ST.STOP_LOSS) elif pattern_trade.limit_current < ticker_last_price: self.__handle_sell_trigger__(pattern_trade, ST.LIMIT) elif pattern_trade.was_sell_limit_already_broken(): self.__handle_sell_trigger__(pattern_trade, ST.PEAK_LIMIT) elif pattern_trade.time_stamp_end < self._time_stamp_for_actual_check: self.__handle_sell_trigger__(pattern_trade, ST.PATTERN_END) elif not self.trade_candidate_controller.is_pattern_id_in_actual_pattern_id_list( pattern_trade.pattern.id): if self.exchange_config.finish_vanished_trades: self.__handle_sell_trigger__(pattern_trade, ST.PATTERN_VANISHED) def __handle_trade_cancellation__(self, pattern_trade: PatternTrade): ticker = pattern_trade.ticker_actual last_price = ticker.last_price actual_stop_loss = pattern_trade.stop_loss_current distance = round(abs(ticker.last_price - actual_stop_loss), 2) comment = 'Trailing stop: distance={:.2f}, actual={:.2f} on {}'.format( distance, last_price, ticker.date_time_str) print('Sell: {}'.format(comment)) ticker_id = pattern_trade.ticker_id if self.trade_process == TP.ONLINE: order_status = pattern_trade.trade_client.create_sell_trailing_stop_order( ticker_id, pattern_trade.executed_amount, distance, pattern_trade.is_simulation) else: order_status = self.__get_order_status_testing__( PTHP.HANDLE_SELL_TRIGGERS, pattern_trade, ST.CANCEL) pattern_trade.set_order_status_sell(order_status, ST.CANCEL, comment) pattern_trade.save_trade() def __handle_sell_trigger__(self, pattern_trade: PatternTrade, sell_trigger: str): sell_comment = pattern_trade.get_sell_comment(sell_trigger) print('Sell: {}'.format(sell_comment)) self.sys_config.file_log.log_message( log_message= 'Trade.ID={}, self.trade_process={}, sys_config.config.save_trade_data={}' .format(pattern_trade.id, self.trade_process, self.sys_config.config.save_trade_data), process='Save trade', process_step='handle_sell_trigger') if self.trade_process == TP.ONLINE: order_status = pattern_trade.trade_client.create_sell_market_order( pattern_trade.ticker_id, pattern_trade.executed_amount, pattern_trade.is_simulation) else: order_status = self.__get_order_status_testing__( PTHP.HANDLE_SELL_TRIGGERS, pattern_trade, sell_trigger) if order_status is None: self.__delete_entries_from_pattern_trade_dict__([pattern_trade.id], PDR.SELL_PROBLEM) else: pattern_trade.set_order_status_sell(order_status, sell_trigger, sell_comment) pattern_trade.save_trade() self.sys_config.sound_machine.play_alarm_after_sell( pattern_trade.trade_result_pct) self.sys_config.file_log.log_trade( log_message='{}: {}, Result: {}'.format( pattern_trade.id_for_logging, sell_trigger, pattern_trade.trade_result_pct), process='Trade_Handler', process_step='Sell') def __handle_wrong_breakout__(self): deletion_key_list = [] for key, pattern_trade in self.__get_pattern_trade_dict_by_status__( PTS.NEW).items(): # print('__handle_wrong_breakout__: pattern_trade.id={}, pattern_trade.trade_process={}'.format( # pattern_trade.id, pattern_trade.trade_process # )) if pattern_trade.is_actual_ticker_wrong_breakout( PTHP.HANDLE_WRONG_BREAKOUT): deletion_key_list.append(key) self.news_handler.add_news( 'Wrong breakout', 'at {} on {}'.format( pattern_trade.ticker_actual.last_price, pattern_trade.ticker_actual.date_time_str)) self.__delete_entries_from_pattern_trade_dict__( deletion_key_list, PDR.WRONG_BREAKOUT) def __remove_finished_pattern_trades__(self): deletion_key_list = [ key for key in self.__get_pattern_trade_dict_by_status__(PTS.FINISHED) ] self.__delete_entries_from_pattern_trade_dict__( deletion_key_list, PDR.TRADE_FINISHED) def __delete_entries_from_pattern_trade_dict__(self, deletion_key_list: list, deletion_reason: str): if len(deletion_key_list) == 0: return for key in deletion_key_list: pattern_trade = self.pattern_trade_dict[key] print('Removed from trade_dict ({}): {}'.format( deletion_reason, pattern_trade.get_trade_meta_data())) self.sys_config.file_log.log_trade('{}: {}'.format( pattern_trade.id_for_logging, deletion_reason), process='Trade_Handler', process_step='Delete') if self.trade_candidate_controller.is_deletion_reason_candidate_for_black_buy_pattern_id_list( pattern_trade, key): self.trade_candidate_controller.add_pattern_trade_to_black_buy_trigger_list( pattern_trade, deletion_reason) del self.pattern_trade_dict[key] self.__update_ticker_lists__() def __handle_buy_triggers__(self): deletion_key_list = [] buying_deletion_key_list = [] for key, pattern_trade in self.__get_pattern_trade_dict_by_status__( PTS.NEW).items(): pattern_trade.correct_simulation_flag_according_to_forecast() pattern_trade.data_dict_obj.add(DC.LIMIT, pattern_trade.limit_current) pattern_trade.data_dict_obj.add(DC.STOP, pattern_trade.stop_loss_current) if pattern_trade.is_actual_ticker_breakout( PTHP.HANDLE_BUY_TRIGGERS): if pattern_trade.are_preconditions_for_breakout_buy_fulfilled( ): self.__set_breakout_after_checks__(pattern_trade) if pattern_trade.pattern.breakout is not None: # pattern_trade.print_details_for_data_frame_for_replay() # ToDo remove this after check ticker_id = pattern_trade.pattern.ticker_id limit_for_extended_pdh = pattern_trade.wave_tick_actual.position + 1 extended_pdh = pattern_trade.pattern.sys_config.get_extended_pdh( ticker_id=ticker_id, limit=limit_for_extended_pdh) pattern_trade.pattern.add_part_entry(extended_pdh) self.__handle_buy_trigger_for_pattern_trade__( pattern_trade) if pattern_trade.order_status_buy is None: # there were problems with buying... buying_deletion_key_list.append(key) else: deletion_key_list.append(key) else: pattern_trade.verify_watching() self.__delete_entries_from_pattern_trade_dict__( deletion_key_list, PDR.BUYING_PRECONDITION_PROBLEM) self.__delete_entries_from_pattern_trade_dict__( buying_deletion_key_list, PDR.BUYING_PROBLEM) def __set_breakout_after_checks__(self, pattern_trade: PatternTrade): wave_tick_list = self.__get_latest_tickers_as_wave_ticks__( pattern_trade.ticker_id, pattern_trade) tick_previous = wave_tick_list.tick_list[-2] tick_current = wave_tick_list.tick_list[-1] pattern_breakout = pattern_trade.pattern.get_pattern_breakout( tick_previous, tick_current, True) if pattern_breakout.is_breakout_a_signal( ) or pattern_breakout.breakout_direction == FD.DESC: pattern_trade.pattern.breakout = pattern_breakout pattern_trade.pattern.function_cont.tick_for_breakout = tick_current self.news_handler.add_news('Breakout', 'OK') else: breakout_problems = ', '.join( [key for key in pattern_breakout.check_dict]) breakout_problems = '{}: {}'.format(pattern_trade.ticker_id, breakout_problems) self.news_handler.add_news('Breakout problems', breakout_problems) print('Breakout problems: {}'.format(breakout_problems)) def __get_latest_tickers_as_wave_ticks__(self, ticker_id, pattern_trade: PatternTrade): trade_client = self.__get_trade_client_for_symbol__(ticker_id) if trade_client is None: return pattern_trade.wave_tick_list return trade_client.get_latest_tickers_as_wave_tick_list( ticker_id, self.sys_config.period, self.sys_config.period_aggregation) def __calculate_wave_tick_values_for_trade_subprocess__(self): for pattern_trade in self.pattern_trade_dict.values(): pattern_trade.calculate_wave_tick_values_for_trade_subprocess() def __calculate_xy_values__(self): for pattern_trade in self.pattern_trade_dict.values(): pattern_trade.calculate_xy_for_replay() def __handle_buy_trigger_for_pattern_trade__(self, pattern_trade: PatternTrade): pattern_trade.set_status_in_execution() # to avoid a second execution ticker = pattern_trade.ticker_actual buy_comment = '{}-{}-{} at {} on {}'.format( ticker.ticker_id, pattern_trade.buy_trigger, pattern_trade.trade_strategy, ticker.last_price, ticker.date_time_str) print('Handle_buy_trigger_for_pattern_trade: {}'.format(buy_comment)) self.sys_config.file_log.log_trade('{}'.format( pattern_trade.id_for_logging), process='Trade_Handler', process_step='Buy') if self.trade_process == TP.ONLINE: order_status = pattern_trade.trade_client.buy_available( ticker.ticker_id, ticker.last_price, pattern_trade.is_simulation) if order_status is None: # e.g. not enough money available... message = '{} - Problem: {}'.format( pattern_trade.id_for_logging, pattern_trade.trade_client.transaction_step) self.sys_config.file_log.log_trade(log_message=message, process='Trade_Handler', process_step='Buy') return else: order_status = self.__get_order_status_testing__( PTHP.HANDLE_BUY_TRIGGERS, pattern_trade) pattern_trade.set_order_status_buy(order_status, buy_comment, ticker) pattern_trade.save_trade() self.sys_config.sound_machine.play_alarm_buy() def __get_order_status_testing__(self, process: str, pattern_trade: PatternTrade, sell_trigger=''): ticker = pattern_trade.ticker_actual order_status = OrderStatus() order_status.order_id = ticker.time_stamp order_status.symbol = ticker.ticker_id order_status.exchange = 'Test' if process == PTHP.HANDLE_BUY_TRIGGERS: order_status.price = pattern_trade.get_actual_buy_price( pattern_trade.buy_trigger, ticker.last_price) else: order_status.price = pattern_trade.get_actual_sell_price( sell_trigger, ticker.last_price) order_status.avg_execution_price = ticker.last_price order_status.side = OS.BUY if process == PTHP.HANDLE_BUY_TRIGGERS else OS.SELL order_status.type = OT.EXCHANGE_TRAILING_STOP if sell_trigger == ST.CANCEL else OT.EXCHANGE_MARKET order_status.time_stamp = ticker.time_stamp if process == PTHP.HANDLE_BUY_TRIGGERS: order_status.executed_amount = round( self.exchange_config.buy_order_value_max / ticker.last_price, 2) else: order_status.executed_amount = pattern_trade.data_dict_obj.get( DC.BUY_AMOUNT) order_status.remaining_amount = 0 order_status.original_amount = order_status.executed_amount order_status.print_order_status( ) # ToDo: Get rid of this print after a while... return order_status def __adjust_stops_and_limits__(self): for pattern_trade in self.__get_pattern_trade_dict_by_status__( PTS.EXECUTED).values(): pattern_trade.adjust_trade_box_to_actual_ticker() pattern_trade.adjust_data_dict_to_actual_ticker() def __create_trailing_stop_order_for_all_executed_trades__(self): for pattern_trade in self.__get_pattern_trade_dict_by_status__( PTS.EXECUTED).values(): ticker_id = pattern_trade.ticker_id amount = pattern_trade.order_status_buy.executed_amount distance = pattern_trade.trailing_stop_distance pattern_trade.order_status_sell = pattern_trade.trade_client.create_sell_trailing_stop_order( ticker_id, amount, distance, pattern_trade.is_simulation) def __update_ticker_lists__(self): self.ticker_id_list = [] for pattern_trade in self.pattern_trade_dict.values(): if pattern_trade.ticker_id not in self.ticker_id_list: self.ticker_id_list.append(pattern_trade.ticker_id) def __get_pattern_trade_dict_by_status__(self, status: str) -> dict: return { key: trade for key, trade in self.pattern_trade_dict.items() if trade.status == status }
def __get_news_handler__(): delimiter = ' \n - ' # news are a list in markdown return NewsHandler(delimiter, '- no news -')