From b09c4d91d7b411032d400fe20e91c2fd6d9be345 Mon Sep 17 00:00:00 2001 From: Paul Bouquet Date: Mon, 1 Oct 2018 15:31:41 +0200 Subject: [PATCH] #22 [Strategy/evaluator/trading mode] add regulated markets high frequency trading --- .../InstantRegulatedMarketEvaluator.json | 4 + .../instant_fluctuations_evaluator.py | 36 +++- Trading/Mode/SimpleTradingMode.json | 0 Trading/Mode/simple_trading_mode.py | 156 ++++++++++++++++++ tentacles_list.json | 2 +- 5 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 Evaluator/RealTime/InstantRegulatedMarketEvaluator.json create mode 100644 Trading/Mode/SimpleTradingMode.json create mode 100644 Trading/Mode/simple_trading_mode.py diff --git a/Evaluator/RealTime/InstantRegulatedMarketEvaluator.json b/Evaluator/RealTime/InstantRegulatedMarketEvaluator.json new file mode 100644 index 000000000..2366760d8 --- /dev/null +++ b/Evaluator/RealTime/InstantRegulatedMarketEvaluator.json @@ -0,0 +1,4 @@ +{ + "regulated_market_price": 1, + "regulated_market_range": 0.03 +} \ No newline at end of file diff --git a/Evaluator/RealTime/instant_fluctuations_evaluator.py b/Evaluator/RealTime/instant_fluctuations_evaluator.py index 9e70ca167..ae780efa2 100644 --- a/Evaluator/RealTime/instant_fluctuations_evaluator.py +++ b/Evaluator/RealTime/instant_fluctuations_evaluator.py @@ -6,7 +6,8 @@ "type": "Evaluator", "subtype": "RealTime", "version": "1.0.0", - "requirements": [] + "requirements": [], + "config_files": ["InstantRegulatedMarketEvaluator.json"] } """ import math @@ -209,3 +210,36 @@ def set_default_config(self): def _should_eval(self): return self.should_eval + + +class InstantRegulatedMarketEvaluator(RealTimeTAEvaluator): + def __init__(self, exchange, symbol): + super().__init__(exchange, symbol) + self.last_candle_data = None + self.last_eval_note = START_PENDING_EVAL_NOTE + self.should_eval = True + self.regulated_market_config = None + + def _refresh_data(self): + new_data = self._get_data_from_exchange(self.specific_config[CONFIG_TIME_FRAME], + limit=20, return_list=False) + self.should_eval = not self._compare_data(new_data, self.last_candle_data) + self.last_candle_data = new_data + + def eval_impl(self): + self.eval_note = 0 + close_values = self.last_candle_data[PriceIndexes.IND_PRICE_CLOSE.value] + + last_price = close_values[-1] + + self.eval_note = 0 + + self.notify_evaluator_thread_managers(self.__class__.__name__) + + def set_default_config(self): + super().set_default_config() + self.specific_config[CONFIG_REFRESH_RATE] = 0.3 + self.regulated_market_config = super().get_evaluator_config() + + def _should_eval(self): + return self.should_eval \ No newline at end of file diff --git a/Trading/Mode/SimpleTradingMode.json b/Trading/Mode/SimpleTradingMode.json new file mode 100644 index 000000000..e69de29bb diff --git a/Trading/Mode/simple_trading_mode.py b/Trading/Mode/simple_trading_mode.py new file mode 100644 index 000000000..eb297a0b3 --- /dev/null +++ b/Trading/Mode/simple_trading_mode.py @@ -0,0 +1,156 @@ +""" +OctoBot Tentacle + +$tentacle_description: { + "name": "simple_trading_mode", + "type": "Trading", + "subtype": "Mode", + "version": "1.0.0", + "requirements": ["mixed_strategies_evaluator"], + "config_files": ["SimpleTradingMode.json"], + "tests":[] +} +""" + +from tools.logging.logging_util import get_logger + +from config.cst import EvaluatorStates, INIT_EVAL_NOTE, TraderOrderType +from tools.evaluators_util import check_valid_eval_note +from trading.trader.modes.abstract_mode_creator import AbstractTradingModeCreator +from trading.trader.modes.abstract_mode_decider import AbstractTradingModeDecider +from trading.trader.modes.abstract_trading_mode import AbstractTradingMode + + +class SimpleTradingMode(AbstractTradingMode): + DESCRIPTION = "SimpleTradingMode is basic trading mode, it can buy and sell with market orders." + + def __init__(self, config, exchange): + super().__init__(config, exchange) + + def create_deciders(self, symbol, symbol_evaluator): + self.add_decider(symbol, SimpleTradingModeDecider(self, symbol_evaluator, self.exchange)) + + def create_creators(self, symbol, symbol_evaluator): + self.add_creator(symbol, SimpleTradingModeCreator(self)) + + +class SimpleTradingModeCreator(AbstractTradingModeCreator): + def __init__(self, trading_mode): + super().__init__(trading_mode) + + # creates a new order + def create_new_order(self, eval_note, symbol, exchange, trader, portfolio, state): + try: + current_symbol_holding, current_market_quantity, market_quantity, price, symbol_market = \ + self.get_pre_order_data(exchange, symbol, portfolio) + + created_orders = [] + + if state in [EvaluatorStates.SHORT, EvaluatorStates.VERY_SHORT]: + # buy quantity from risk + quantity = current_symbol_holding * trader.get_risk() + + quantity += self.get_additional_dusts_to_quantity_if_necessary(quantity, price, + symbol_market, current_symbol_holding) + for order_quantity, order_price in self.check_and_adapt_order_details_if_necessary(quantity, price, + symbol_market): + market = trader.create_order_instance(order_type=TraderOrderType.SELL_MARKET, + symbol=symbol, + current_price=order_price, + quantity=order_quantity, + price=order_price) + trader.create_order(market, portfolio) + created_orders.append(market) + return created_orders + + elif state in [EvaluatorStates.LONG, EvaluatorStates.VERY_LONG]: + # buy quantity from risk + quantity = current_market_quantity * trader.get_risk() + + for order_quantity, order_price in self.check_and_adapt_order_details_if_necessary(quantity, price, + symbol_market): + market = trader.create_order_instance(order_type=TraderOrderType.BUY_MARKET, + symbol=symbol, + current_price=order_price, + quantity=order_quantity, + price=order_price) + trader.create_order(market, portfolio) + created_orders.append(market) + return created_orders + + # if nothing go returned, return None + return None + + except Exception as e: + get_logger(self.__class__.__name__).error("Failed to create order : {0}".format(e)) + return None + + +class SimpleTradingModeDecider(AbstractTradingModeDecider): + def __init__(self, trading_mode, symbol_evaluator, exchange): + super().__init__(trading_mode, symbol_evaluator, exchange) + + # If final_eval not is < X_THRESHOLD --> state = X + self.VERY_LONG_THRESHOLD = -0.85 + self.LONG_THRESHOLD = -0.25 + self.NEUTRAL_THRESHOLD = 0.25 + self.SHORT_THRESHOLD = 0.85 + + def set_final_eval(self): + strategies_counter = 0 + # Strategies analysis + for evaluated_strategies in self.symbol_evaluator.get_strategies_eval_list(self.exchange): + strategy_eval = evaluated_strategies.get_eval_note() + if check_valid_eval_note(strategy_eval): + self.final_eval += strategy_eval + strategies_counter += 1 + + if strategies_counter > 0: + self.final_eval /= strategies_counter + else: + self.final_eval = INIT_EVAL_NOTE + + def create_state(self): + if self.final_eval < self.VERY_LONG_THRESHOLD: + self._set_state(EvaluatorStates.VERY_LONG) + + elif self.final_eval < self.LONG_THRESHOLD: + self._set_state(EvaluatorStates.LONG) + + elif self.final_eval < self.NEUTRAL_THRESHOLD: + self._set_state(EvaluatorStates.NEUTRAL) + + elif self.final_eval < self.SHORT_THRESHOLD: + self._set_state(EvaluatorStates.SHORT) + + else: + self._set_state(EvaluatorStates.VERY_SHORT) + + @classmethod + def get_should_cancel_loaded_orders(cls): + return True + + def _set_state(self, new_state): + if new_state != self.state: + # previous_state = self.state + self.state = new_state + self.logger.info("{0} ** NEW FINAL STATE ** : {1}".format(self.symbol, self.state)) + + # if new state is not neutral --> cancel orders and create new else keep orders + if new_state is not EvaluatorStates.NEUTRAL: + + # cancel open orders + self.cancel_symbol_open_orders() + + # create notification + if self.symbol_evaluator.matrices: + self.notifier.notify_alert( + self.final_eval, + self.symbol_evaluator.get_crypto_currency_evaluator(), + self.symbol_evaluator.get_symbol(), + self.symbol_evaluator.get_trader(self.exchange), + self.state, + self.symbol_evaluator.get_matrix(self.exchange).get_matrix()) + + # call orders creation method + self.create_final_state_orders(self.notifier, self.trading_mode.get_only_creator_key(self.symbol)) diff --git a/tentacles_list.json b/tentacles_list.json index 923adb319..29c8f02ce 100644 --- a/tentacles_list.json +++ b/tentacles_list.json @@ -1 +1 @@ -{"instant_fluctuations_evaluator": {"name": "instant_fluctuations_evaluator", "type": "Evaluator", "subtype": "RealTime", "version": "1.0.0", "requirements": []}, "orderbook_evaluator": {"name": "orderbook_evaluator", "type": "Evaluator", "subtype": "RealTime", "version": "1.0.0", "requirements": []}, "forum_evaluator": {"name": "forum_evaluator", "type": "Evaluator", "subtype": "Social", "version": "1.0.0", "requirements": [], "config_files": ["RedditForumEvaluator.json"]}, "news_evaluator": {"name": "news_evaluator", "type": "Evaluator", "subtype": "Social", "version": "1.0.0", "requirements": [], "config_files": ["TwitterNewsEvaluator.json"]}, "stats_evaluator": {"name": "stats_evaluator", "type": "Evaluator", "subtype": "Social", "version": "1.0.0", "requirements": [], "config_files": ["GoogleTrendStatsEvaluator.json"]}, "high_frequency_strategy_evaluator": {"name": "high_frequency_strategy_evaluator", "type": "Evaluator", "subtype": "Strategies", "version": "1.0.0", "requirements": ["instant_fluctuations_evaluator"], "config_files": ["HighFrequencyStrategiesEvaluator.json"]}, "market_stability_strategy_evaluator": {"name": "market_stability_strategy_evaluator", "type": "Evaluator", "subtype": "Strategies", "version": "1.0.0", "requirements": ["instant_fluctuations_evaluator"], "config_files": ["MarketStabilityStrategiesEvaluator.json"]}, "mixed_strategies_evaluator": {"name": "mixed_strategies_evaluator", "type": "Evaluator", "subtype": "Strategies", "version": "1.0.0", "requirements": ["instant_fluctuations_evaluator", "news_evaluator"], "config_files": ["FullMixedStrategiesEvaluator.json", "InstantSocialReactionMixedStrategiesEvaluator.json", "SimpleMixedStrategiesEvaluator.json"], "tests": ["test_full_mixed_strategies_evaluator"]}, "move_signals_strategy_evaluator": {"name": "move_signals_strategy_evaluator", "type": "Evaluator", "subtype": "Strategies", "version": "1.0.0", "requirements": ["momentum_evaluator", "trend_evaluator", "instant_fluctuations_evaluator"], "config_files": ["MoveSignalsStrategyEvaluator.json"], "tests": ["test_move_signals_strategy_evaluator"]}, "momentum_evaluator": {"name": "momentum_evaluator", "type": "Evaluator", "subtype": "TA", "version": "1.0.0", "requirements": [], "tests": ["test_adx_TA_evaluator", "test_bollinger_bands_momentum_TA_evaluator", "test_macd_TA_evaluator", "test_rsi_TA_evaluator", "test_klinger_TA_evaluator"]}, "trend_evaluator": {"name": "trend_evaluator", "type": "Evaluator", "subtype": "TA", "version": "1.0.0", "requirements": [], "tests": ["test_double_moving_averages_TA_evaluator"]}, "volatility_evaluator": {"name": "volatility_evaluator", "type": "Evaluator", "subtype": "TA", "version": "1.0.0", "requirements": []}, "overall_state_analysis": {"name": "overall_state_analysis", "type": "Evaluator", "subtype": "Util", "version": "1.0.0", "requirements": []}, "pattern_analysis": {"name": "pattern_analysis", "type": "Evaluator", "subtype": "Util", "version": "1.0.0", "requirements": []}, "statistics_analysis": {"name": "statistics_analysis", "type": "Evaluator", "subtype": "Util", "version": "1.0.0", "requirements": []}, "text_analysis": {"name": "text_analysis", "type": "Evaluator", "subtype": "Util", "version": "1.0.0", "requirements": []}, "trend_analysis": {"name": "trend_analysis", "type": "Evaluator", "subtype": "Util", "version": "1.0.0", "requirements": []}, "daily_trading_mode": {"name": "daily_trading_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": ["mixed_strategies_evaluator"], "config_files": ["DailyTradingMode.json"], "tests": ["test_daily_trading_mode_creator", "test_daily_trading_mode_decider"]}, "high_frequency_mode": {"name": "high_frequency_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": ["high_frequency_strategy_evaluator"], "config_files": ["HighFrequencyMode.json"], "developing": true}, "hybrid_trading_mode": {"name": "hybrid_trading_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": ["daily_trading_mode", "high_frequency_mode", "market_stability_strategy_evaluator"], "config_files": ["HybridTradingMode.json"], "developing": true}, "investor_mode": {"name": "investor_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": [], "config_files": ["InvestorMode.json"], "developing": true}, "objective_mode": {"name": "objective_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": [], "config_files": ["ObjectiveMode.json"], "developing": true}, "opportunity_mode": {"name": "opportunity_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": [], "config_files": ["OpportunityMode.json"], "developing": true}, "safe_profit_mode": {"name": "safe_profit_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": [], "config_files": ["SafeProfitMode.json"], "developing": true}, "signal_trading_mode": {"name": "signal_trading_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": ["move_signals_strategy_evaluator", "daily_trading_mode"], "config_files": ["SignalTradingMode.json"]}} \ No newline at end of file +{"instant_fluctuations_evaluator": {"name": "instant_fluctuations_evaluator", "type": "Evaluator", "subtype": "RealTime", "version": "1.0.0", "requirements": [], "config_files": ["InstantRegulatedMarketEvaluator.json"]}, "orderbook_evaluator": {"name": "orderbook_evaluator", "type": "Evaluator", "subtype": "RealTime", "version": "1.0.0", "requirements": []}, "forum_evaluator": {"name": "forum_evaluator", "type": "Evaluator", "subtype": "Social", "version": "1.0.0", "requirements": [], "config_files": ["RedditForumEvaluator.json"]}, "news_evaluator": {"name": "news_evaluator", "type": "Evaluator", "subtype": "Social", "version": "1.0.0", "requirements": [], "config_files": ["TwitterNewsEvaluator.json"]}, "stats_evaluator": {"name": "stats_evaluator", "type": "Evaluator", "subtype": "Social", "version": "1.0.0", "requirements": [], "config_files": ["GoogleTrendStatsEvaluator.json"]}, "high_frequency_strategy_evaluator": {"name": "high_frequency_strategy_evaluator", "type": "Evaluator", "subtype": "Strategies", "version": "1.0.0", "requirements": ["instant_fluctuations_evaluator"], "config_files": ["HighFrequencyStrategiesEvaluator.json"]}, "market_stability_strategy_evaluator": {"name": "market_stability_strategy_evaluator", "type": "Evaluator", "subtype": "Strategies", "version": "1.0.0", "requirements": ["instant_fluctuations_evaluator"], "config_files": ["MarketStabilityStrategiesEvaluator.json"]}, "mixed_strategies_evaluator": {"name": "mixed_strategies_evaluator", "type": "Evaluator", "subtype": "Strategies", "version": "1.0.0", "requirements": ["instant_fluctuations_evaluator", "news_evaluator"], "config_files": ["FullMixedStrategiesEvaluator.json", "InstantSocialReactionMixedStrategiesEvaluator.json", "SimpleMixedStrategiesEvaluator.json"], "tests": ["test_full_mixed_strategies_evaluator"]}, "move_signals_strategy_evaluator": {"name": "move_signals_strategy_evaluator", "type": "Evaluator", "subtype": "Strategies", "version": "1.0.0", "requirements": ["momentum_evaluator", "trend_evaluator", "instant_fluctuations_evaluator"], "config_files": ["MoveSignalsStrategyEvaluator.json"], "tests": ["test_move_signals_strategy_evaluator"]}, "momentum_evaluator": {"name": "momentum_evaluator", "type": "Evaluator", "subtype": "TA", "version": "1.0.0", "requirements": [], "tests": ["test_adx_TA_evaluator", "test_bollinger_bands_momentum_TA_evaluator", "test_macd_TA_evaluator", "test_rsi_TA_evaluator", "test_klinger_TA_evaluator"]}, "trend_evaluator": {"name": "trend_evaluator", "type": "Evaluator", "subtype": "TA", "version": "1.0.0", "requirements": [], "tests": ["test_double_moving_averages_TA_evaluator"]}, "volatility_evaluator": {"name": "volatility_evaluator", "type": "Evaluator", "subtype": "TA", "version": "1.0.0", "requirements": []}, "overall_state_analysis": {"name": "overall_state_analysis", "type": "Evaluator", "subtype": "Util", "version": "1.0.0", "requirements": []}, "pattern_analysis": {"name": "pattern_analysis", "type": "Evaluator", "subtype": "Util", "version": "1.0.0", "requirements": []}, "statistics_analysis": {"name": "statistics_analysis", "type": "Evaluator", "subtype": "Util", "version": "1.0.0", "requirements": []}, "text_analysis": {"name": "text_analysis", "type": "Evaluator", "subtype": "Util", "version": "1.0.0", "requirements": []}, "trend_analysis": {"name": "trend_analysis", "type": "Evaluator", "subtype": "Util", "version": "1.0.0", "requirements": []}, "daily_trading_mode": {"name": "daily_trading_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": ["mixed_strategies_evaluator"], "config_files": ["DailyTradingMode.json"], "tests": ["test_daily_trading_mode_creator", "test_daily_trading_mode_decider"]}, "high_frequency_mode": {"name": "high_frequency_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": ["high_frequency_strategy_evaluator"], "config_files": ["HighFrequencyMode.json"], "developing": true}, "hybrid_trading_mode": {"name": "hybrid_trading_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": ["daily_trading_mode", "high_frequency_mode", "market_stability_strategy_evaluator"], "config_files": ["HybridTradingMode.json"], "developing": true}, "investor_mode": {"name": "investor_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": [], "config_files": ["InvestorMode.json"], "developing": true}, "objective_mode": {"name": "objective_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": [], "config_files": ["ObjectiveMode.json"], "developing": true}, "opportunity_mode": {"name": "opportunity_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": [], "config_files": ["OpportunityMode.json"], "developing": true}, "safe_profit_mode": {"name": "safe_profit_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": [], "config_files": ["SafeProfitMode.json"], "developing": true}, "signal_trading_mode": {"name": "signal_trading_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": ["move_signals_strategy_evaluator", "daily_trading_mode"], "config_files": ["SignalTradingMode.json"]}, "simple_trading_mode": {"name": "simple_trading_mode", "type": "Trading", "subtype": "Mode", "version": "1.0.0", "requirements": ["mixed_strategies_evaluator"], "config_files": ["SimpleTradingMode.json"], "tests": []}} \ No newline at end of file