Example #1
0
    def update_holdings(self, end=None):
        if not self.transactions.all():
            return

        if end is None:
            end = last_business_day()

        hlds = {}
        for txn in self.transactions.order_by('datetime').all():
            sym = txn.security.symbol

            if sym not in hlds:  # Transaction for a new security
                # find the latest holding record for this symbol
                # if found, the current transaction must has been processed in the past and will
                # be skipped below
                # if not found, start an empty holding record here
                hlds[sym] = self._get_latest_record_or_empty(txn)

            # convert date into pandas timestamp with business offset to automatically skip holidays
            hld_date = to_business_timestamp(hlds[sym].date)
            txn_date = to_business_timestamp(date_(txn.datetime))

            if txn_date < hld_date:  # already processed in the past
                continue
            elif txn_date == hld_date: # there might be multiple transactions for a day
                if not txn.processed:
                    self._transact_and_save(hlds[sym], txn)
            else: # txn_date > hld_date
                # self.fill_in_gaps(hlds[sym], pd.bdate_range(start=hld_date+1, end=txn_date-1))
                self.insert_holding(hlds[sym], txn_date)
                self._transact_and_save(hlds[sym], txn)
Example #2
0
    def update_holdings(self, end):
        if not self.transactions.all():
            return

        hlds = {}
        for txn in self.transactions.all():
            sym = txn.security.symbol

            if sym not in hlds:  # Transaction for a new security
                # find the latest holding record for this symbol
                # if found, the current transaction must has been processed in the past and will
                # be skipped below
                # if not found, start an empty holding record here
                hlds[sym] = self.get_latest_record_or_empty(txn)

            # convert date into pandas timestamp with business offset to automatically skip holidays
            # note holding record is kept for every business day, so detail time of the transaction
            # is stripped off.
            hld_date = to_business_timestamp(hlds[sym].date)
            txn_date = to_business_timestamp(date_(txn.datetime))

            if txn_date < hld_date:  # already processed in the past
                continue
            elif txn_date == hld_date: # there might be multiple transactions for a day
                self._transact_and_save(hlds[sym], txn)
            else: # txn_date > hld_date
                self.fill_in_gaps(hlds[sym], pd.bdate_range(start=hld_date+1, end=txn_date-1))
                self.insert_holding(hlds[sym], txn_date)
                self._transact_and_save(hlds[sym], txn)

        # fill the gaps between last transaction and end
        for sym, hld in hlds.items():
            self.fill_in_gaps(hld, pd.bdate_range(start=to_business_timestamp(hld.date)+1, end=end))
Example #3
0
    def update_db(cls):
        last_db_date = INIT_DATE
        exchange = Exchange()

        if ExchangeRate.objects.all():
            last_db_date = ExchangeRate.objects.order_by('date').last().date
            last_db_date = pd.Timestamp(last_db_date, offset='B')+1

        for d in pd.bdate_range(start=last_db_date, end=last_business_day()):
            rates = exchange.historical_rates(d)
            for c in CURRENCY_CHOICES:
                if c[0] == BASE_CURRENCY:
                    continue
                cls.objects.create(date=date_(d), currency=c[0],
                                   rate=exchange.exchange(1, c[0], BASE_CURRENCY, rates))
Example #4
0
 def _get_latest_record_or_empty(self, txn):
     try:
         return self.holdings.filter(security=txn.security).latest()
     except Holding.DoesNotExist:
         return Holding(security=txn.security, portfolio=self, date=date_(txn.datetime))