REPLICATION PACKAGE - CODE ONLY - Algorithmic Pricing and Liquidity in Securities Markets
Jean-Edouard Colliard, Thierry Foucault, Stefano Lovo
Conditionally accepted, Review of Financial Studies


12 November 2025


OVERVIEW

This replication package contains the codes for the paper "Algorithmic Pricing and Liquidity in Securities Markets" by Jean-Edouard Colliard, Thierry Foucault, and Stefano Lovo. For each figure in the paper or the Online Appendix, the replication package gives the codes used to run the simulations studied in the paper. The file List_Figures.xlsx lists all the figures and the corresponding codes. Running the simulation codes will produce the same simulation data we have used. Once the data has been generated, the package also gives the code used to generate each figure from the data. 

This version of the package only includes the codes. Researchers who wish to reproduce our figures will have to run the simulations again, which took a total of around 110 hours on the virtual machine we have used (more below). We also offer an alternative version of the replication package, titled "REPLICATION PACKAGE - CODE AND DATA", which also includes all the simulation data. The alternative version is substantially heavier (1.14 GB instead of 3.22 MB).

Note that some figures require extensive simulations and the associated codes may take several hours to run. Thus, the replication package is organized in different folders, each one corresponding to a different figure or numerical exercise. We recommend running these folders one by one. The folders are independent of each other and can be run in any order.

Figures 1, 2, and 6 are simple numerical illustrations. The corresponding folders "Figure 1", "Figure 2", and "Figure 6" contain only one file (.tex or .nb) that generates the figure as well as the figures generated.

All the other folders use the same structure. They contain one or several files starting with "script_simulation", one or several files starting with "simulation_exp", one or several files starting with "simulation_rep", and one or several files starting with "script_fig" or "script_table". In addition, each folder contains a subfolder called "Data" and a subfolder called "Figures". The flow is always the following: (i) "script_simulation" is the main script that launches the simulations. It calls "simulation_rep" to run K experiments with given parameters (it may call simulation_rep several times if the figure compares different parameter values) and saves statistics about the experiments in the folder "Data"; (ii) "simulation_rep" calls "simulation_exp" K times to generate K independent experiments, and records statistics about those experiments (e.g., average values of different variables of interest); (iii) "simulation_exp" runs one experiment of T episodes and records the realized history; (iv) "script_fig" or "script_table" reads the data recorded in the folder "Data" to produce figures or tables, and stores them in the folder "Figures". In this version of the replication package the folders "Data" and "Figures" are initially empty and are updated when running the scripts.

All the .m files are fully commented.

.m files were run using Matlab R2023b. 
.nb files were run using Wolfram Mathematica 13.2.
.tex files were run with WinEdt, using in particular the tikz package.

The .m files were run on an Azure virtual machine "Standard F16s v2" with 16 virtual CPUs and 32 GB of RAM. Both this Readme and comments in the .m files give the running times obtained on that virtual machine (only for scripts that take a significant time to run). 

Some of the .m files use parallel computing. To turn off parallel computing, comment out the following lines in "script_simulation":

delete(gcp("nocreate"));  
myCluster = parcluster('local'); 
parpool('local',8);

and replace any instance of "parfor" with "for" (in "simulation_rep" and "simulation_exp").

Note that the parallel computing sets the number of workers at 8, to ensure the reproducibility of the published results. When using a machine that cannot handle 8 workers, or when using a machine that can handle more than 8 workers and hence do the computations faster, one can replace the line:

parpool('local',8);

with:

parpool('local',myCluster.NumWorkers);

This will make sure that the machine uses the maximum number of workers. However, this will lead to random draws different from those that were used to generate the figures (see Note 1 below).

Note 1: Most of the figures are based on Monte Carlo simulations. To facilitate reproducibility, all simulations use a given random seed (command "rng(1)" in "script_simulation"). It is important to understand how this interacts with parallel computing. With this specification, each worker will use an independent sequence of random draws, the same sequence each time the program is executed. All the programs were run with 8 workers. If one runs the program with a different number of workers, the results will no longer be numerically equal. For instance, with 10 workers, the 8 first workers will use the same sequence of random draws as those used in the figures, but the other 2 will use different sequences. Even when running the programs with 8 workers, there will be minor discrepancies. The reason is that each figure uses 1,000 experiments for each set of parameters, and parallelization is done at the experiment level. On average, each of the 8 workers will complete 125 experiments. However, on a given execution, it may happen out of chance that a worker was so fast that it completed 126 experiments, and another worker only 124. When this happens, the extra experiment conducted by the first worker hence uses different random draws from the ones in the original execution. In some figures, there are many simulations and these differences accumulate, creating minor discrepancies in the figures generated. Otherwise, running the code independently should produce the exact same random draws we obtained in our simulations, and the data generated should be numerically the same. 

One exception is Table OA.2 in the Online Appendix. In that table we report the estimates a dealer would have after only a few experiments. Since the allocation of the different experiments to the different workers is different in each execution, the numbers will be different each time. This is actually in line with the message of Table OA.2, which is precisely that the results are not reliable for small values of K'.

The command "rng(1)" can be commented out to run the simulations with new random draws, independent from the ones we used. This makes little to no difference in practice as we rely on 1,000 iid draws for every estimation. An exception is again Table OA.2 in the Online Appendix, where again the point is precisely that the estimates are noisy. 

Finally, please keep in mind that "rng(1)" is used at the beginning of each script, but some scripts take very long to execute (up to around 55 hours). It can be convenient to run the script in several steps, e.g., one set of parameters at a time, but then this will change the random draws. In principle all the results reported in the paper were derived after executing the corresponding script in one go.

Note 2: The codes may sometimes use slightly different terms from those used in the final version of the paper. Two frequent examples are the use of "AMM" instead of "AM", and "Baseline case" and "Private values case" instead of "Adverse selection case" and "No adverse selection case".

Note 3: When generating Figure 8, by mistake we used only 7 workers instead of 8. This change is immaterial but using 8 workers instead will lead to different random draws and hence numbers that will not be numerically equal (see Note 1). To ensure reproducibility the code in this package keeps the original value of 7 workers.


INSTRUCTIONS, FIGURE BY FIGURE


- Figure 1:

Open the folder "Figure_1". It contains: "Fig_1.tex".

Run Fig_1.tex. This will generate Fig_1.pdf, which is Figure 1 in the paper (this tikz code is directly included in the latex source file for the paper).


- Figure 2:

Open the folder "Figure_2". It contains: "Fig_2.nb", "Fig_2_a.pdf", and "Fig_2_b.pdf".

Run Fig_2.nb. This will generate Fig_2_a.pdf and Fig_2_b.pdf, which are the left and right panels of Figure 2 in the paper, respectively.


- Figure 3:

Open the folder "Figure_3". It contains: "script_simulation.m", "simulation_exp.m", "simulation_rep.m", "script_figure_3.m", and two empty subfolders called "Data" and "Figures".

Run script_simulation.m. This script will call simulation_rep.m, which itself calls simulation_exp.m. The script will generate simulation data and save it as av_all_episodes.txt and last_episodes.txt in the folder "Data". Running the script took around 20 minutes on our virtual machine. 

Run script_figure_3.m. The script will read the data from av_all_episodes.txt and last_episodes.txt, produce the graphs Fig_3_a.png and Fig_3_b.png, which are Panels A and B of Figure 3 in the paper, and save them in the folder "Figures".


- Figure 4:

Open the folder "Figure_4". It contains: "script_simulation.m", "simulation_exp.m", "simulation_rep.m", "simulation_exp_private.m", "simulation_rep_private.m", "script_figure_4.m", and two empty subfolders called "Data" and "Figures". 

Run script_simulation.m. This script will first call simulation_rep.m, which itself calls simulation_exp.m. This will generate simulation data for the adverse selection case and save it as last_episodes_x.txt in the folder "Data", where x is between 1 and 9 (corresponding to different values of sigma). The script then calls simulation_rep_private.m, which itself calls simulation_exp_private.m. This will generate simulation data for the private values case and save it as last_episodes_private_x.txt in the folder "Data", where x is between 1 and 9 (corresponding to different values of sigma). Running the script took around 6 hours on our virtual machine. 

Run script_figure_4.m. The script will read the data from the 18 files last_episodes_x.txt and last_episodes_private_x.txt, produce the graphs Fig_4_a.png and Fig_4_b.png, which are Panels A and B of Figure 4 in the paper, and save them in the folder "Figures". 


- Figure 5: 

Open the folder "Figure_5". It contains: "script_simulation.m", "simulation_exp.m", "simulation_rep.m", "simulation_exp_private.m", "simulation_rep_private.m", "script_figure_5.m", and two empty subfolders called "Data" and "Figures". 

Run script_simulation.m. This script will first call simulation_rep.m, which itself calls simulation_exp.m. This will generate simulation data for the adverse selection case and save it as last_episodes_x.txt in the folder "Data", where x is between 0 and 8 (corresponding to different values of Delta_v). The script then calls simulation_rep_private.m, which itself calls simulation_exp_private.m. This will generate simulation data for the private values case and save it as last_episodes_private_x.txt in the folder "Data", where x is between 0 and 8 (corresponding to different values of Delta_v). Running the script took around 6 hours on our virtual machine. 

Run script_figure_5.m. The script will read the data from the 18 files last_episodes_x.txt and last_episodes_private_x.txt, produce the graphs Fig_5_a.png and Fig_5_b.png,  which are Panels A and B of Figure 5 in the paper, and save them in the folder "Figures". 


- Figure 6:

Open the folder "Figure_6". It contains: "Fig_6.tex".

Run Fig_6.tex. This will generate Fig_6.pdf, which is Figure 6 in the paper (this tikz code is directly included in the latex source file for the paper).


- Figure 7:

Open the folder "Figure_7". It contains: "script_simulation.m", "simulation_exp.m", "simulation_rep.m", "script_figure_7.m", and two empty subfolders called "Data" and "Figures". 

Run script_simulation.m. This script will first call simulation_rep.m, which itself calls simulation_exp.m. This will generate simulation data and save it as av_all_episodes.txt and last_episodes.txt in the folder "Data". Running the script took around 5 minutes on our virtual machine. 

Run script_figure_7.m. The script will read the data from the files last_episodes.txt and av_all_episodes.txt, produce the graphs Fig_7_a.png and Fig_7_b.png, which are Panels A and B of Figure 7 in the paper, and save them in the folder "Figures". 


- Figure 8: 

Open the folder "Figure_8". It contains: "script_simulation.m", "simulation_exp.m", "simulation_rep.m", "simulation_exp_private.m", "simulation_rep_private.m", "script_figure_8.m", and two empty subfolders called "Data" and "Figures". 

Run script_simulation.m. This script will first call simulation_rep.m, which itself calls simulation_exp.m. This will generate simulation data for the adverse selection case and save it as last_episodes_x.txt in the folder "Data", where x is between 2 and 10 (corresponding to different values of N). The script then calls simulation_rep_private.m, which itself calls simulation_exp_private.m. This will generate simulation data for the private values case and save it as last_episodes_private_x.txt in the folder "Data", where x is between 2 and 10 (corresponding to different values of N). Running the script took around 13 hours on our virtual machine (the running time for a simulation with a given N increases with N). 

Run script_figure_8.m. The script will read the data from the 18 files last_episodes_x.txt and last_episodes_private_x.txt, produce the graphs Fig_8_a.png and Fig_8_b.png, which are Panels A and B of Figure 8 in the paper, and save them in the folder "Figures". 


- Figure 9: 

Open the folder "Figure_9". It contains: "script_simulation.m", "simulation_exp.m", "simulation_rep.m", "script_figure_9.m", and two empty subfolders called "Data" and "Figures". 

Run script_simulation.m. This script will first call simulation_rep.m, which itself calls simulation_exp.m. This will generate simulation data for different values of the tick size and save it aslast_episodes_x.txt in the folder "Data", where x is between 1 and 5 (corresponding to different values of the tick size). The script will then repeat the simulation but adjust beta to the tick size, and save last_episodes_beta_x.txt in the folder "Data". Running the script took around 4 hours on our virtual machine (the running time for a simulation is higher when the tick size is lower). 

Run script_figure_9.m. The script will read the data from the 20 files last_episodes_x.txt and last_episodes_beta_x.txt, produce the graphs Fig_9_a.png, Fig_9_b.png, Fig_9_c.png, and Fig_9_d.png, which are Panels A, B, C, and D of Figure 9 in the paper, and save them in the folder "Figures". 


- Figure 10: 

Open the folder "Figure_10". It contains: "script_simulation.m", "simulation_exp.m", "simulation_rep.m", "script_figure_10.m", and two empty subfolders called "Data" and "Figures". 

Run script_simulation.m. This script will first call simulation_rep.m, which itself calls simulation_exp.m. This will generate simulation data for Delta_v' = 7, 1, and 4, and save them as av_all_episodes_Deltav_7_Ts_1000.txt, av_all_episodes_Deltav_1_Ts_1000.txt, and av_all_episodes_Placebo.txt, respectively, in the folder "Data". Running the script took around 2 hours on our virtual machine.

Run script_figure_10.m. The script will read the data from the 3 files av_all_episodes_Deltav_7_Ts_1000.txt, av_all_episodes_Deltav_1_Ts_1000.txt, and av_all_episodes_Placebo.txt, produce the graphsFig_10_a.png, Fig_10_b.png, Fig_10_c.png, and Fig_10_d.png, which are Panels A, B, C, and D of Figure 10 in the paper, and save them in the folder "Figures". 


- Figures 11 and 12:

Open the folder "Figures_11-12". It contains: "script_simulation.m", "simulation_exp.m", "simulation_rep.m", "script_figure_11.m", "script_figure_12.m", and two empty subfolders called "Data" and "Figures". 

Run script_simulation.m. This script will first call simulation_rep.m, which itself calls simulation_exp.m. This will generate simulation data for different values of sigma and save it as last_episodes_x.txt in the folder "Data", where x is between 1 and 9 (corresponding to different values of sigma). Running the script took around 10 hours on our virtual machine.

Run script_figure_11.m. The script will read the data from the 9 files last_episodes_x.txt, produce the graph Fig_11.png, which is Figure 11 in the paper, and save it in the folder "Figures". 

Run script_figure_12.m. The script will read the data from the 9 files last_episodes_x.txt, produce the graph Fig_12.png, which is Figure 12 in the paper, and save it in the folder "Figures". 


- Footnote 21 (Kolmogorov-Smirnov tests):

Open the folder "Footnote_KS". It contains: "script_simulation.m", "simulation_exp.m", "simulation_rep.m", "script_test.m", and one empty subfolder called "Data". 

Run script_simulation.m. This script will first call simulation_rep.m, which itself calls simulation_exp.m. This will generate simulation data for the baseline parameters, record the prices in different episodes for K = 1000 experiments, and save them as T_episodes.txt in the folder "Data". Running the script took around 20 minutes on our virtual machine.

Run script_test.m. The script will read the data from T_episodes.txt and produce the p-values reported in Footnote 21 in the paper.


- Online Appendix, Figure OA.1:

Open the folder "OnlineAppendix_Figure_OA_1". It contains: "script_simulation.m", "simulation_exp.m", "simulation_rep.m", "script_figure_OA_1.m", and two empty subfolders called "Data" and "Figures". 

Run script_simulation.m. This script will call simulation_rep.m, which itself calls simulation_exp.m. The script will generate simulation data and save it as av_all_episodes.txt and last_episodes.txt in the folder "Data". Running the script took around 20 minutes on our virtual machine. 

Run script_figure_OA_1.m. The script will read the data from av_all_episodes.txt and last_episodes.txt, produce the graphs Fig_OA_1_a.png and Fig_OA_b.png, which are Panels A and B of Figure OA.1 in the Online Appendix, and save them in the folder "Figures".


- Online Appendix, Figures OA.2, OA.3, and OA.4: 

Open the folder "OnlineAppendix_Figure_OA_2-3-4". It contains: "script_simulation.m", "simulation_exp.m", "simulation_rep.m", "simulation_exp_private.m", "simulation_rep_private.m", "script_figure_OA_2_3_4.m", and two empty subfolders called "Data" and "Figures". 

Run script_simulation.m. This script will first call simulation_rep.m, which itself calls simulation_exp.m. This will generate simulation data for the adverse selection case and save it as last_episodes_x_y.txt in the folder "Data", where x and y are between 1 and 9 (x corresponds to 9 values of sigma and y to different (alpha,beta) pairs). The script then calls simulation_rep_private.m, which itself calls simulation_exp_private.m. This will generate simulation data for the private values case and save it as last_episodes_private_x_y.txt in the folder "Data", where x and y are between 1 and 9 (x corresponds to 9 values of sigma and y to different (alpha,beta) pairs). Running the script took around 55 hours on our virtual machine. 

Run script_figure_OA_2_3_4.m. The script will read the data from last_episodes_x_y.txt and last_episodes_private_x_y.txt, produce the graphs Fig_OA_2_x_y.png, with x between 1 and 9 and y equal to 1 or 2, and save them in the folder "Figures". The figures with y = 1 and x between 1 and 3, 4 and 6, and 7 and 9 correspond to the left-hand side panels of Figures OA.2, OA.3, and OA.4, respectively. The figures with y = 2 and x between 1 and 3, 4 and 6, and 7 and 9 correspond to the right-hand side panels of Figures OA.2, OA.3, and OA.4, respectively. 


- Online Appendix, Figure OA.5: 

Open the folder "OnlineAppendix_Figure_OA_5". It contains: "script_simulation.m", "simulation_exp.m", "simulation_rep.m", "script_figure_OA_5.m", and two empty subfolders called "Data" and "Figures". 

Run script_simulation.m. This script will call simulation_rep.m, which itself calls simulation_exp.m. The script will generate simulation data and save it as last_episodes_fixed.txt and last_episodes_random.txt in the folder "Data". Running the script took around 1 minute on our virtual machine. 

Run script_figure_OA_5.m. The script will read the data from last_episodes_fixed.txt and last_episodes_random.txt, produce the graphs Fig_OA_5_a.png and Fig_OA_5_b.png, which are Panels A and B of Figure OA.5 in the Online Appendix, and save them in the folder "Figures".


- Online Appendix, Figures OA.6, OA.7, and OA.8: 

Open the folder "OnlineAppendix_Figure_OA_6-7-8". It contains: "script_master.m", "script_simulation.m", "script_simulation_exclusion.m", "script_simulation_accommodation.m", "script_rep.m", "script_rep_exclusion.m", "script_rep_accommodation.m", "script_exp.m", "script_exp_exclusion.m", "script_exp_accommodation.m", "script_figure_OA_6_7_8.m", and two empty subfolders called "Data" and "Figures". 

Run script_master.m. This script will run script_simulation.m, which will call simulation_rep.m, which itself calls simulation_exp.m. The script script_simulation.m will generate simulation data and save it as last_episodes.txt and av_all_episodes.txt in the folder "Data". The script script_master.m will then run script_simulation_exclusion.m, which will call simulation_rep_exclusion.m, which itself calls simulation_exp_exclusion.m. The script script_simulation_exclusion.m will generate simulation data and save it as last_episodes_exclusion.txt and av_all_episodes_exclusion.txt in the folder "Data". The script script_master.m will finally run script_simulation_accommodation.m, which will call simulation_rep_accommodation.m, which itself calls simulation_exp_accommodation.m. The script script_simulation_accommodation.m will generate simulation data and save it as last_episodes_accommodation.txt and av_all_episodes_accommodation.txt in the folder "Data". Running script_master.m took 45 minutes on our virtual machine. 
 
Run script_figure_OA_6_7_8.m. The script will read the data from last_episodes.txt, last_episodes_exclusion.txt, last_episodes_accommodation.txt, av_all_episodes.txt, av_all_episodes_exclusion.txt, and av_all_episodes_accommodation.txt, produce the graphs Fig_OA_6_a.png and Fig_OA_6_b.png (Panels A and B of Figure OA.6 in the Online Appendix), Fig_OA_7_a.png, Fig_OA_7_b.png, Fig_OA_7_c.png, and Fig_OA_7_d.png (Panels A, B, C, and D of Figure OA.7 in the Online Appendix), and Fig_OA_8_a.png, Fig_OA_8_b.png, Fig_OA_8_c.png, and Fig_OA_8_d.png (Panels A, B, C, and D of Figure OA.8 in the Online Appendix), and save them in the folder "Figures".


- Online Appendix, Tables OA.1, OA.2, and OA.3: 

Open the folder "OnlineAppendix_Table_OA_1-2-3". It contains: "script_simulation.m", "simulation_exp.m", "simulation_rep.m", "script_table_OA_1_2_3.m", "table2latex.m" (Víctor Martínez-Cagigal (2025), MATLAB Table to LaTeX conversor, MATLAB Central File Exchange), and two empty subfolders called "Data" and "Figures". 

Run script_simulation.m. This script will call simulation_rep.m, which itself calls simulation_exp.m. The script will generate simulation data and save it as last_episodes_i_j.txt in the folder "Data", for each of the 45 pairs (i,j). Running the script took around 13 hours on our virtual machine. 

Run script_table_OA_1_2_3.m. The script will read the data from all the files last_episodes_i_j.txt, produce tables corresponding to Tables OA.1, OA.2, and OA.3, and use table2latex.m to save them in latex format in the folder "Figures" as Table_OA_1.tex, Table_OA_2.tex, and Table_OA_3.tex, which are the data reported in Tables OA.1, OA.2, and OA.3 in the Online Appendix.
