<jupyter_start><jupyter_text>Contents1. Basic usage of accounts2. Usage of depot container and alternative accounts (e.g., stocks)3. Handling loans  1. Basic usage of accountsDemonstrates basic usage of automatic csv-based accounts. Artificially create account with random transactionsFirst, make some random transactions to play with. They will be stored in a csv-file as if I already made an account before. You shouldn't be needed to do anything of this, when using the package yourself later.<jupyter_code># number of random transactions
N = 100

# make a random series of dates
daydiff = np.random.exponential(scale=2, size=N).round()
bdates = np.array([dt.date.today() - dt.timedelta(days=d) for d in daydiff.cumsum()])
bdates = bdates[-1::-1]
vdates = np.array([d + dt.timedelta(days=np.random.randint(3)) for d in bdates])

agent = np.array(['agent %d' % i for i in range(N)])
description = np.array(['description %d' % i for i in range(N)])
types = np.array(['type %d' % i for i in range(N)])

amounts = np.full(N, 1500, dtype=float)
negind = np.random.rand(N) > N*2 / 30 / N
amounts[negind] = -np.random.exponential(scale=100, size=negind.sum())
amounts[0] += 2300

transactions = pd.DataFrame(np.c_[bdates, vdates, agent, types, description, amounts], columns=('booking date', 
                            'value date', 'agent', 'type', 'description', 'amount'))

filename = 'ing-diba'
path = os.path.join('data', 'ing-diba')
transactions.to_csv(os.path.join(path, filename)+'.csv')<jupyter_output><empty_output><jupyter_text>Open existing ING-DiBa accountI here open the artificially created ing_diba_giro account using the existing directory structure ('./data/ing-diba') with the previously used filename. The first time this is executed there should be a message saying that 6 transactions were added from two extra csv-files found in the account folder. These two files mimick the csv-format that you get when downloading transactions from the ING-DiBA website (at least in Germany). The two files contain 4 transactions of which 2 are common to both files. The common transactions will only be added once. Hence, there are only 6 added transactions.The print command will show the current balance of the account after all transactions are processed.<jupyter_code>acc = ha.accounts.ing_diba_giro(filename, path=path)
print(acc)<jupyter_output>reading new csv-file: Umsatzanzeige_20161211.csv
adding 4 new transactions

reading new csv-file: Umsatzanzeige_20161217.csv
adding 2 new transactions

Added 6 new transactions.
ing-diba: -2969.76 EUR<jupyter_text>Showing monthly summaryYou can check and compare the sum of incoming and outgoing transactions for each recorded month. You can select which months to show by giving a (sequence of) integer(s) where 0 is the current month and larger numbers select the corresponding previous months.<jupyter_code>acc.get_monthly_balance(range(4))<jupyter_output><empty_output><jupyter_text>Alternatively, you can select months by a string of the form yyyy-mm:<jupyter_code>acc.get_monthly_balance('2016-11')<jupyter_output><empty_output><jupyter_text>Selecting transactions of a given monthHaving seen the summaries for some months you may want to see the corresponding transactions.<jupyter_code>tr, _ = acc.get_month('2016-10')
tr<jupyter_output><empty_output><jupyter_text>Selecting most recent transactionsYou can get the N most recent transactions.<jupyter_code>acc.get_last(10)<jupyter_output><empty_output><jupyter_text>Finding transactionsYou can look for specific transactions based on equality criteria for the different fields of a transaction. For example, for the amount:<jupyter_code>acc.find(amount=1500)<jupyter_output><empty_output><jupyter_text>for the dates:<jupyter_code>acc.find(vdate='20161103')
acc.find(bdate='20.08.2016')<jupyter_output><empty_output><jupyter_text>For the string fields the input is interpreted as a search pattern. All transactions which contain the given pattern in the selected field will be returned:<jupyter_code>acc.find(agent='agent 4')
acc.find(t_type='46')<jupyter_output><empty_output><jupyter_text>By default, search is case-insensitive, but you can change that:<jupyter_code>acc.find(description='DeScription 12')
acc.find(description='DeScription 12', case=True)<jupyter_output><empty_output><jupyter_text>You can also combine search across fields:<jupyter_code>acc.find(description='12', amount=1500)<jupyter_output><empty_output><jupyter_text>Visualising the transaction historyYou can plot three kinds of information. The balance of the account over time:<jupyter_code>fig = acc.plot_history()<jupyter_output><empty_output><jupyter_text>individual transaction amounts over time:<jupyter_code>fig = acc.plot_history(what='amount')<jupyter_output><empty_output><jupyter_text>or the cumulative sum of transaction amounts within a specified period (equals to balance when the time period includes all transactions):<jupyter_code>fig = acc.plot_history(startdate='01.08.2016', enddate='23.09.2016', what='cumsum')<jupyter_output><empty_output><jupyter_text>2. Usage of depot container and alternative accountsA depot is a collection of accounts. As accounts, depots are associated with a currency, but can hold accounts associated with different currencies. In overviews, the depot tries to convert the assets held in the different accounts into the currency of the depot.  Creating a depot and adding accounts<jupyter_code>dep = ha.depot('demo depot', path='data', currency='EUR')
dep.add_account(acc)
dep.account_infos<jupyter_output><empty_output><jupyter_text>Manual accounts holding a stock or similar assetYou can manage accounts with only seldom transactions manually, i.e., you can add transactions yourself. This makes, for example, sense for stocks that you expect to hold for a while. The only difference between an account holding a stock or fund is its currency which identifies the stock or fund. For automatic conversion of stock values to the currency of the depot the currency of the stock account should be a [ticker symbol](https://en.wikipedia.org/wiki/Ticker_symbol) which is listed on [Yahoo finance](https://finance.yahoo.com/lookup), as here:<jupyter_code>yah = ha.accounts.manual_current('Yahoo', path=os.path.join('data', 'manual_accounts'), 
                                 currency='YHOO')<jupyter_output><empty_output><jupyter_text>Stock accounts just use the default transaction fields such as the value date and agent. Amount is the number of stocks that were bought or sold. Description can be anything and the transaction type may hold information about the price of the stock at the time of the transaction, although this is currently not used anywhere.<jupyter_code>yah.add_transaction('23.04.2007', agent='me', desc='buy', amount=145, 
                    t_type='buying rate: 28.70 USD')
yah.add_transaction('01.12.2008', agent='me', desc='sell (need cash)', amount=-45, 
                    t_type='selling rate: 12.20 USD')
yah.transactions<jupyter_output><empty_output><jupyter_text>You can store stocks which are not listed on Yahoo, or for which you can't find a ticker symbol using their [International Securities Identification Number (ISIN)](https://en.wikipedia.org/wiki/International_Securities_Identification_Number) as currency, but these can currently not be automatically converted to other currencies.<jupyter_code>stx = ha.accounts.manual_current('dbxtrack_stoxx_50', path=os.path.join('data', 'manual_accounts'),
                                 currency='LU0380865021')
stx.add_transaction('13.08.2013', 'me', 'buy', 139, t_type='buying rate: 34.52 EUR')<jupyter_output><empty_output><jupyter_text>adding the two stock accounts to the depot<jupyter_code>dep.add_account(yah)
dep.add_account(stx)
dep.account_infos<jupyter_output><empty_output><jupyter_text>Manual account holding bitcoinA bitcoin account is just another account with currency 'BTC' or 'XBT'. It can be automatically converted to other currencies based on the current price of bitcoin. You can use the automatic csv-account, if you have csv-files for your transactions from somewhere, or handle the bitcoin transactions manually as here:<jupyter_code>btc = ha.accounts.manual_current('bitcoin', path=os.path.join('data', 'manual_accounts'),
                                 currency='BTC')
btc.add_transaction('20.04.2016', 'me', 'buy', 6.5382, t_type='buying rate: 391.3129 EUR')
dep.add_account(btc)<jupyter_output><empty_output><jupyter_text>Showing an overview over assets in the depotFinally, putting it all together, you can get an overview over your current financial situation in the currency of the depot. The balance of accounts with inconvertible currencies will be returned in a list. The others are shown in a pie plot.<jupyter_code>inconvertible = dep.show_overview()
inconvertible<jupyter_output>/media/bitzer/Data/Projekte/accounts/homeaccounting/conversions.py:93: UserWarning: converter: unexpected error (could not convert string to float: 'N/A') during conversion, returning NaN!
  'returning NaN!'.format(err))
/media/bitzer/Data/Projekte/accounts/homeaccounting/conversions.py:39: UserWarning: converter: cannot currently convert assets to or from ISIN, returning NaN!
  warn('converter: cannot currently convert assets to or from ISIN, '<jupyter_text>Get the age of held or sold units of the assets in the accountsIn some countries it may be interesting for tax purposes to know how long you have held an asset before selling it off again. The depot and individual accounts have a method which inform you about that:<jupyter_code>dep.get_ages(exclude='ing-diba')<jupyter_output><empty_output><jupyter_text>The table shows for all accounts except the ing-diba current account the currently held assets together with their age (amount is positive and date is NaT) as well as the age of assets, when they were sold (negative amounts with sell date). See docstring of get_ages for more options and further information.  3. Handling loansYou have saved some money and you want to help a family member, friend or whoever in a difficult financial situation. So you give them a loan and transfer the money to them from one of your accounts. Obviously you want to keep track of their payments for paying back the loan. Perhaps you have even agreed that an interest is to be paid as defined by an [annual equivalent rate (AER)](https://en.wikipedia.org/wiki/Effective_interest_rate). This can be handled by the homeaccounting package using a `credit_subaccount`. Here's a description of how such a `credit_subaccount` is defined:<jupyter_code>print(ha.accounts.credit_subaccount.__init__.__doc__)<jupyter_output>Define a credit account based on a standard current account.
        
            The credit account is solely based on selected transactions of the
            associated current account which can either be given as index into
            the transaction list, or using search terms in the description 
            and/or agent of the transactions.
            
            Arguments
            ---------
            acc : account
                the associated current account.
                
            desc : string
                search pattern for description of transactions.
                
            aer : number (percent)
                interest rate to be payable, as `annual equivalent rate`_
            
            tr_inds : 1D numpy array, default empty array
                indeces into transaction list of acc, pointing to transactions
                which cannot be identified by the search patterns
                
            agent : string, default None
            [...]<jupyter_text>Here's the transaction I will be using as the initial payment that has been made to the borrower. This should obviously have a negative amount:<jupyter_code>init_ind = 82
trans = acc.transactions.loc[82]
trans<jupyter_output><empty_output><jupyter_text>Now I define the loan using a reference ('13EX5i') that defines later payments and should occur in the description field of the corresponding transactions. The first payment hasn't used the reference, but is given by a transaction number instead (the one chosen above). The loan has an AER of 1.3%. Payable interest is computed on a daily basis.After the `credit_subaccount` is created the current state of the loan is automatically printed. The negative 'current balance' is the amount that the borrower still needs to pay back.<jupyter_code>loan = ha.accounts.credit_subaccount(acc, '13EX5i', 1.3, 82)<jupyter_output>current balance:     -331.90
total given credit:  -331.62
accrued interest:      -0.28<jupyter_text>For demonstration purposes, I now manually add a transaction to the original account which is a payment from the borrower over half the total given credit:<jupyter_code>today = ha.accounts.parse_date(pd.datetime.today().date())
acc.transactions = pd.concat([acc.transactions, 
        pd.DataFrame([[today, today, trans.agent, trans.type,
                       'payment for loan 13EX5i', -trans.amount/2]], 
                     index=[acc.transactions.index[-1]+1], 
                     columns=acc.transactions.columns)])<jupyter_output><empty_output><jupyter_text>The state of the loan automatically adjusts:<jupyter_code>print(loan)<jupyter_output>current balance:     -166.09
total given credit:  -331.62
accrued interest:      -0.28
{'fraction_non_alphanumeric': 0.08172107268245313, 'fraction_numerical': 0.01874953312915515, 'mean_word_length': 4.728712023962345, 'pattern_counts': {'":': 0, '<': 104, '<?xml version=': 0, '>': 105, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '27', 'dir': 'jupyter-structured-clean-dedup', 'id': '384806', 'license': 'MIT', 'n_tokens_mistral': 3945, 'n_tokens_neox': 3672, 'n_words': 1419, 'path': 'examples/Homeaccounting_Demo.ipynb', 'repo_name': 'sbitzer/csv-homeaccounting', 'size': '13387'}