def process_balance(self, timestamp, prices): try: metrics = [] values = self.__context.fetch_balances(timestamp) for dto in values if values is not None else []: amount = dto.balance.bc_amnt rate = self._calculate_evaluation(dto.evaluation, prices) if dto.account is None or amount is None or rate is None: continue metric = Metric() metric.mc_type = 'balance' metric.mc_name = dto.account.ac_disp metric.mc_time = timestamp metric.mc_amnt = amount * rate metrics.append(metric) self.__context.save_metrics(metrics) except BaseException as e: self.__logger.warn('Balance : %s : %s', type(e), e.args)
def _convert_ticker(self, timestamp, prices, dto): threshold_minutes = self.__context.get_property(self._ID, 'ticker_threshold', 3) threshold_cutoff = timestamp - timedelta(minutes=int(threshold_minutes)) if dto.ticker.tk_time.replace(tzinfo=threshold_cutoff.tzinfo) < threshold_cutoff: return None price = prices.get(dto.ticker.tk_site, {}).get(dto.ticker.tk_code) if price is None or price == self._ZERO or dto.product is None: return None expiry = dto.product.pr_expr if expiry is not None and expiry.astimezone(timestamp.tzinfo) < timestamp: return None rate = self._calculate_evaluation(dto.fund, prices) if rate is None: return None metric = Metric() metric.mc_type = 'ticker' metric.mc_name = dto.product.pr_disp metric.mc_time = timestamp metric.mc_amnt = price * rate return metric
def test_save_metrics(self): self.target._create_all() dt = datetime.now() m1 = Metric() m1.mc_type = 't1' m1.mc_time = dt + timedelta(minutes=1) m1.mc_name = 'n1' m1.mc_amnt = Decimal('1.2') m2 = Metric() m2.mc_type = 't2' m2.mc_time = dt + timedelta(minutes=2) m2.mc_name = 'n2' m2.mc_amnt = Decimal('2.3') m3 = copy(m1) m3.mc_amnt = Decimal('3.4') m4 = copy(m2) m4.mc_amnt = Decimal('4.5') m5 = copy(m1) m5.mc_name = None # All new records results = self.target.save_metrics([m1, m2]) self.assertEqual(len(results), 2) self.assertTrue(m1 in results) self.assertTrue(m2 in results) # Existing records results = self.target.save_metrics([m3, None, m4]) self.assertEqual(len(results), 2) self.assertTrue(m3 in results) self.assertTrue(m4 in results) # PK Failure with self.assertRaises(BaseException): self.target.save_metrics([m5]) # Read-only self.target._is_read_only = lambda: True results = self.target.save_metrics([m1]) self.assertEqual(len(results), 0)
def process_position(self, timestamp, prices): try: metrics = [] values = self.__context.fetch_positions(timestamp) for dto in values if values is not None else []: amount = dto.position.ps_fund rate = self._calculate_evaluation(dto.fund, prices) if dto.product is None or amount is None or rate is None: continue metric = Metric() metric.mc_type = 'position@upl' metric.mc_name = dto.product.pr_disp metric.mc_time = timestamp metric.mc_amnt = amount * rate metrics.append(metric) for dto in values if values is not None else []: amount = dto.position.ps_inst rate = self._calculate_evaluation(dto.inst, prices) if dto.product is None or amount is None or rate is None: continue metric = Metric() metric.mc_type = 'position@qty' metric.mc_name = dto.product.pr_disp metric.mc_time = timestamp metric.mc_amnt = amount * rate metrics.append(metric) self.__context.save_metrics(metrics) except BaseException as e: self.__logger.warn('Position : %s : %s', type(e), e.args)
def test_Metric(self): value = Metric() self.assertEqual("{'table': 't_metric', 'type': 'None', " "'time': 'None', 'name': 'None', 'amnt': 'None'}", str(value)) value.mc_type = 'foo' value.mc_time = datetime.fromtimestamp(1234567890.123456, tz=utc) value.mc_name = 'bar' value.mc_amnt = Decimal('1.2') self.assertEqual("{'table': 't_metric', 'type': 'foo', " "'time': '2009-02-13 23:31:30.123456 UTC', 'name': 'bar', 'amnt': '1.2'}", str(value))
def process_transaction_trade(self, timestamp, prices): try: metrics = [] offset = timedelta(minutes=int( self.__context.get_property(self._ID, 'offset', 9 * 60))) t = timestamp + offset windows = { 'DAY': t.replace(microsecond=0, second=0, minute=0, hour=0) - offset, 'MTD': t.replace(microsecond=0, second=0, minute=0, hour=0, day=1) - offset, 'YTD': t.replace( microsecond=0, second=0, minute=0, hour=0, day=1, month=1) - offset, } for key, val in windows.items(): values = self.__context.fetch_transactions(val, timestamp) for dto in values if values is not None else []: inst_qty = dto.tx_net_inst fund_qty = dto.tx_net_fund inst_rate = self.calculate_evaluation(dto.ev_inst, prices) fund_rate = self.calculate_evaluation(dto.ev_fund, prices) if dto.product is None \ or inst_qty is None or fund_qty is None \ or inst_rate is None or fund_rate is None: continue metric = Metric() metric.mc_type = 'trade@' + key metric.mc_name = dto.product.pr_disp metric.mc_time = timestamp metric.mc_amnt = (inst_qty * inst_rate) + (fund_qty * fund_rate) metrics.append(metric) self.__context.save_metrics(metrics) except BaseException as e: self.__logger.warn('Transaction (trade) : %s : %s', type(e), e.args)
def process_transaction_volume(self, timestamp, prices): try: metrics = [] windows = { '12H': timestamp - timedelta(hours=12), '01D': timestamp - timedelta(hours=24), '30D': timestamp - timedelta(days=30), } for key, val in windows.items(): values = self.__context.fetch_transactions(val, timestamp) for dto in values if values is not None else []: amount = dto.tx_grs_fund rate = self.calculate_evaluation(dto.ev_fund, prices) if dto.product is None or amount is None or rate is None: continue metric = Metric() metric.mc_type = 'volume@' + key metric.mc_name = dto.product.pr_disp metric.mc_time = timestamp metric.mc_amnt = amount * rate metrics.append(metric) self.__context.save_metrics(metrics) except BaseException as e: self.__logger.warn('Transaction (volume) : %s : %s', type(e), e.args)
def process_ticker(self, timestamp): prices = None try: values = self.__context.fetch_tickers(timestamp, include_expired=True) prices = defaultdict(lambda: dict()) for dto in values if values is not None else []: ticker = dto.ticker ask = ticker.tk_ask if ticker.tk_ask != self._ZERO else None bid = ticker.tk_bid if ticker.tk_bid != self._ZERO else None ltp = ticker.tk_ltp if ticker.tk_ltp != self._ZERO else None price = None if ask is not None and bid is not None: price = (ask + bid) * self._HALF if price is None: price = ask if price is None: price = bid if price is None: price = ltp prices[ticker.tk_site][ticker.tk_code] = price metrics = [] threshold_minutes = self.__context.get_property( self._ID, 'ticker_threshold', 3) threshold_cutoff = timestamp - timedelta( minutes=int(threshold_minutes)) for dto in values if values is not None else []: if dto.ticker.tk_time.replace( tzinfo=threshold_cutoff.tzinfo) < threshold_cutoff: continue price = prices[dto.ticker.tk_site][dto.ticker.tk_code] if price is None or price == self._ZERO or dto.product is None: continue expiry = dto.product.pr_expr if expiry is not None and expiry.astimezone( timestamp.tzinfo) < timestamp: continue rate = self.calculate_evaluation(dto.fund, prices) if rate is None: continue metric = Metric() metric.mc_type = 'ticker' metric.mc_name = dto.product.pr_disp metric.mc_time = timestamp metric.mc_amnt = price * rate metrics.append(metric) self.__context.save_metrics(metrics) except BaseException as e: self.__logger.warn('Ticker : %s : %s', type(e), e.args) return prices