I have started looking at the Minsky software package, developed by Steve Keen and with coding by Russell Standish. The package is in C++, with the source code available at https://github.com/highperformancecoder/minsky. An older version is available as a precompiled executable at SourceForge; later versions are now available as a benefit for the Minsky Patreon support page: https://www.patreon.com/hpcoder/overview. I will be using the package as part of my recession modelling book; this article offers some initial pointers for those of us who do not read documentation.
One of the advantages of the Minsky package is that the researchers that use it can distribute the models so that readers can examine them. Even if the reader is not too familiar with mathematics, it may be possible to play around with an existing model, and see what happens if small tweaks are made. (Although some proficiency with the package would be necessary to avoid breaking models.)
The same holds for stock-flow consistent models; for example, anything I do with the sfc_models package is available on GitHub, and can be replicated.
This transparency is completely unlike neoclassical DSGE models. As such, the recent charges by fans of economic orthodoxy that Modern Monetary Theory is "guru-based" is a case of the pot calling the kettle black. Take for example the orthodox assertion that fiscal policy "only works if the zero lower bound is hit." That assertion is based on a textual interpretation of paper written by "gurus." It is not backed by simulation evidence, and the mathematics is developed using a non-standard notation that defy validation by outsiders.
IntroductionThe first thing to note that the Minsky package is continuous time, unlike the discrete time models of my sfc_models package, or the textbook Monetary Economics by Godley and Lavoie. Therefore, the package uses a Runge-Kutta algorithm to generate the solution. The equations behind the model are differential equations, unlike the difference equations of discrete time.
It is presumably possible to simulate a wide range of differential equations. The above figure shows an example of a linear feedback control system (with a proportional feedback rule). There is a constant external disturbance which is fed into an integrator. The output of the integrator is added to the disturbance (with a negative sign) to stabilise the system. We can see the output in a graph object.
The system was built with drag-and-drop operations. If we switch to the "equations" tab, we see the underlying equations generated by parsing the system configuration. We have the initial condition, and then the single dynamic equation, which is the closed-loop equation.
Godley TablesThe low-level operations I used to build the feedback control system are straightforward - at least if you worked with a similar package in the past. I used to use the Simulink simulation tool for Matlab, and was able to build the system without looking at the documentation.
However, economic models are complex. Building them up as a set of low-level operations to create differential equations would be a painful task. In order for the package to offer advantages over using pen and paper and a numerical solver, the user will need to use Godley Tables.
The figure above shows a system with a Godley table - the brownish bank-looking thing in the middle. (It is named after the economist Wynne Godley.) If you download advanced models (see note below!), you will be confronted by these objects. What it represents is not obvious, and this is where I was forced to actually read the documentation. The above diagram is an example that is provided (banking model example).
The initial view above is effectively meaningless; we need to double-click the Godley Table to have a chance to understand what is going on.
The Godley table represents a sector's balance sheet/flows. This is a bank, with two depositors, "Patient" and "Impatient." (I think this is based on some neoclassical model.) The balance sheet is written as a row: the assets are cash, the two depositor liability accounts, and then the bank equity.
- The second row shows the initial conditions; the bank has $20 in cash, offset by a $20 deposit held by "Patient." We can see that the balance sheet adds up: assets - (liabilities + equity) = A - L -E = 0.
- The next row is labelled lending, and shows one set of flows. (You can add more rows for more complex models). We see a flow, which is equal to the variable "lend", going from "Patient" to "Impatient." The last entry validates that the flows net to zero.
We can now go back to the diagram above. The bottom four entries are the balance sheet. and the entry to the left is the variable "lend." It is defined externally to the Godley table: it is equal to 0.1 times the balance in "Patient."
The two variables "Patient" and "Impatient" are wired to a graph, and we can see that Patient's balance goes down towards zero, and Impatient's mirrors this. We could then add other flows - presumably Impatient buying smokes, beers, and drywall - and turn this into a more useful model.
From a technical perspective, all the variables are stocks, and the equations are flows. Since we are in continuous time, the flows would have units of dollars per year. For example, a flow of 10 implies a flow of $10 per year.
If the Godley Table is properly specified (each flow always nets to zero), stock-flow consistency is maintained. This workflow is much more efficient than it would have been trying to build the bank with low level operations. That would have required specifying each stock as an integral of the associated flow.
In summary, I recommend going through the example of building the banking system, so that you can see how the Godley tables work. The rest of the package should be more intuitive.
- I used the precompiled binary file. Some time ago, I tried compiling from the source code, and was not able to get it to work (and gave up). (From what I vaguely recall, there were compiler compatibility issues with the compilers that I was using to build Python modules.)
- If you download example files from GitHub, click on the "Raw" button. Other attempts to download the example files corrupted them, and Minsky threw some format error when trying to load the file. (This tip is in the "README" file, but I needed to scroll down to see it.)
- Deleting wires (the lines that connect objects in the diagram) is best done by hovering over the wire (blue selection points appear on the wire), and then deleting with the delete key. It is possible to get a context menu (right mouse menu) with the delete option, but it does not pop up all the time. (Thanks to Steve Keen for explaining this.)
- I did not show an example, but it is possible to define variables and then build sub-systems that connect to a widget that is a copy of that variable. This means that we can compartmentalise the wiring of the model.
I will be writing a section of my book on Steve Keen's models, and will put that up as a draft. My interest is in finding a simple model that generates a financial crisis/recession.
My own package sfc_models is discrete time, and is where I will probably continue my development efforts. However, if I need to work with continuous time models, I will probably use Minsky.
As a final note, I just want to explain why I built my own package, rather than add on top of Minsky, which is open source. I had two concerns. The first was that I preferred discrete time models, and I wanted my work to be compatible with Monetary Economics. The second concern is that I had little desire to start coding in C++ once again. I had done a lot of coding with C/C++, but the workflow advantages of scripting languages like Python are massive. The sfc_models package takes advantage of the flexibility of Python object-oriented model that would be exceedingly awkward to replicate in C++.
(c) Brian Romanchuk 2019