Gold ETF Arbitrage

An algorithm that moves capital between the gold funds of the Tehran Stock Exchange, on the way to an automated gold portfolio that aims to earn more than holding gold.

In testing
  • Python
  • Gold funds
  • Tehran Stock Exchange
  • Relative value
  • Order book
  • Execution simulator
  • Data 36 gold funds

    Their order books and trades over 995 trading days, from July 2022 to September 2026.

  • Simulation 60,957 trades

    Simulated trades in the base scenario, over 395 trading days and 21 funds.

  • Testing 82 full simulations

    Run to check the rule on different periods, fee levels and assumptions before reporting it.

  • Technology 1 language
    PythonData, simulator and algorithm

Introduction

More than thirty funds on the Tehran Stock Exchange do one thing: they hold gold. They hold the same gold, yet each one trades at its own price against what it owns. At any moment one fund is a little dear and another a little cheap, and which is which changes from hour to hour. Most investors choose one fund and stay in it. The differences are small, so fees and thin order books swallow them unless both are measured exactly.

We decided to treat all the gold funds as one asset, and to hold that asset through whichever fund is cheapest to own at the time, moving only when the move pays for its own cost.

The project holds the order books and trades of 36 gold funds from July 2022 to September 2026, 995 trading days, together with each fund's published net asset value. On that record we built a simulator that replays the exchange second by second, and tested one switching rule across 21 funds from January 2025 to September 2026, at four levels of broker fee. In that simulation the portfolio finished ahead of simply holding the most traded gold fund in 19 of 21 months. The destination is an automated gold portfolio that is fully in gold at every moment and aims to end with more gold than it started with.

Simulator report

The report below shows that test in four scenarios. Only the broker fee varies between them: no discount, and 25%, 35% and 45% discount. The rule is the same in all four. You can download the report and read and weigh it independently of us.

  • GOLD 21 gold funds of the Tehran Stock Exchange
    • Jan 2025 to Sep 2026test period
    • 395trading days
    • 60,957simulated trades in the base scenario
    • 4 scenarios4 fee levels

    One self-contained HTML file, 4.9 MB, in five languages

This is a simulation result on the market's recorded order books, not real trading, and no guarantee of the future. No competing traders are modelled in this simulation.

Approach

We never ask whether gold will rise or fall; we only ask which fund is the cheapest way to hold it right now. The work proceeds in three stages:

  1. From prices and net asset values to one yardstick for every fund

    A fund's price alone says nothing, because every fund has a different unit size and a different mix of gold bar and coin. We set each fund's market price against the value of what it holds and against the same figure for the most traded gold fund, which is our benchmark. The result is one number per fund that says how dear or cheap it is compared with its own normal. All funds are read on that one scale.

  2. From the yardstick to a switch that pays for itself

    A cheap fund is not yet a reason to move. Every switch costs a sale fee, a purchase fee and the gap between buyers and sellers in two order books. The rule moves capital only when the difference is clearly larger than that cost, and brings it back when the difference has closed. A switch that would not earn back its cost is not made.

  3. From the decision to a filled order

    Gold funds other than the largest one trade thinly, so a decision is worth only what the order book can actually fill. The algorithm sizes each order to the depth on the screen, works the two sides of a switch together, and keeps the account in gold throughout. It does not sell short and does not borrow to enlarge the position.

The simulator sits under all three stages. It replays the recorded order books of all the funds side by side, one second at a time. Our orders join the queue behind the orders that were already there, fill in part or not at all, and take away the liquidity they consume. Market data reaches the algorithm a few seconds late and orders take time to arrive, as they would in practice. The simulator also keeps the account itself, and refuses any order that would borrow beyond the broker's intraday limit, sell what is not held, or trade outside the day's price limits.

The project began inside TSETMC and uses the same market recordings. It is a separate project because its question, its simulator and its destination are its own.

What stands out

  • It is measured in gold, not in toman.

    Gold itself can rise or fall, and a gold fund will follow it. Our benchmark is therefore not cash but simply holding the most traded gold fund. Every figure we report is the portfolio divided by what the same money would be worth if it had stayed in that fund. A result of zero means "no better than holding gold", not "no loss".

  • Always fully in gold.

    The portfolio never sits in cash waiting for a better day and never bets against gold. It holds gold funds at every close. In every simulation of the final rule, no borrowed money was carried overnight; the simulator checks this at every close and records it if it ever happens.

  • A simulator that keeps the account honest.

    An ordinary backtest assumes every order fills at the quoted price. Ours replays the recorded order books second by second, puts our orders in the queue, and fills them only against volume that was really there. The base scenario contains 60,957 simulated trades over 395 trading days. The algorithm sees the market with a delay and its orders arrive with a delay.

  • Fees are in the account from the first line.

    The advantage of one fund over another is small, so the broker's fee decides whether a switch is worth making. We ran the whole simulation again at four fee levels, from no discount to a 45% discount, with the rule unchanged. The report shows all four, so the reader can see how much of the result depends on the fee.

  • Tested where it could fail.

    A rule that works on one period may only have been lucky. We checked the rule's logic on the prices of 2022 to 2024, a period no simulation had used, and we read the two halves of the test period separately, because the exchange changed a trading limit between them. On an earlier version of the rule we also replaced the chosen fund with a randomly chosen one at the same moments, and that version lost money. In all, 82 full-period simulations stand behind the reported result.

  • A result you can read without us.

    The simulator report is one file that opens in a browser. It shows the portfolio against holding gold month by month, the worst stretch behind gold as well as the best month, and what the fees took. It also states its own limits: it is a simulation, and it does not model other traders competing for the same orders.

The road ahead

  1. Done

    The market recordings, the execution simulator and the switching rule are built, and the rule has been tested in simulation across 21 funds and four fee levels.

  2. Now

    Establishing what the simulation cannot know, such as the real delay of live data and of our orders, and preparing to run the algorithm on the live market without sending orders.

  3. Next

    Running it on the live market on paper, comparing each day with the simulator's replay of that same day, and then a small pilot to measure real fills against simulated ones.

  4. Final step

    Managing capital automatically as a gold portfolio, as a product beside the money-management fund.

Technology

The whole project is written in Python: preparing the market recordings, the execution simulator, the algorithm and the analysis. A full simulation of 21 funds over 21 months, second by second, takes about fifteen minutes on one machine, and several run side by side. No change is accepted without passing 55 automated tests, some of which were written to reproduce a past mistake so that it cannot return.