.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/fraud/schemes/plot_01_ponzi_scheme.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_fraud_schemes_plot_01_ponzi_scheme.py: Ponzi's scheme: paying old investors with new money (1920) ========================================================== In 1920 Charles Ponzi promised Boston investors 50% in 45 days, supposedly from arbitrage on international reply coupons. There was no arbitrage: each payout came from later deposits. Such a scheme pays its promises only while new money grows fast enough. A deposit :math:`D` made :math:`\tau` periods ago is owed :math:`(1 + r) D` today; if deposits grow by :math:`g` per period and the operator keeps a fraction :math:`s` of each, the scheme keeps up exactly when .. math:: (1 - s)(1 + g)^\tau \ge 1 + r . For Ponzi's terms, deposits must grow by half every 45 days. No population of investors grows like that for long: once growth slows, the payout outruns the cash, and the latest investors lose everything they paid in. .. GENERATED FROM PYTHON SOURCE LINES 23-28 .. code-block:: Python import matplotlib.pyplot as plt import blockchainkit as bk from blockchainkit.fraud.visualizers import plot_ponzi .. GENERATED FROM PYTHON SOURCE LINES 29-33 Growth that cannot last ----------------------- Deposits grow by 60% a period, faster than the breakeven 50%, until the pool of new investors saturates at 20 times the first period's money. .. GENERATED FROM PYTHON SOURCE LINES 33-46 .. code-block:: Python needed = bk.fraud.breakeven_growth(0.5, term=1) print(f"breakeven growth: {needed:.0%} per 45 days") deposits = [min(100 * 1.6**t, 2_000) for t in range(15)] run = bk.fraud.simulate_ponzi(deposits, promised_return=0.5, term=1) print("collapsed in period", run.collapse, f"after raising {run.raised:,.0f}") print(f"still owed to investors: {run.owed[-1]:,.0f}") assert run.collapse is not None and run.owed[-1] > 2_000 fig, ax = plt.subplots(figsize=(8, 4)) plot_ponzi(run, ax=ax) fig.tight_layout() .. image-sg:: /api/gallery/fraud/schemes/images/sphx_glr_plot_01_ponzi_scheme_001.png :alt: Ponzi scheme: collapsed in period 7 :srcset: /api/gallery/fraud/schemes/images/sphx_glr_plot_01_ponzi_scheme_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none breakeven growth: 50% per 45 days collapsed in period 7 after raising 6,307 still owed to investors: 3,154 .. GENERATED FROM PYTHON SOURCE LINES 47-49 When it collapses, against how fast deposits grow ------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 49-68 .. code-block:: Python growths = [0.3 + 0.05 * k for k in range(9)] lifetimes = [] for g in growths: flows = [min(100 * (1 + g) ** t, 2_000) for t in range(40)] result = bk.fraud.simulate_ponzi(flows, promised_return=0.5) lifetimes.append(len(result.deposits)) assert lifetimes[0] < lifetimes[-1] < 40 # Faster growth only postpones the end. fig, ax = plt.subplots(figsize=(7, 4)) ax.plot(growths, lifetimes, "o-", color="#dc2626") ax.axvline(needed, color="#64748b", linestyle="--", label="breakeven growth") ax.set(xlabel="growth of deposits per period", ylabel="periods until collapse") ax.set_title("A saturating market ends every Ponzi scheme") ax.legend() fig.tight_layout() plt.show() .. image-sg:: /api/gallery/fraud/schemes/images/sphx_glr_plot_01_ponzi_scheme_002.png :alt: A saturating market ends every Ponzi scheme :srcset: /api/gallery/fraud/schemes/images/sphx_glr_plot_01_ponzi_scheme_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 69-75 Exercise -------- Ponzi kept part of every deposit for himself. How fast must deposits grow for a scheme promising 50% in 45 days if the operator skims 20%? Check your answer with :func:`~blockchainkit.fraud.systems.ponzi.breakeven_growth`. A worked solution is in :doc:`/exercises/fraud`. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.075 seconds) .. _sphx_glr_download_api_gallery_fraud_schemes_plot_01_ponzi_scheme.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../../../lite/lab/index.html?path=api/gallery/fraud/schemes/plot_01_ponzi_scheme.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_01_ponzi_scheme.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_01_ponzi_scheme.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_01_ponzi_scheme.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_