def _build_url(self, exchange: str, symbols: List[str],
                   start_epoch_s: float, end_epoch_s: float) -> str:
        """
        Build url from parameters and api key
        """

        start_str = IntuitiveDateConverter.to_day_str(start_epoch_s)
        end_datetime = IntuitiveDateConverter.to_datetime(end_epoch_s)
        end_datetime += timedelta(days=1)
        end_str = IntuitiveDateConverter.to_day_str(end_datetime)
        symbols_str = ','.join(symbols)
        url = f'https://api.twelvedata.com/time_series?exchange={exchange}&symbol={symbols_str}&interval=1day&' \
              f'start_date={start_str}&end_date={end_str}&apikey={self.api_key}'

        return url
예제 #2
0
    def _build_url(self, symbol: str, start_epoch_s: float,
                   end_epoch_s: float) -> str:
        """
        Build url from parameters and api key
        """

        unit_str = 'day'
        range_str = '1'
        start_str = IntuitiveDateConverter.to_day_str(start_epoch_s)
        end_str = IntuitiveDateConverter.to_day_str(end_epoch_s)

        url = f'https://api.polygon.io/v2/aggs/ticker/{symbol}/range/{range_str}/{unit_str}/{start_str}/{end_str}?' \
            f'apiKey={self.api_key}'

        return url
 def run(self):
     all_timestamps = self.register.get_all_timestamps()
     for epoch_s in all_timestamps:
         for trader_id in range(len(self.trader_ensembles)):
             trader_ensemble = self.trader_ensembles[trader_id]
             self.trader_ensembles[trader_id].execute(
                 epoch_s, self.register)
             net_worth_mean, net_worth_median, net_worth_sd = \
                 trader_ensemble.performance.get_net_worth_estimate(epoch_s)
             cash_mean, cash_median, cash_sd = trader_ensemble.performance.get_cash_estimate(
                 epoch_s)
             date = IntuitiveDateConverter.to_day_str(epoch_s)
             self.campaign_recorder.record(
                 date, trader_id,
                 self.campaign_recorder.METRIC_NET_WORTH_MEAN,
                 net_worth_mean)
             self.campaign_recorder.record(
                 date, trader_id,
                 self.campaign_recorder.METRIC_NET_WORTH_MEDIAN,
                 net_worth_median)
             self.campaign_recorder.record(
                 date, trader_id,
                 self.campaign_recorder.METRIC_NET_WORTH_SD, net_worth_sd)
             self.campaign_recorder.record(
                 date, trader_id, self.campaign_recorder.METRIC_CASH_MEAN,
                 cash_mean)
             self.campaign_recorder.record(
                 date, trader_id, self.campaign_recorder.METRIC_CASH_MEDIAN,
                 cash_median)
             self.campaign_recorder.record(
                 date, trader_id, self.campaign_recorder.METRIC_CASH_SD,
                 cash_sd)
예제 #4
0
 def __init__(self, data_ingest_manager: DataIngestManager,
              traders: List[Trader]) -> List:
     self.data_ingest_manager = data_ingest_manager
     self.traders = traders
     self.today_day_str = IntuitiveDateConverter.to_day_str(datetime.now())
     self.today_epoch_s = IntuitiveDateConverter.to_epoch_s(
         self.today_day_str)
예제 #5
0
 def run(self, candidates: List[Stock], current_holdings: List[Stock]):
     self.today_day_str = IntuitiveDateConverter.to_day_str(datetime.now())
     self.today_epoch_s = IntuitiveDateConverter.to_epoch_s(
         self.today_day_str)
     all_stocks = candidates + current_holdings
     register = self._populate_register(all_stocks)
     signals = self.apply_traders(register, candidates, current_holdings)
     return signals
예제 #6
0
    def _run_and_evaluate_to_day_str(self,
                                     conversion_input: object,
                                     expected_output_type: type,
                                     expected_output_value: object) -> None:

        idc = IntuitiveDateConverter()
        actual_output = idc.to_day_str(conversion_input)
        actual_output_type = type(actual_output)

        self.assertEqual(expected_output_type, actual_output_type)
        self.assertEqual(expected_output_value, actual_output)
    def run(self):

        all_timestamps = self.register.get_all_timestamps()
        for epoch_s in all_timestamps:
            self.trader_ensemble.execute(epoch_s, self.register)
            net_worth_mean, net_worth_median, net_worth_sd = \
                self.trader_ensemble.performance.get_net_worth_estimate(epoch_s)
            cash_mean, cash_median, cash_sd = \
                self.trader_ensemble.performance.get_cash_estimate(epoch_s)
            date = IntuitiveDateConverter.to_day_str(epoch_s)
            print(
                f'{date}, net worth: {net_worth_mean} +- {2 * net_worth_sd} [median: {net_worth_median}], '
                f'cash: {cash_mean} +-  {2 * cash_sd} [median: {cash_median}]')
예제 #8
0
    def determine_buys(self, epoch_s: float,
                       register: SymbolDayRegister) -> List[str]:
        """
        Apply rules that trigger buy order
        """
        stocks = list(register.keys())
        random.shuffle(stocks)
        to_buy = list()
        for stock in stocks:

            buy_flag = True
            prices = [None] * (self.n_crash + 1)

            for i in range(self.n_crash):

                close_today = register.get_close(stock, epoch_s, -i)
                if close_today is None:
                    buy_flag = False
                    break

                close_yesterday = register.get_close(stock, epoch_s, -i - 1)
                if close_yesterday is None:
                    buy_flag = False
                    break

                gain = 100 * (close_today / close_yesterday - 1)
                if gain > self.gain_crash:
                    buy_flag = False
                    break

                prices[i] = close_today
                prices[i + 1] = close_yesterday

            if buy_flag:
                to_buy.append(stock)
                date = IntuitiveDateConverter.to_day_str(epoch_s)
                print(
                    f'Identified BUY flag: {date} : {stock.to_str()} : {prices}'
                )
                if self.logger is not None:
                    message = f'Identified BUY flag: {date} : {stock.to_str()} : {prices}'
                    self.logger.log_message(message)

            if len(to_buy) >= self.n_buy_per_day:
                break

        return to_buy
예제 #9
0
    def determine_sells(self, epoch_s: float,
                        register: SymbolDayRegister) -> List[str]:
        """
        Apply rules that trigger sell order
        """
        stocks = self.holdings.keys()
        to_sell = list()
        for stock in stocks:

            sell_flag = True
            prices = [None] * (self.n_down + 1)

            for i in range(self.n_down):

                close_today = register.get_close(stock, epoch_s, -i)
                if close_today is None:
                    sell_flag = False
                    break

                close_yesterday = register.get_close(stock, epoch_s, -i - 1)
                if close_yesterday is None:
                    sell_flag = False
                    break

                gain = 100 * (close_today / close_yesterday - 1)
                if gain > self.gain_down:
                    sell_flag = False
                    break

                prices[i] = close_today
                prices[i + 1] = close_yesterday

            if sell_flag:
                to_sell.append(stock)
                date = IntuitiveDateConverter.to_day_str(epoch_s)
                if self.logger is not None:
                    message = f'Identified SELL flag: {date} : {stock.to_str()} : {prices}'
                    self.logger.log_message(message)

        return to_sell
    def get_technical_indicator(self, stock: Stock, indicator_name: str,
                                start_epoch_s: float,
                                end_epoch_s: float) -> List[Moment]:

        start_date = IntuitiveDateConverter.to_day_str(start_epoch_s)
        end_datetime = IntuitiveDateConverter.to_datetime(end_epoch_s)
        end_datetime += timedelta(days=1)
        end_date = IntuitiveDateConverter.to_day_str(end_datetime)

        request_url = f'https://api.twelvedata.com/{indicator_name.lower()}?symbol=' \
                      f'{stock.symbol}&exchange={stock.exchange}&interval=1day&start_date=' \
                      f'{start_date}&end_date={end_date}&apikey={self.api_key}'

        for _ in range(MAX_RETRIES):
            try:
                print(
                    f'API call for technical indicator {indicator_name.lower()} for {stock.to_str()}'
                )
                response = requests.get(request_url)
            except ChunkedEncodingError:
                print(
                    f'intermittent ChunkedEncodingError. Retrying in {RETRY_PAUSE_CHUNK_ERROR}s'
                )
                time.sleep(RETRY_PAUSE_CHUNK_ERROR)
                print('retrying')
                continue
            except Exception as e:
                print("Stopping retry loop because of un-handled error")
                raise e
            else:
                content = response.content
                content = json.loads(content)
                if 'code' in content.keys():
                    if content['code'] == ERROR_CODE_TOO_MANY_REQUESTS:
                        print(
                            f'Too many requests. Pausing for {RETRY_PAUSE_S} seconds before retrying.'
                        )
                        time.sleep(RETRY_PAUSE_S)
                        continue

                if 'values' not in content:
                    print('unexpected response:')
                    print(content)

                break

        moments = list()

        if 'values' not in content:
            return moments

        for item in content['values']:

            epoch_s = IntuitiveDateConverter.to_epoch_s(item['datetime'])
            for k, v in item.items():

                if k == 'datetime':
                    continue

                if k == indicator_name:
                    moment_data = {
                        'epoch_s': epoch_s,
                        'exchange': stock.exchange,
                        'symbol': stock.symbol,
                        indicator_name: item[k]
                    }
                    moment = Moment(**moment_data)
                    moments.append(moment)
                else:
                    moment_data = {
                        'epoch_s': epoch_s,
                        'exchange': stock.exchange,
                        'symbol': stock.symbol,
                        f'{indicator_name}_{k}': item[k]
                    }
                    moment = Moment(**moment_data)
                    moments.append(moment)

        return moments