Thank you for writing this, you've done a good job putting the sourced research paper/technical report into code. Unfortunately the technical report is garbage. I've spent the last few days trying to fix some of the major issues (I can see in the code you tried to address some of the problems as well). The following is a quick summary.
Quick Observations that Something is Wrong
When running the program you can observe issues. All prices are more or less random and trend towards pennies. No agents are profitable, they just go bankrupt faster or slower depending on idle time and resource costs. Refiners spend the most and go bankrupt rapidly--I noticed you added a special case in code to get them back based on demand when they all die off. The entire point of the paper is to find prices in a simulated economy, however this function is not accomplished and I claim cannot be accomplished using the methods described in the paper.
Critical Issues in the Technical Paper
-
The first thing I noticed was that the described double auction algorithm in the paper is not a proper double auction. Trades should never execute at prices below the seller bid, nor above the buyer ask, yet the described algorithm does not prevent either case. In particular the seller does not have proper control of the prices they are getting to allow them to be profitable. At first I thought this was why agents weren't profitable, but I quickly found a larger problem...
-
Commodity prices in the sim have some interaction with supply/demand but have no foundation in production costs, so agents cannot be profitable. Nor will discovered prices have much of a relation to the simulated economy. Bids (and asks) are random values in a range that was based on observations of past trades (which were also set randomly). So prices will cluster for a while at randomly found ranges somewhat effected by supply and demand, but none of the prices found will actually be relevant. A particular glaring omission is the agents described in the technical paper do not take into account their costs when setting asks so have no hope of being profitable beyond random chance. Also discovered commodity prices do not reflect the value that actually went into producing those commodities. So prices are nonsensical, agents just go bankrupt, and the result of the simulation is meaningless.
A Few Fixes
For the first issue, adding a line to break out of the bid/ask trade processing loop in resolveOffers() when buyer.unit_price < seller.unit_price seems to patch the major problem. Other improvements can be made, but issue 2 is much more critical.
The second issue requires expanding Inventory to track the average price paid per unit for all purchased commodities in addition to commodity count. I changed the Float in Inventory._stuff to be a Point to hold the extra value. I added a BasicAgent.consumeInventory and BasicAgent.produceInventory to be called instead of changeInventory to help identify inventory changes that should track production costs. Money lost due to being idle in Logic.perform also needed to be tracked. Agent logic should change to make all _consume() calls before each _production() call is made so costs are tracked before production.
Once costs are tracked, Agents can then take those costs into account when setting ask levels for their produced commodities to allow for a profit. In fact once you track costs associated with producing a commodity, it immediately becomes apparent that ask price selection as simple as: askPrice = costs * profit_factor. If asks aren't hit, profit_factor can be reduced. Meanwhile the ask selection method in the technical paper is nonsense.
After making the above changes I observe that agents can be profitable, prices stabilize, and they relate to each other reasonably given how some commodities have more value in them based on what goes into producing them. Supply/demand dynamics are simulated as before. Initial conditions for each commodity had to be modified as discovered prices were more than random nonsense and the initial conditions became important.
I would make a pull request except I ported the Haxe project to C# as I'm unfamiliar with Haxe. Also I'm still messing around with things.