def test_local_booking(self): fileloc = data.new_metadata('<local>', 0) date = datetime.date.today() txn = data.Transaction( fileloc, date, '*', None, "Narration", data.EMPTY_SET, data.EMPTY_SET, [ data.Posting( 'Assets:Something', MISSING, position.CostSpec(MISSING, None, MISSING, MISSING, MISSING, MISSING), MISSING, None, None) ]) expected_txn = data.Transaction( fileloc, date, '*', None, "Narration", data.EMPTY_SET, data.EMPTY_SET, [ data.Posting('Assets:Something', None, position.Cost(None, None, None, None), None, None, None) ]) actual_txn = cmptest._local_booking(txn) self.assertEqual(actual_txn, expected_txn) txn = data.Transaction( fileloc, date, '*', None, "Narration", data.EMPTY_SET, data.EMPTY_SET, [ data.Posting( 'Assets:Something', amount.Amount(MISSING, MISSING), position.CostSpec(MISSING, None, MISSING, MISSING, MISSING, MISSING), amount.Amount( MISSING, MISSING), None, None) ]) expected_txn = data.Transaction( fileloc, date, '*', None, "Narration", data.EMPTY_SET, data.EMPTY_SET, [ data.Posting('Assets:Something', amount.Amount(None, None), position.Cost(None, None, None, None), amount.Amount(None, None), None, None) ]) actual_txn = cmptest._local_booking(txn) self.assertEqual(actual_txn, expected_txn)
def Shopping(self, buy): # let's go shopping!! Shoppingbag = [] for idx, row in buy.iterrows(): # continue # debugging currency = row['currency'] currency_IBcommision = row['ibCommissionCurrency'] symbol = row['symbol'] proceeds = amount.Amount(row['proceeds'].__round__(2), currency) commission = amount.Amount((row['ibCommission'].__round__(2)), currency_IBcommision) quantity = amount.Amount(row['quantity'], symbol) price = amount.Amount(row['tradePrice'], currency) text = row['description'] number_per = D(row['tradePrice']) currency_cost = currency cost = position.CostSpec(number_per=price.number, number_total=None, currency=currency, date=row['tradeDate'], label=None, merge=False) postings = [ data.Posting(self.getAssetAccount(symbol), quantity, cost, None, None, None), data.Posting(self.getLiquidityAccount(currency), proceeds, None, None, None, None), data.Posting(self.getLiquidityAccount(currency_IBcommision), commission, None, None, None, None), data.Posting(self.getFeesAccount(currency_IBcommision), minus(commission), None, None, None, None) ] Shoppingbag.append( data.Transaction( data.new_metadata('Buy', 0), row['dateTime'].date(), self.flag, symbol, # payee ' '.join( ['BUY', quantity.to_string(), '@', price.to_string()]), data.EMPTY_SET, data.EMPTY_SET, postings)) return Shoppingbag
def Forex(self, fx): # returns beancount transactions for IBKR forex transactions fxTransactions = [] for idx, row in fx.iterrows(): symbol = row['symbol'] curr_prim, curr_sec = getForexCurrencies(symbol) currency_IBcommision = row['ibCommissionCurrency'] proceeds = amount.Amount(row['proceeds'], curr_sec) quantity = amount.Amount(row['quantity'], curr_prim) price = amount.Amount(row['tradePrice'], curr_sec) commission = amount.Amount(row['ibCommission'], currency_IBcommision) buysell = row['buySell'].name cost = position.CostSpec(number_per=None, number_total=None, currency=None, date=None, label=None, merge=False) postings = [ data.Posting(self.getLiquidityAccount(curr_prim), quantity, None, price, None, None), data.Posting(self.getLiquidityAccount(curr_sec), proceeds, None, None, None, None), data.Posting(self.getLiquidityAccount(currency_IBcommision), commission, None, None, None, None), data.Posting(self.getFeesAccount(currency_IBcommision), minus(commission), None, None, None, None) ] fxTransactions.append( data.Transaction( data.new_metadata('FX Transaction', 0), row['tradeDate'], self.flag, symbol, # payee ' '.join([ buysell, quantity.to_string(), '@', price.to_string() ]), data.EMPTY_SET, data.EMPTY_SET, postings)) return fxTransactions
def test_cost_to_str__detail(self): cost = position.CostSpec(D('101.23'), D('202.46'), 'USD', datetime.date(2015, 9, 6), "f4412439c31b", True) self.assertEqual('101.23 # 202.46 USD, 2015-09-06, "f4412439c31b", *', position.cost_to_str(cost, self.dformat)) cost = position.CostSpec(D('101.23'), D('202.46'), 'USD', datetime.date(2015, 9, 6), "f4412439c31b", False) self.assertEqual('101.23 # 202.46 USD, 2015-09-06, "f4412439c31b"', position.cost_to_str(cost, self.dformat)) cost = position.CostSpec(D('101.23'), None, 'USD', datetime.date(2015, 9, 6), None, True) self.assertEqual('101.23 USD, 2015-09-06, *', position.cost_to_str(cost, self.dformat)) cost = position.CostSpec(D('101.23'), D('202.46'), 'USD', None, None, False) self.assertEqual('101.23 # 202.46 USD', position.cost_to_str(cost, self.dformat)) cost = position.CostSpec(None, D('202.46'), 'USD', None, None, False) self.assertEqual('# 202.46 USD', position.cost_to_str(cost, self.dformat)) cost = position.CostSpec(D('101.23'), None, 'USD', None, "f4412439c31b", True) self.assertEqual('101.23 USD, "f4412439c31b", *', position.cost_to_str(cost, self.dformat)) cost = position.CostSpec(None, None, None, None, "f4412439c31b", False) self.assertEqual('"f4412439c31b"', position.cost_to_str(cost, self.dformat)) cost = position.CostSpec(None, None, 'USD', None, "f4412439c31b", True) self.assertEqual('"f4412439c31b", *', position.cost_to_str(cost, self.dformat))
def Panic(self, sale, lots): # OMG, IT is happening!! Doom=[] for idx, row in sale.iterrows(): # continue # debugging currency = row['currency'] currency_IBcommision = row['ibCommissionCurrency'] symbol = row['symbol'] proceeds = amount.Amount(row['proceeds'].__round__(2),currency) commission=amount.Amount((row['ibCommission'].__round__(2)),currency_IBcommision) quantity = amount.Amount(row['quantity'],symbol) price = amount.Amount(row['tradePrice'],currency) text=row['description'] date=row['dateTime'].date() number_per=D(row['tradePrice']) currency_cost=currency # Closed lot row follows sell row cost=None try: clo=lots.loc[idx+1] if -clo['quantity'] == row['quantity'] and clo['symbol'] == row['symbol']: cost = position.CostSpec( number_per=0 if self.suppressClosedLotPrice else clo['tradePrice'], number_total=None, currency=clo['currency'], date=clo['openDateTime'].date(), label=None, merge=False) except: pass if cost is None: # provide an empty {} cost spec (otherwise beancount can't match the lot) cost=position.CostSpec( number_per=None, number_total=None, currency=None, date=None, label=None, merge=False) lotpostings = [ data.Posting(self.getAssetAccount(symbol), amount.Amount(-clo['quantity'],clo['symbol']), cost, price, None, None) ] postings=[ # data.Posting(self.getAssetAccount(symbol), # this first posting is probably wrong # quantity, None, price, None, None), data.Posting(self.getLiquidityAccount(currency), proceeds, None, None, None, None) ] + \ lotpostings + \ [data.Posting(self.getPNLAccount(symbol), None, None, None, None, None), data.Posting(self.getLiquidityAccount(currency_IBcommision), commission, None, None, None, None), data.Posting(self.getFeesAccount(currency_IBcommision), minus(commission),None, None, None, None) ] Doom.append( data.Transaction(data.new_metadata('Buy',0), date, self.flag, symbol, # payee ' '.join(['SELL', quantity.to_string() , '@', price.to_string() ]), data.EMPTY_SET, data.EMPTY_SET, postings )) return Doom
def Panic(self, sale, lots): # OMG, IT is happening!! Doom = [] for idx, row in sale.iterrows(): # continue # debugging currency = row['currency'] currency_IBcommision = row['ibCommissionCurrency'] symbol = row['symbol'] proceeds = amount.Amount(row['proceeds'].__round__(2), currency) commission = amount.Amount((row['ibCommission'].__round__(2)), currency_IBcommision) quantity = amount.Amount(row['quantity'], symbol) price = amount.Amount(row['tradePrice'], currency) text = row['description'] date = row['dateTime'].date() number_per = D(row['tradePrice']) currency_cost = currency # Closed lot rows (potentially multiple) follow sell row lotpostings = [] sum_lots_quantity = 0 # mylots: lots closed by sale 'row' # symbol must match; begin at the row after the sell row # we do not know the number of lot rows; stop iteration if quantity is enough mylots = lots[(lots['symbol'] == row['symbol']) & (lots.index > idx)] for li, clo in mylots.iterrows(): sum_lots_quantity += clo['quantity'] if sum_lots_quantity > -row['quantity']: # oops, too many lots (warning issued below) break cost = position.CostSpec( number_per=0 if self.suppressClosedLotPrice else round( clo['tradePrice'], 2), number_total=None, currency=clo['currency'], date=clo['openDateTime'].date(), label=None, merge=False) lotpostings.append( data.Posting( self.getAssetAccount(symbol), amount.Amount(-clo['quantity'], clo['symbol']), cost, price, None, None)) if sum_lots_quantity == -row['quantity']: # Exact match is expected: # all lots found for this sell transaction break if sum_lots_quantity != -row['quantity']: warnings.warn(f"Lots matching failure: sell index={idx}") postings = [ # data.Posting(self.getAssetAccount(symbol), # this first posting is probably wrong # quantity, None, price, None, None), data.Posting(self.getLiquidityAccount(currency), proceeds, None, None, None, None) ] + \ lotpostings + \ [data.Posting(self.getPNLAccount(symbol), None, None, None, None, None), data.Posting(self.getLiquidityAccount(currency_IBcommision), commission, None, None, None, None), data.Posting(self.getFeesAccount(currency_IBcommision), minus(commission), None, None, None, None) ] Doom.append( data.Transaction( data.new_metadata('Buy', 0), date, self.flag, symbol, # payee ' '.join( ['SELL', quantity.to_string(), '@', price.to_string()]), data.EMPTY_SET, data.EMPTY_SET, postings)) return Doom