def deserialise_posting(posting): """Parse JSON to a Beancount Posting.""" amount = posting.get("amount") unit_price = None total_price = None if amount: if "@@" in amount: amount, raw_total_price = amount.split("@@") total_price = A(raw_total_price) elif "@" in amount: amount, raw_unit_price = amount.split("@") unit_price = A(raw_unit_price) pos = position.from_string(amount) units = pos.units if re.search(r"{\s*}", amount): cost = data.CostSpec(MISSING, None, MISSING, None, None, False) else: cost = pos.cost else: units, cost = None, None if total_price is not None: try: num = total_price.number / units.number.copy_abs() except decimal.InvalidOperation: # if both units and total price is zero, set it to zero. num = ZERO unit_price = Amount(num, total_price.currency) return data.Posting(posting["account"], units, cost, unit_price, None, None)
def deserialise_posting(posting): """Parse JSON to a Beancount Posting.""" amount = posting.get("amount") price = None if amount: if "@" in amount: amount, raw_price = amount.split("@") price = A(raw_price) pos = position.from_string(amount) units = pos.units if re.search(r"{\s*}", amount): cost = data.CostSpec(MISSING, None, MISSING, None, None, False) else: cost = pos.cost else: units, cost = None, None return data.Posting(posting["account"], units, cost, price, None, None)
def put(self): requestData = request.json postings = [] for reqPost in requestData['postings']: if 'cost' in reqPost and 'costCurrency' in reqPost: cost = data.CostSpec( D(str(reqPost['cost'])), None, reqPost['costCurrency'], None, None, None ) else: cost = None if 'amount' in reqPost and 'currency' in reqPost: amt = amount.Amount(D(str(reqPost['amount'])), reqPost['currency']) else: amt = None postings.append(data.Posting( reqPost['account'], amt, cost, None, None, None )) print(requestData) storage.addTransaction(data.Transaction( None, requestData['date'], requestData.get('flag', '*'), requestData.get('payee', None), requestData.get('naration', None), None, None, postings ), requestData['filename']) return 'ok'
def fetchSingle(self, trx): id = int(trx['id']) type = int(trx['type']) date = parse(trx['datetime']).date() posAmt = 0 posCcy = None negAmt = 0 negCcy = None for ccy in self.currencies: if ccy in trx: amt = D(trx[ccy]) if amt > 0: posAmt = amt posCcy = ccy.upper() elif amt < 0: negAmt = amt negCcy = ccy.upper() if type == 0: narration = 'Deposit' cost = data.Cost(self.priceLookup.fetchPriceAmount(posCcy, date), 'CHF', None, None) postings = [ data.Posting(self.account + ':' + posCcy, amount.Amount(posAmt, posCcy), cost, None, None, None), ] elif type == 1: narration = 'Withdrawal' postings = [ data.Posting(self.account + ':' + negCcy, amount.Amount(negAmt, negCcy), None, None, None, None), ] elif type == 2: fee = D(trx['fee']) if posCcy.lower() + '_' + negCcy.lower() in trx: feeCcy = negCcy negAmt -= fee else: feeCcy = posCcy posAmt -= fee rateFiatCcy = self.priceLookup.fetchPriceAmount(feeCcy, date) if feeCcy == posCcy: posCcyCost = None posCcyPrice = amount.Amount(rateFiatCcy, 'CHF') negCcyCost = data.CostSpec(MISSING, None, MISSING, None, None, False) negCcyPrice = None else: posCcyCost = data.CostSpec(None, D(-negAmt * rateFiatCcy), 'CHF', None, None, False) posCcyPrice = None negCcyCost = None negCcyPrice = amount.Amount(rateFiatCcy, 'CHF') narration = 'Trade' postings = [ data.Posting(self.account + ':' + posCcy, amount.Amount(posAmt, posCcy), posCcyCost, posCcyPrice, None, None), data.Posting(self.account + ':' + negCcy, amount.Amount(negAmt, negCcy), negCcyCost, negCcyPrice, None, None) ] if float(fee) > 0: postings.append( data.Posting( self.otherExpensesAccount, amount.Amount(round(fee * rateFiatCcy, 2), 'CHF'), None, None, None, None)) postings.append( data.Posting(self.capGainAccount, None, None, None, None, None)) else: raise ValueError('Transaction type ' + str(type) + ' is not handled') meta = data.new_metadata('bitstamp', id, {'ref': str(id)}) return data.Transaction(meta, date, '*', '', narration, data.EMPTY_SET, data.EMPTY_SET, postings)
from beancount.core import data, amount, account from beancount.core.number import MISSING from beancount.core.amount import Amount # create a logger logger = logging.getLogger(__name__) def parse_file(file_name): """Wrapper callback for file cache""" return parser.parse(file_name) EMPTY_COST_SPEC = data.CostSpec(number_per=MISSING, number_total=None, currency=MISSING, date=None, label=None, merge=False) @dataclasses.dataclass class CombinedTrades: tradeDate: datetime.datetime ibOrderID: str tradePrice: decimal.Decimal exchange: str multiplier: int ibCommission: decimal.Decimal symbol: str safe_symbol: str buySell: str