Ejemplo n.º 1
0
    def addStartTimeDB(self, dframe):
        '''
        Add the start time to the new column labeled Start or frc.start. Each transaction whthin a
        trade will share a start time.
        :params dframe: The output df to place the data
        :return dframe: The same dframe but with the new start data.
        '''

        rc = self._frc

        newTrade = True
        oldsymb = ''
        oldaccnt = ''
        for i, row in dframe.iterrows():

            if row[rc.ticker] != oldsymb or row[rc.acct] != oldaccnt or row[
                    rc.shares] == row[rc.bal]:
                newTrade = True
            oldsymb = row[rc.ticker]
            oldaccnt = row[rc.acct]

            if newTrade:
                newTrade = True if isNumeric(
                    row[rc.bal]) and row[rc.bal] == 0 else False
                oldTime = dframe.at[i, rc.time]
                dframe.at[i, rc.start] = oldTime

            else:
                dframe.at[i, rc.start] = oldTime
            if row[rc.bal] == 0:
                newTrade = True
        return dframe
Ejemplo n.º 2
0
    def getShares(self):
        '''
        Utility to get the number of shares in this Trade. Each TradeObject object represents a
        single trade, or the part of a trade that happens on one day, with at least 1
        transaction/ticket.
        '''
        if len(self.df.iloc[0][frc.oc]) == 0:
            # If we are here, structjour has failed to determine long/short or balance
            # With no balance set, we can still set some kind of shares for market val for the day.
            # This value provides context info for the user. Set the best we can.
            # If shares are unbalanced, this figure will be ok
            self.shares = self.df[frc.shares].sum()
            # If shares are balanced (This should never run but ...) find max purchase/sell
            if self.shares == 0:
                maxbuy = self.df[frc.shares].max()
                maxsell = self.df[frc.shares].min()
                self.shares = maxbuy if max(maxbuy, abs(maxsell)) else maxsell
            return self.shares

        if self.settings.value('inputType') == 'DB':
            return self.getSharesDB()
        elif self.shares == 0 or not isNumeric(self.shares):
            if self.side.startswith("B") or self.side.startswith("HOLD+"):
                self.shares = self.df[frc.bal].max()
            else:
                self.shares = self.df[frc.bal].min()
        return self.shares
Ejemplo n.º 3
0
 def __setMarketValue(self):
     '''
     Set the market value based on shares * price.  For incomplete trades, the info may be 
     incomplete and a NaN value produced. A value is required. Set to 0
     '''
     mkt = self.getShares() * self.df.loc[self.ix0][frc.price]
     mkt = mkt if isNumeric(mkt) else 0
     self.TheTrade.MktVal = mkt
     return self.TheTrade
Ejemplo n.º 4
0
 def updateTSID(cls, tid, tsid):
     ModelBase.connect(new_session=True)
     session = ModelBase.session
     q = session.query(Trade).filter_by(id=tid).one_or_none()
     if q:
         if not isNumeric(q.trade_sum_id) or tsid != q.trade_sum_id:
             q.trade_sum_id = tsid
             session.add(q)
             session.commit()
     session.close()
Ejemplo n.º 5
0
    def fixTsid(self, tdf):
        if len(tdf['tsid'].unique()) > 1:
            therightone = list()

            for id in tdf['tsid'].unique():
                if isNumeric(id):
                    therightone.append(id)
            if len(therightone) > 1:
                # This could be a place for user input...There are confused ids here
                # The question is what trade do these transactions belong to.
                raise ValueError(
                    'Programmers exception: Something needs to be done here')
            elif len(therightone) == 1:
                ibdb = StatementDB()
                for i, row in tdf.iterrows():
                    tdf.at[i, 'tsid'] = therightone[0]
                    ibdb.updateTSID(row['id'], therightone[0])
                # If one of the vals was nan, the column became float
                tdf = tdf.astype({'tsid': int})
                # Update the db
        return tdf
Ejemplo n.º 6
0
    def test_TheTradeObjectSetEntries(self):
        rc = FinReqCol()
        for tto in self.ttos:
            tto._TheTradeObject__setEntries()
            # if len(tto.df) < 4:
            #     self.fail('This test requires a longer sample of transactions to run.')
            count = 0
            x0 = tto.df.index[0]

            long = False
            r = tto.df.loc[x0]
            if len(r[rc.oc]) < 1 and (r[rc.side].startswith('B') or
                                      r[rc.side].lower().startswith('hold+')):
                long = True
            elif r[rc.oc] == 'O' and r[rc.shares] > 0 or r[
                    rc.oc] == 'C' and r[rc.shares] < 0:
                long = True

            # side = r[rc.side]
            for i, row in tto.df.iterrows():
                count += 1
                if (long and row[rc.shares] > 0) or (not long
                                                     and row[rc.shares] < 0):
                    if row[rc.price] != 0:
                        entry = 'Entry' + str(count)
                        ttoprice = tto.TheTrade[entry].unique()[0]
                        self.assertEqual(ttoprice, row.Price,
                                         "Failed to set entry correctly")
                else:
                    if row[rc.price] != 0:
                        entry = 'Exit' + str(count)
                        ttoprice = tto.TheTrade[entry].unique()[0]
                        self.assertEqual(ttoprice, row[rc.price],
                                         "Failed to set exit correctly")
                if row[rc.PL] != 0:
                    PLname = 'PL' + str(count)
                    ttopl = tto.TheTrade[PLname].unique()[0]
                    self.assertEqual(
                        ttopl, row[rc.PL] if isNumeric(row[rc.PL]) else 0,
                        "Failed to set pl correctly")
Ejemplo n.º 7
0
    def postProcessingDB(self, ldf):
        '''
        A few items that need fixing up. Locate and name flipped positions and overnight holds and
        change the name appropriately. Look for trades that lack a tsid (foreign key) and fix
        :params ldf: A ist of DataFrames, each DataFrame represents a trade defined by the initial
                     purchase or short of a stock, and all transactions until the transaction which
                     returns the share balance to 0.
        :return (ldf, nt): The updated versions of the list of DataFrames, and the updated single
                      DataFrame.
        '''
        rc = self._frc
        dframe = pd.DataFrame()
        for tdf in ldf:
            x0 = tdf.index[0]
            xl = tdf.index[-1]
            if tdf.at[x0, rc.bal] != tdf.at[x0,
                                            rc.shares] or tdf.at[xl,
                                                                 rc.bal] != 0:
                tdf.at[xl, rc.name] = tdf.at[xl, rc.name] + " OVERNIGHT"

            if tdf.at[x0, rc.bal] != 0:
                firstrow = True
                for i, row in tdf.iterrows():
                    # Cant fix anythintg if the balance is not set
                    if row[rc.bal] is None:
                        break
                    if firstrow:
                        side = True if row[rc.bal] > 0 else False
                        firstrow = False
                    elif row[rc.bal] != 0 and (row[rc.bal] >= 0) != side:
                        tdf.at[xl, rc.name] = tdf.at[xl, rc.name] + " FLIPPED"
                        break
            else:
                assert len(tdf) == 1
            if len(tdf['tsid'].unique()) > 1 or not isNumeric(
                    tdf['tsid'].unique()[0]):
                tdf = self.fixTsid(tdf)

            dframe = dframe.append(tdf)
        return ldf, dframe
Ejemplo n.º 8
0
 def updateBal(cls, t, balance):
     '''Uses an ongoing session. Update balance only if there is no current balance'''
     if not isNumeric(t.balance):
         t.balance = balance
         ModelBase.session.add(t)
         return t