# Experiments in modelling a disaster
[**LINK TO CODE BASE**](https://github.com/20squares/ftx)
**Warning: This post is not financial advice. We literally crunched this model in less than 24 hours, please do not use it for anything serious.**
**DISCLAIMER: Turns out [FTX is filing for bankruptcy](https://twitter.com/FTX_Official/status/1591071832823959552?t=WXgT9IzI2w95-el2ao121w&s=35). Most likely this model is already very much outdated. That probability distribution was `0` after all :P**
As you know, the situation in the cryptocurrency ecosystem right now is a disaster. The FTX crash has taken (almost?) everyone by surprise and it is almost impossible to really understand what is going on, which naturally brings us to the first disclaimer (there will be many in this post):
**Disclaimer: The sources from which you source information will drastically affect the model of reality you will form in your mind.**
This seems needless to say but it is important, especially for us that deal with modelling all the time: Never forget about your biases.
So, for now, [this](https://pricetheory.substack.com/p/what-is-an-ftx
) is what we consider to be a good recap of what went on in the last few days.
## Basic handwavy assumptions
Notwithstanding trying to understand what is really going on with FTX, some things are clear: Above all, there is the fact that many people have their funds locked into FTX and are not able to withdraw.
Moreover, from various announcements FTX made yesterday it seems that:
- People will be able to withdraw Tron (TRX) from FTX 'soon'.
- TRX prices have been consistently higher than market prices in the last few hours.
From these few elements, we decided to draft a small game theoretic model of what is going on right now. Which brings us to our second disclaimer:
**Disclaimer: In this modelling exercise we will make a boatload of assumptions, way more than we are comfortable with.**
This is unfortunately unavoidable, as in the current FTX situation there is clearly a lot of private information that can be guessed at best, and that is really essential to understand what is _really_ going on and which strategic outcomes may be optimal.
So, this is what we decided to assume for now. Clearly this will be our own modelling bias, it will probably be very wrong, but the silver lining is that should more information become available, we (or _you_, since the codebase is public!) will be able to revise it accordingly.
- *We assume that* FTX is blocking withdrawals because it has a liquidity problem. This, in particular, implies that every person with funds stuck into FTX has credit toward FTX.
- *We assume that* FTX will allow users to convert assets to TRX and possibly vice-versa, basically maintaining a minimum operational trading logic.
**Disclaimer: At the moment this seems true only to some extent. The possible amounts exchanged internally are quite heavily capped.**
- *We assume that* FTX will allow withdrawals in TRX. This is a **huge** assumption.
- *We assume that* FTX can at least in some capacity manipulate the price of TRX on its platform.
- *We assume that* FTX will allow withdrawals in TRX because either it has a lot of TRX (unlikely) or someone will lend FTX a lot of TRX (more likely given [this] post).
- *We assume that* whoever lends TRX to FTX won't do it for free.
- *We assume that* whoever lends TRX to FTX can collude with FTX to manipulate TRX price.
- *We assume that users converting funds on FTX or elsewhere won't impact the market*. This is another **huge** assumption, that essentially covers only small players. We plan to change this as we fine-tune the model.
## Drafting a model
From this, we can draw a simple model.
- There are two elements in our game: A *platform* (FTX) and a *user*.
**Disclaimer: The only player we model explicitly for now is user, while platform is treated as not having strategic content. This will likely change in the next few hours.**
**Disclaimer: Also, at the moment we just model one user. We plan to add more soon.**
- There are three assets in our game, `X`, `Y` and `TRX`. `X` and `Y` represent the same asset (e.g. `ETH`), traded internally and externally to the platform, respectively. `TRX` is the asset being lend to the platform.
**Disclaimer: At the moment we are considering only one asset against `TRX`. You can see this as the equivalent in `ETH` that the user is holding.**
- The platform is offering `X` and `TRX`.
- `X` cannot be withdrawn or deposited by users.
- `TRX` can be exchanged for `X` on the platform.
- `TRX` can be withdrawn by users, not deposited.
> The following stub is irrelevant right now and not part of the model, but will become relevant when the platform will be added to the game as a player.
> - The platform *can*:
> - Observe the market prices for the asset pairs `X/TRX` and `Y/TRX`.
> - Forecast and manipulate the internal price of the asset pair `X/TRX`.
> - The platform *wants*:
> - Reduce the debt it has towards its creditors (the users), that is, reduce the amount of `X` owned by the users.
The user is, at the moment, the only strategic player in the game.
- The user has:
- A quantity of `balanceCoinX` deposited on the platform.
- A quantity of `balanceTRXInside` deposited inside the platform.
- A quantity of `balanceCoinY` deposited outside the platform.
- A quantity of `balanceTRXOutside` deposited outside the platform.
In the most basic scenario -- a user trying to save its stuck funds -- we can set `balanceCoinX` to some quantity and all other balances to `0`.
- The user knows:
- Its own balances.
- The '*current* internal price' `exchangePriceXtoTRX`.
- The '*current* external price' `exchangePriceTRXtoY`.
- The user *can*:
- Do nothing (keep everything as is) and hope for the best.
- Exchange `X` for `TRX` on the platform.
- (hopefuly) withdraw `TRX`.
- Exchange `TRX` for `Y` outside the platform.
### Modelling decisions
All these possible decisions are piped together in this big open game:
```
decisions name gridParameterCoinX gridParameterTRX = [opengame|
inputs : balanceCoinX, balanceCoinY, balanceTRXInside,balanceTRXOutside, exchangePriceXtoTRX, exchangePriceTRXtoY;
feedback : ;
:-----:
inputs : balanceCoinX, exchangePriceXtoTRX ;
feedback : ;
operation : exchangeToTRX name gridParameterCoinX ;
outputs : coinX ;
returns : ;
// exchange x for trx inside
inputs : coinX, exchangePriceXtoTRX ;
feedback : ;
operation : swapCoinXforY ;
outputs : trx ;
returns : ;
// compute exchange
inputs : balanceCoinX, coinX ;
feedback : ;
operation : forwardFunction $ uncurry subtractFromBalance ;
outputs : balanceCoinXNew ;
returns : ;
// update balance of x coin inside
inputs : balanceTRXInside, trx ;
feedback : ;
operation : forwardFunction $ uncurry addToBalance ;
outputs : balanceTRXIntermediate ;
returns : ;
// update balance of trx inside
inputs : balanceTRXIntermediate, exchangePriceTRXtoY ;
feedback : ;
operation : withdrawTRX name gridParameterTRX ;
outputs : trxWithdrawn ;
returns : ;
// withdraw trx from ftx
inputs : balanceTRXIntermediate, trxWithdrawn ;
feedback : ;
operation : forwardFunction $ uncurry subtractFromBalance ;
outputs : balanceTRXNewInside ;
returns : ;
// update balance of trx inside ftx
inputs : balanceTRXOutside, trxWithdrawn ;
feedback : ;
operation : forwardFunction $ uncurry addToBalance ;
outputs : balanceTRXOutsideIntermediate ;
returns : ;
// update balance of trx outside ftx
inputs : balanceTRXOutsideIntermediate, exchangePriceTRXtoY ;
feedback : ;
operation : exchangeFromTRX name gridParameterTRX ;
outputs : trxExchanged ;
returns : ;
// exchange trx outside for y
inputs : balanceTRXOutsideIntermediate, trxExchanged ;
feedback : ;
operation : forwardFunction $ uncurry subtractFromBalance ;
outputs : balanceTRXNewOutside ;
returns : ;
// update balance of trx outside
inputs : trxExchanged, exchangePriceTRXtoY ;
feedback : ;
operation : exchangeToTRX name gridParameterTRX ;
outputs : coinY ;
returns : ;
// compute actual exchange of y
inputs : balanceCoinY, coinY ;
feedback : ;
operation : forwardFunction $ uncurry addToBalance ;
outputs : balanceCoinYNew ;
returns : ;
// update balance of y outside
:-----:
outputs : balanceCoinXNew,balanceCoinYNew,balanceTRXNewInside,balanceTRXNewOutside ;
returns : ;
|]
```
This open game itelf is the composition of smaller open games. For instance, `exchangeToTRX` is another open game defined in the code base. This exemplifies the idea of 'games as lego bricks which can be composed together'.
### Modelling payoffs
Clearly, the user *wants* to maximize its own balance. This is not easy to assess, as, for instance, the 'value' of `X` depends on how likely the user believes that the platform will fail. The `payoff` calculation is thus itself expressed as an open game, itself the composition of smaller games.
```
payoffs name = [opengame|
inputs : balanceCoinX, balanceCoinY, balanceTRXInside,balanceTRXOutside,balanceCoinXNew,balanceCoinYNew,balanceTRXInsideNew,balanceTRXOutsideNew,pX,pY,pTRXInsideFTX,pTRXOutside ;
feedback : ;
:-----:
inputs : balanceCoinX, balanceCoinY, balanceTRXInside,balanceTRXOutside, balanceCoinXNew,balanceCoinYNew,balanceTRXInsideNew,balanceTRXOutsideNew ;
feedback : ;
operation : forwardFunction $ computeDiffBalances ;
outputs : diffX,diffY,diffTRXInside,diffTRXOutside ;
returns : ;
inputs : diffX,diffY,diffTRXInside,diffTRXOutside,pX,pY,pTRXInsideFTX,pTRXOutside;
feedback : ;
operation : forwardFunction $ computePayoffs ;
outputs : profit ;
returns : ;
inputs : profit ;
feedback : ;
operation : addPayoffs name ;
outputs : ;
returns : ;
:-----:
outputs : ;
returns : ;
|]
```
Clearly, in reality there are more possibilities, as users actively trading on the platform to maximize either `X` or `TRX`. We won't cover this trading logic right now as it is far too complicated to analyze in such a short time.
Arguably, there will also be some users (which we deem *fanboys*) that do not want to recover their assets because, for example, still have absolute faith in the platform. We assume these constitute a minority and won't consider them for the model.
### How likely it is that the platform fails?
Now it is finally time to instantiate the game. This happens here:
```
------------------------------------
-- 3 Create probbility distributions
------------------------------------
-- Create probability distributions for the value of coin x and trx _inside_ ftx
-- We assume that the other parameters are taken as exogenous
-- with prob p value of coin x inside ftx 0; with prob (1-p) value
distributionPriceX p value = distFromList [(0,p),(value,(1-p))]
-- with prob p value of trx inside ftx 0; with prob (1-p) value
distributionPriceTRX p value = distFromList [(0,p),(value,(1-p))]
priceDistributions pX valueX pTRX valueTRX = [opengame|
inputs : ;
feedback : ;
:-----:
inputs : ;
feedback : ;
operation : nature $ distributionPriceX pX valueX;
outputs : priceX;
returns : ;
inputs : ;
feedback : ;
operation : nature $ distributionPriceTRX pTRX valueTRX;
outputs : priceTRX;
returns : ;
:-----:
outputs : priceX,priceTRX;
returns : ;
|]
```
Basically, we are instantiating a probability distribution describing how valuable `X` and `TRX` held inside the platform are. This is fundamental: This probability distribution, essentially, represents how likely the user thinks that the platform will fail. The lower this probability, the lower the assets held inside the platform are valued.
### Testing some strategies
Finally, we are able to describe some strategies. For now, we just consider a couple:
- Always exchange, withdraw etc. everything
- Always exchange, withdraw etc. nothing
In the first case, the user takes its whole balance of `X` and converts it to `TRX`. Then proceeds to convert all `TRX` to `Y` externally.
In practice, we can make the strategies way more granular: The user is free to exchange just a little bit, withdraw just a little bit, convert on the outside market just a little bit. This is evident from the code describing the strategies:
```
maxStrategy :: Kleisli Stochastic (Double, ExchangeRatio) Double
maxStrategy = Kleisli (\(balance,_) -> playDeterministically balance)
overallMaxStrategy = maxStrategy ::- maxStrategy ::- maxStrategy ::- maxStrategy ::- Nil
```
Unsurprisingly, these two strategies are respectively equilibria precisely when the probability distribution `p` is either 0 (the user is certain platform will fail) or `1`.
In the next hours, we will play with more complex strategies. Notably, we will try the nice trick of playing the game in reverse: We will try the 'withdraw everything' strategy with `p=0`, that we know it is an equilibrium. Then we will crank up `p` incrementally until the equilibrium breaks. That will be the point when user starts thinking that 'probably withdrawing everything is not the best strategy for the situation'.
## Other things to do
There are many things we need to do to further refine this model:
1. Test with mixed strategies!
2. Turn the platform into a strategic player.
3. Model explicitly a *lender* (Tron) that lends TRX to the platform, and can presumably observe prices internal and external, user behavior and decide on how much `TRX` to lend. That is:
> - There is a *lender*, lending a specific asset (`TRX`) to the platform.
> - The lender *can*:
> - Decide how much `TRX` it wants to lend to the platform.
> - Probably collude with the platform to manipulate the `X/TRX` price.
> - The lender *wants*:
- To sell `TRX` at a better price it normally would.
5. Consider the current scenario where exchanges are capped to some limited amount of `TRX`.
...All in all, there is still a lot of stuff to do. But hey, we've been modelling this for less than 5 hours, so I'd consider myself satisfied!
[**LINK TO CODE BASE**](https://github.com/20squares/ftx)