This post actually does not have much to do with financial programming unless you are using WordPress as one of your tools, as I do 😃.
I have a nice setup where I am developing locally using Docker and then I have Actions configured in GitHub where my pull requests trigger a deployment to an Azure Container App.
I am using JWT Authentication for WordPress to secure some of my routes and I am using a theme in WordPress that we have developed in-house.
Every time I want to install and active a new plugin I do that first locally and then I deploy the code into production which is the Container App.
This time I was going to add Yoast SEO so I did the same thing as usual and everything worked locally so I deployed the code and then were going to conduct the Yoast first time configuration in the production environment.
This is when I started to have problems!
When I opened my production website I had the following error message:
Warning: include(/var/www/html/wp-content/plugins/wordpress-seo/vendor/composer/../../vendor_prefixed/psr/log/Psr/Log/LoggerTrait.php): Failed to open stream: No such file or directory in /var/www/html/wp-content/plugins/jwt-authentication-for-wp-rest-api/includes/vendor/composer/ClassLoader.php….
I had to revert my commit and go back to the old state and tried to de-activate Yoast to try to install it again but fully from the production environment, this did not work though.
My idea was to install the plugin locally and not activate it, then deploy the code and do the activation in the production environment which should make the database changes. You see, everything had worked both locally and in production while the Yoast plugin was de-activated.
When I then tried to activate he plugin I instead got a bunch of errors that looked like this:
WordPress database error: [Table ‘wordpress.wp_yoast_indexable’ doesn’t exist] SELECT * FROM wp_yoast_indexable WHERE object_id = ’44’ AND object_type = ‘post’ LIMIT 1
WordPress database error: [Table ‘wordpress.wp_yoast_indexable’ doesn’t exist] SELECT * FROM wp_yoast_indexable WHERE object_id = ’44’ AND object_type = ‘post’ LIMIT 1
Looking in the database the Yoast tables were missing. I started to look deeper into the wp_options table where I had deleted all content with wpseo in it using the following query:
DELETE FROM wordpress.wp_options WHERE option_name LIKE “%wpseo%”;
I saw a few entries that had the name yoast in them, which was not mentioned by the wordpress.org article so I ran the following query too:
DELETE FROM wordpress.wp_options WHERE option_name LIKE “%yoast%”;
This removed the entry in the database that stored what database migration my system had for the Yoast tables and that was the last thing that was needed. Now when I activated the plugin again the tables were created.
Now the activation of Yoast worked but I did get an error message after activation saying:
Deprecated: strip_tags(): passing null to parameter #1 ($string) of type string is deprecated in /var/www/html/wp-admin/admin-header.php on line 36
This was a non fatal error though and the site worked as it should from this point forward.
It took me some time to figure out what more to delete from the database table wp_options so I thought that I might be able to save a few hours of searching for other people that might end up in the same dead end 😊
There is an overwhelming number of software services being presented, and sometimes launched, within the financial industry which promotes APIs as the ONLY user interface and that it is some kind of magic pill.
Don’t get me wrong, I love APIs, that is one of the main reasons why I started Bricknode in 2010 (now part of Huddlestock). There is a lot of misunderstanding going around though. In 2010, talking about API-first was cool and new, talking about API-first today is just lame 😂 because it is assumed.
The image below shows how a typical application is structured.
An API is the interface that is used by other applications that would like to communicate programmatically with an application. A Graphical User Interface typically uses an API to communicate with the business logic and eventually the database of its own application.
The API is a pre-cursor to the Graphical User Interfaces. If you are building an application for other developers then having an API as your only interface is fine but if you are building an application for humans then you also need a Graphical User Interface but that is hard work and takes time!
It is much easier to just knock up an API and then say that you are done with it 😊and other developers have to do the hard work with building the interface for other humans to interact with your application.
Generally, even if you are just doing an API as your interface there is usually a need for some sort of GUI too so that a developer can make some types of configurations.
At Bricknode (now Huddlestock) we spent many years building up multiple GUIs and lots of API functionality while at the same time serving real customers and putting our products to practice. By doing it that way we made sure that what we built could be used both by machines and humans which I think is key!
When we created Bricknode in 2010, 14 years ago, I thought that the financial world would switch to using APIs from file communication over night 😂. OMG, was I ever naive!
There are two legs to IaaS and they are as follows:
The last couple of days I have done a few postings on X and LinkedIn regarding the awesome work that we are doing within Huddlestock like these:
After our system update on Wednesday I am going to get the add-on Aksjesparekonto added to our release pipeline! It means that on Thursday I will have fun doing final product tests for this new functionality and after that it will be available to the world!! #Aksjesparekonto#ASKpic.twitter.com/NgjcdyiOUf
This is what I was referring to in my post here https://t.co/ND0B5we4qt ! Now we are live with supporting bank accounts in Norway which is a pre-requisite for the full launch! This makes it so that customers can both deposit and withdraw money with Norwegian banks! @Huddlestockhttps://t.co/32ZFkOZUpM
Here are some of my colleagues at the Skövde office where we are hard at work on this to support automatic #investments in Norway just as we do in Sweden with #Autogiro Functionality is exactly the same so we just have to add a new interface 😀 https://t.co/KlBdLAeWbxpic.twitter.com/u2jBeXM6Zp
Huddlestock is constantly integrating with new services, like for example AvtaleGiro, Nets, Bambora etc. I am always surprised by the old tech that is used by these companies and the likes of Huddlestock is building integrations to these so that customers of for example Huddlestock don’t have to deal with those old formats. Instead customers of Huddlestock can use the Huddlestock API to do their thing and Huddlestock takes care of all the heavy lifting that needs to happen under the hood.
So, what do I mean by old tech? A typical thing is communication with Flat Files. Flat Files were popularized during the 1970s by IBM and simply means that in a text file you have one line which contains a single entity of data. Maybe you have heard about CSV-files and those are Flat Files where each value is separated by a comma or semicolon.
The worst of them all are position based files where you need to get an instruction on what positions in the file means what, look at the example below:
I have entered some red dividers in the file for illustration, between position 1 to 11 there is one number, between position 12 to 23 there is another number etc.
This is extremely limiting and is not as easy to read by a human and you have a fixed number of characters that you can deal with in the file. There is no hierarchy within the data so it is all bad!
This is however how a lot of the financial companies communicate today, even in 2024!!, and that is why a company like Huddlestock brings soo much value to the market because it integrates with all these services and wrap them in a completely new system like Bricknode which then the users can interact with through many graphical user interfaces or via API.
My goal is to get every company and entrepreneur who is looking to develop a new financial service to first reach out to Huddlestock and see how it could help cut down the road to market and make tech less costly!
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! 🥶
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.
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.
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).
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.
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.
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.