Can software engineering be likened to energy creation and waste management?

Creating energy is a difficult thing, it is very hard to get more out than you put in and without creating a heap of waste that you have to take care of somehow and that potentially could drown you. Lately I have been likening software engineering to this when I want to illustrate the problems for non-techies and get a point across.

Developing software is not easy and if you want to get more value out than you put in it can be a real tough nut to crack. Personally I have never had much interest in doing consultancy work because then you are simply selling hours and you have no way of getting more value out than you put in.

Yes, investing in creating products where the value creation is more than the hours put in is risky but it is a risk that I would gladly take any given day. I would always go for trying to create fusion power as opposed to burning coal. Life is about taking risks so don’t leave this one without having lived it.

When you start a new venture it is important to get to an MVP as quickly as possible so that you can start getting feedback. During this period it is acceptable to take a bunch of shortcuts when developing which will result in some technical debt. I liken this to producing some dirty energy where you will have to deal with the waste products somehow.

The rationale is that if the MVP is a success and you find product market fit it is worth investing more in the development and also start cleaning up some of that waste. As you are able to apply more and more resources you will be able to produce cleaner and cleaner “energy” with less and less waste.

You have to watch out for scope creep with regards to the MVP though. I bet that your first hypothesis of your MVP will not be correct. That is natural, just make sure that it does not drag out too much. Each change that you have to make while creating dirty energy from your development efforts builds up that pile of waste. You have to get around to doing some cleaning before it is too late.

Don’t forget about the waste

Even if you manage to get the MVP right it can be easy for everyone to get caught up in the excitement and continue to implement new and cool features. This is another serious trap! The only remedy that I know of is to make sure everyone is aligned around this concept from the start. There is certainly a speed limit that should apply to how fast an organization is moving in relationship to its available resources.

The creative process always takes time and you need to have time for designing, trying things out and then re-designing. Startups are almost always cash strapped and must be very careful about where time is invested. Don’t find yourself in a hot market with a hot product and realize that you need to stop everything for a few years and take care of waste! Trust me, I have been there! 🥶

Programming financial transactions

One of the simplest yet most complex and important element of finance is the transaction! When building financial software it has always been a struggle in each project until we have been able to nail down the transaction engine.

If you go too shallow when building this thing it will come back and bite you since you will be limited with future functionality. Building it deep enough when it comes to granularity takes a lot of time and testing. You want to make sure that the solution is configurable and dynamic enough to not fall over when you introduce new use cases.

In my earlier years as a FinTech developer focusing on wealth management solutions this is where my hair started to become thinner 😁.

I wanted to do this once and for all and never have to care about it again ever in my life so Bricknode came to be!

This article is not about explaining all the secret details how we got this fantastic transactional engine to work, some of the secrets are shared here, but rather spread the knowledge about how to use it.

The learning curve is not that steep and once you grasp this you will see how you can build any type of financial application without inventing the wheel again.

To make it even simpler I have decided to share a code project in GitHub which you can use as much as you want to play around with this. It is called Bricknode Broker Utilities and I will add more and more interesting functionality to illustrate.

Bricknode Broker Utilities

Except for the really cool graphics this application will illustrate how to work with the API and I have inputted my instance of Bricknode Broker into the user secrets.

In the image below I have successfully logged on to this application and the menu with the available functions presents itself.

Awesome graphics!

The first function is for creating a transaction and the code for the transaction service looks like this:

using System.Globalization;
using BfsApi;

namespace Bricknode_Broker_Utilities.Services;

public class TransactionService
{
    private readonly BfsDataService _bfsDataService;

    public TransactionService(BfsDataService bfsDataService)
    {
        _bfsDataService = bfsDataService;
    }

    /// <summary>
    ///     This method will deposit cash into an account within the Bricknode Broker instance
    /// </summary>
    /// <returns></returns>
    public async Task DepositCash(string bfsInstanceKey)
    {
        Console.WriteLine("Account number:");
        var accountNumber = int.Parse(Console.ReadLine() ?? string.Empty);

        var account = await _bfsDataService.GetAccountByNumber(accountNumber, bfsInstanceKey);

        Console.WriteLine("Amount to deposit:");
        var amount = decimal.Parse(Console.ReadLine() ?? string.Empty);

        Console.WriteLine("The following cash assets are available to deposit:");

        var cashAssets = await _bfsDataService.GetAvailableCashAssets(bfsInstanceKey);

        foreach (var cashAsset in cashAssets) Console.WriteLine($"{cashAsset.Key}");

        Console.WriteLine("");

        Console.WriteLine("Enter the three letter symbol for the cash asset that you would like to deposit:");

        var cashAssetKey = Console.ReadLine();

        var selectedCashAsset = cashAssets.Single(t => t.Key == cashAssetKey);

        Console.WriteLine("Enter trade date in the following format (YYYY-MM-DD)");
        var tradeDate =
            DateTime.ParseExact(Console.ReadLine() ?? string.Empty, "yyyy-MM-dd", CultureInfo.InvariantCulture);

        Console.WriteLine("Enter settle date in the following format (YYYY-MM-DD)");
        var settleDate =
            DateTime.ParseExact(Console.ReadLine() ?? string.Empty, "yyyy-MM-dd", CultureInfo.InvariantCulture);

        var superTransaction = CreateSuperTransaction(account, amount, selectedCashAsset, tradeDate, settleDate);

        var response = await _bfsDataService.CreateTransaction(superTransaction, bfsInstanceKey);

        if (response.Message == "OK")
        {
            Console.WriteLine("Success! The transaction was created.");
            return;
        }

        Console.WriteLine($"No transaction was created because of the following error: {response.Message}");
    }

    private SuperTransaction CreateSuperTransaction(GetAccountResponseRow account, decimal amount,
        GetCashResponseRow selectedCashAsset, DateTime tradeDate, DateTime settleDate)
    {
        return new SuperTransaction
        {
            Batch = Guid.NewGuid(),
            BusinessEventId = Guid.NewGuid(),
            BusinessTransactions = new[]
            {
                new BusinessTransaction
                {
                    Account = account.BrickId,
                    AmountAsset1 = amount,
                    Asset1 = selectedCashAsset.BrickId,
                    BusinessTransactionType = "Default_Transfer_Trade_Cash",
                    TradeDate = tradeDate
                },
                new BusinessTransaction
                {
                    Account = account.BrickId,
                    AmountAsset1 = amount,
                    Asset1 = selectedCashAsset.BrickId,
                    BusinessTransactionType = "Default_Transfer_Settle_Cash",
                    SettlementDate = settleDate,
                    ValueDate = settleDate
                }
            }
        };
    }
}

A “transaction”, as it is experienced by a bank or brokerage customer looking at their account is actually made up of a hierarchy of transaction levels to make this work in reality.

The “customer facing” transaction, or the top level of the hierarchy so to speak is called a Super Transaction in Bricknode Broker and you need to care about this one and its first child called Business Transaction.

The API methods are described here.

A Super Transaction should always be made up of two Business Transactions where the Business Transactions influences what we call different dimensions.

Imagine a bucket which is being filled or emptied depending on if money is pouring in or out.

The bucket concept

In our world the bucket is being housed by an account and an account can house and keep track of several buckets at a time.

The Dimension is a label that we can put on a bucket, instead of one bucket holding water and another bucket holding milk we can say that a bucket holds cash in the Trade dimension and another bucket holds cash in the Settle dimension.

Multiple buckets

We can then add even more dimensions like Accrued Interest if we wish and the buckets are simply holding a balance for assets in a certain dimension.

Let’s focus on the part of the code where the Super Transaction is created.

private SuperTransaction CreateSuperTransaction(GetAccountResponseRow account, decimal amount,
        GetCashResponseRow selectedCashAsset, DateTime tradeDate, DateTime settleDate)
    {
        return new SuperTransaction
        {
            Batch = Guid.NewGuid(),
            BusinessEventId = Guid.NewGuid(),
            BusinessTransactions = new[]
            {
                new BusinessTransaction
                {
                    Account = account.BrickId,
                    AmountAsset1 = amount,
                    Asset1 = selectedCashAsset.BrickId,
                    BusinessTransactionType = "Default_Transfer_Trade_Cash",
                    TradeDate = tradeDate
                },
                new BusinessTransaction
                {
                    Account = account.BrickId,
                    AmountAsset1 = amount,
                    Asset1 = selectedCashAsset.BrickId,
                    BusinessTransactionType = "Default_Transfer_Settle_Cash",
                    SettlementDate = settleDate,
                    ValueDate = settleDate
                }
            }
        };
    }

Where the Business Transactions are created there is a property called BusinessTransactionType being set. This is very important because the definition of the transaction type holds information about which Dimension the corresponding transactions will be tagged to.

Now, how on earth can you figure out what transaction type to use as the input?

Well, this is where things get a bit tricky and Bricknode, or some developer 😉, should create some tooling around this! Maybe an idea for one of you that you can add to the Bricknode Marketplace! 💡

By navigating to Transaction Types in System Data you can filter on types:

Bricknode Broker Admin

The naming convention of the transaction types tells you a lot. The first section starts usually with Default and means that these have been created by default by the system. The second section can be Trade, Transfer or Payment and that tells you the master type group of the transaction and reflects if it impacts the return of the account or not. A Trade and Payment can impact the return of the account but not a Transfer.

The third section tells if the transaction type will generate an entry in the Trade or Settle dimension and the sections that follow are simply more granular details of what the transaction type is used for.

To double check what will happen when the transaction type is used it is possible to download the actual transaction type mapping as it is called. This can be done by checking the box in front of a transaction type and then click the Export button.

For the transaction type called Default_Transfer_Trade_Cash the mapping looks like this (XML).

<BusinessTransactionMappingRules xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.bricknode.com/TransactionMapping">
    <BusinessTransactionMappingRule transactionType="Default_Transfer_Trade_Cash">
        <AccountTransactionItems>
            <AccountTransaction dimension="T" assetType="Asset1" amountType="AmountAsset1" factor="1" transactionDate="TradeDate" xsi:type="DefaultSystemAccount" useAcquisitionValue="false"/>
        </AccountTransactionItems>
    </BusinessTransactionMappingRule>
</BusinessTransactionMappingRules>

In this example where it says dimension=”T” it means Trade as the dimension, if it says S it means Settle. The dimensions used can be seen in the GUI section called Dimensions where new dimensions can be entered ad-hoc according to needs.

Dimensions

I have used many financial applications which have had a go at creating the ultimate transaction engine but IMHO nothing comes close to what has been created by Bricknode.

I am yet to see a use case that this model could not cater to and if it would be possible to get a patent for a transaction engine this should be it 🙂.

Please get in touch if you have any questions, ideas or requests that you would like me to address in the future and code some examples of to illustrate.

How does a company build value? What goes in must come out!

When starting out to analyze companies it might be hard to understand what all these balance sheets and income statements are all about. There can be a lot of pitfalls and creative accounting but in essence it is about putting something into a company and then either keeping it there or taking it out.

A company can receive assets (often cash) by selling its products and/or services.

A company can also accept investments and gain assets by that activity. Assets leave the company either as costs when it buys things to be able to conduct business or when it issues dividends to investors.

The company can accumulate assets within its own umbrella and that should mean that the value of the company goes up. This is because the company now has more assets than before. If dividends are paid out the value of the company should go down with the same amount because it now has less assets.

The ability of a company to generate new assets by itself obviously goes into the valuation but that is something that concerns the future valuation of a business.

So, if a company continues to pile up cash from income and does not distribute any to investors through dividends, it should be possible to see this on the balance sheet, and the value of the company increases if all other variables are equal.

Market update for week 35

Inflation overview

I always start off by looking at my inflation indicators below.

CRB index in SEK

First I look at the CRB index in SEK since SEK is where I consume goods living in Sweden and this is the inflation that I am mostly concerned about.

During 2007/2008 we were at peak levels higher than we are currently though so I am thinking that we probably should reach peak levels within short. As for my investment models though this indicator is still flashing red hot inflation.

CPI change is next up and this is still raging as shown by the chart above. Looking at the longer term chart we get some perspective though.

Gold compared to SEK is continuing to hold up too with an upward sloping moving average which the price has been bouncing against.

Finally as an inflation gauge I look at the real interest rate in Sweden which I measure as the 10 year Swedish Government Bond compared to the CPI change. This one is still at a negative -6.66 % and even though I like this song which talks about this number 🙂 I would rather see something else.

Inflation summary

All my indicators to gauge inflation is flashing red for continued inflation which means that I still want to keep a lot of inflation protection by being invested into interest generating products with SEK exposure like preference shares, D-shares and Bonds. I also like various forms of corporate loans which I want to participate in. Marcus Hernhag has a lot of very good articles about this in Sweden.

I usually keep exposure to commodities like gold and other assets through instruments like these Amundi Physical Gold ETC and iShares Diversified Commodity Swap. I have had such good runs in these products though so I took all that exposure off during the summer and at these levels I do not want to re-establish them.