Exemple #1
0
class Trader():
    EXCHANGES = {'binance': Binance}
    STRATEGIES = {
        'playground': Playground,
        'macd_stochastic': MacdStochastic,
        'macd': Macd,
        'ichimoku_cloud': IchimokuCloud,
        'bollinger_bands': BollingerBands
    }

    flag = 0
    strategies = []
    history = []

    def __init__(self, config, secrets):
        for strategy in config['strategies']:
            self.strategies.append(self.STRATEGIES[strategy](self))
        self.exchange = self.EXCHANGES[config['exchange']](
            secrets['keys'][config['exchange']]['key'],
            secrets['keys'][config['exchange']]['secret'])
        self.symbol = config['symbol'].lower()
        self.interval = config['interval']
        self.reporter = Reporter(config['starting_amount'], self.exchange.FEE)

        self.type = config['type']
        if self.type == 'live':
            self.paper_trade = config['paper_trade']

        if not self.exchange.check_symbol_exists(self.symbol):
            raise SystemExit(
                'ERROR: Symbol "{symbol}" not found on exchange "{id}"'.format(
                    symbol=self.symbol, id=self.exchange.ID))

    # def start(self):

    def live_trade(self):
        # TODO: Check if user has enough funds in account if not paper trading
        # Get history so strategy has enough context
        for strategy in self.strategies:
            history_days = strategy.HISTORY_DAYS
            now = datetime.datetime.now()
            delta = datetime.timedelta(days=history_days)
            history_days_ago = now - delta
            period = {
                'start': int(history_days_ago.timestamp() * 1000),
                'end': int(now.timestamp() * 1000)
            }
            context_historical_data = self.exchange.get_historical_data(
                symbol=self.symbol.upper(),
                interval=self.interval,
                period=period)
            strategy.set_context_history(context_historical_data)

        async def start(self):
            task = asyncio.create_task(
                self.exchange.connect_to_kline(self.symbol, self.interval,
                                               self.handle_strategies))
            await task

        atexit.register(self.reporter.create_report, self.history)

        try:
            asyncio.run(start(self))
        except:
            pass

    def backtest(self, period):
        for strategy in self.strategies:
            history_days = strategy.HISTORY_DAYS
            timestamp = period['start']
            start_datetime = datetime.datetime.fromtimestamp(timestamp / 1000)
            delta = datetime.timedelta(days=history_days)
            history_days_ago = start_datetime - delta
            context_period = {
                'start': int(history_days_ago.timestamp() * 1000),
                'end': int(start_datetime.timestamp() * 1000)
            }

            context_historical_data = self.exchange.get_historical_data(
                symbol=self.symbol.upper(),
                interval=self.interval,
                period=context_period)
            strategy.set_context_history(context_historical_data)

        historical_data = self.exchange.get_historical_data(
            symbol=self.symbol.upper(), interval=self.interval, period=period)

        # Send data to strategy
        for data in historical_data:
            self.handle_strategies(data)

        # Sell leftover
        self.sell(historical_data[-1])

        self.reporter.create_report(self.history)

    def handle_strategies(self, data):
        self.history.append(data)
        signals_given = {}

        for strategy in self.strategies:
            flag = strategy.handle_new_data(data)
            signals_given[strategy] = flag

        flag_total = 0

        # Check if we wanted to sell or buy
        for strategy in self.strategies:
            flag_total += signals_given[strategy]

        flag_total /= len(self.strategies)

        if flag_total == 1.0:  # Buy
            self.buy(data)
        elif flag_total == -1.0:  # Sell
            self.sell(data)

    def buy(self, reference):
        if self.flag == 1:
            return

        if self.type == 'backtest':
            self.reporter.register_buy_reference(reference)
        elif self.type == 'live':
            print('Buying')
            if self.paper_trade == True:
                self.reporter.register_buy_reference(reference)
            elif self.paper_trade == False:
                # TODO: Send buy request to exchance. If succesfull, continue
                self.reporter.register_buy_reference(reference)

        self.flag = 1

    def sell(self, reference):
        if self.flag == -1 or self.flag == 0:
            return

        if self.type == 'backtest':
            self.reporter.register_sell_reference(reference)
        elif self.type == 'live':
            print('Selling')
            if self.paper_trade == True:
                self.reporter.register_sell_reference(reference)
            elif self.paper_trade == False:
                # TODO: Send buy request to exchance. If succesfull, continue
                self.reporter.register_sell_reference(reference)

        # Let us know we were successful (relevant for live & non paper trading)
        self.flag = -1