-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtldrKandleManagement.tex
192 lines (144 loc) · 6.25 KB
/
tldrKandleManagement.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
\documentclass[oneside,12pt]{article}
\frenchspacing
\usepackage{geometry}
\geometry{a4paper}
\geometry{landscape}
% \geometry{columnsep=80pt}
% \geometry{paperwidth=1280pt}
% \geometry{paperheight=720pt}
\usepackage[utf8]{inputenc}
% \usepackage{fontspec}
%\setmainfont{optima}
\usepackage{ulem}
\usepackage{color}
\usepackage{amssymb}
\usepackage{extarrows}
\usepackage{/Users/V/icd/sty/vmacros}
\usepackage{/Users/V/icd/sty/tokens}
\usepackage[colorlinks=true]{hyperref}
\usepackage{graphicx}
\title{Testing Kandle-based strategies using an ocaml simulator}
\author{Mangrove Research}
\begin{document}
\maketitle
You need to install ocaml.
Eg via the \href{https://opam.ocaml.org/doc/Install.html}{opam package manager}
\section{Setup}
\subsection{Setup price series}
To run a test we first need to get a price series.
There are two options.
We can use a csv file of historical data (see \ttt{h} function):
\begin{verbatim}
let h
~number_of_lines:nb_lines (* nb_lines to read after header *)
~filename:filename (* path to csv file *)
~column:col (* index of price column in file *)
~splitchar:c (* split char in the csv file *)
= ...
\end{verbatim}
Or we can use a BM or GBM with parameters:
\begin{verbatim}
let gbrowmo
~initial_value:ival (* initial price value *)
~drift:drift (* drift of BM *)
~volatility:vol (* volatility of BM *)
~timestep:dt (* integration step *)
~duration:duration (* total duration *)
= ...
\end{verbatim}
Both methods output a price series as an array of floats.
\subsection{Setup Kandle}
To define a Kandle instance one needs:
\\ - a (relative) price grid
\\ - an initial allocation of capital (in quote),
\\ - and the fraction $\al$ of the said quote to be swapped to base (to provide Kandle's asks)
The relative price grid is defined by picking any 2 of the following 3 parameters:
\\- (half) number of points,
\\- range multiplier,
\\- gridstep (aka ratio)
The initial price (or entry price)
used to center the grid is taken from the price series (hence the name `relative' price grid).
\section{Plain simulation}
A simulation is the interaction of a Kandle with a price series.
The output of a simulation run is a 6-uple:
\\- the return
\\- the number of up crossings and up exits (above range)
\\- the number of down crossings and down exits (below range)
\\- the final price of the price series
To set up a run of the simulation,
we combine both sets of parameters (using here range and gridstep for the price grid).
Inputs:
\begin{verbatim}
let sim
~rangeMultiplier:rangeMultiplier (* pmax/p0 = p0/pmin *)
~gridstep:gridstep (* ratio of price grid *)
~quote:qB (* total budget in quote *)
~cashmix:alpha (* 0 <= alpha <= 1 *)
~start:start (* entry in position *)
~duration:duration (* number of price moves *)
~price_series:price_series (* series of price *)
\end{verbatim}
Outputs:
\begin{verbatim}
(mtmf /. mtmi -. 1.),
!rebu,
!cross_above,
!rebd, !cross_below,
price_series.(start + duration - 1)
\end{verbatim}
Fig.~\ref{sim} shows an example of a 1000 runs, 10000 steps each.
The syntax is
\begin{verbatim}
./a.out 1000 10 1.25
\end{verbatim}
with arguments (in this order): number of repetitions, number of points on the grid, and ratio of the grid.
The compiled code will generate a csv file \ttt{return\_vs\_final\_price\_scatter\_1.25\_10\_stopped.csv}.
The csv file can be visualised using a python script called \ttt{hist.py} with similar syntax \ttt{python hist.py 10 1.25}.
\IG{300pt}
{alms/png/return_vs_final_price_scatter.png}
{\label{sim} On the $x$-axis the final price, on the $y$-axis the return. In red (green) realisations with a negative (positive) return.}
\section{Simulation with exit}
There is a variant, called \ttt{sim\_stopped}, that will stop if the price exits the range. So no need to specify a duration.
Either the simulation will stop (an return the time of exit and price), and it will run all the way to the
end of the price series.
Inputs:
\begin{verbatim}
let sim_stopped
~rangeMultiplier:rangeMultiplier
~gridstep:gridstep
~quote:qB
~cashmix:alpha
~start:start
~price_series:price_series
\end{verbatim}
Outputs:
\begin{verbatim}
mtmf /. mtmi, (* growth rate, because more compositional *)
!rebu, !upper_exit,
!rebd, !lower_exit,
!current_index,
!current_price
\end{verbatim}
\NB[1] \ttt{sim\_stopped} returns the growth rate $\ttt{mtmf /. mtmi}$ not the return $\ttt{mtmf /. mtmi} - 1$.
Fig.~\ref{simstopped} shows an example of a 1000 runs, 10000 steps each (under 2sec of execution, using the native compiler ocamlopt).
We see the green and red walls at the ends of the range near the $\pm20\%$ mark.
\IG{250pt}
{alms/png/return_vs_final_price_scatter_1.05_4_stopped.png}
{\label{simstopped} On the $x$-axis the final price, on the $y$-axis the return. The Kandle grid has 4 points (on each side of the entry price of $100$), with a ratio of $1.05$.}
\section{Simulation with reset}
There is also a \ttt{sim\_reset} variant where each time the price exits the range,
the strategy re-enters with the same grid translated to the new current price.
Note that price-tracking Kandle is subtly different from a vanilla MM strategy which translates its price grid each time the price moves (at a given frequency),
regardless of whether one of its offers was consumed or not.
The difference is that in the latter case even in the absence of crossing the price stays always $\eps$ away from the current price.
% It would be interesting to simulate that as well.
Todo: implement the vanilla MM strategy and measure the payoff difference (MM should be better).
Fig.~\ref{simReset} shows an example where $r=1.02$, with 1 offer on each side of the entry price, and a price GBM $\mu=0$, $\sig=0.08$.
One sees that the payoff shape is very different, and looks
similar to a buy and hold with half the cash invested (black line)
with some low amount of noise induced by the path-dependent crossings.
\IG{250pt}
{alms/png/return_vs_final_price_scatter_1.02_0.08.png}
{\label{simReset} The regression line is close to that of a buy-and-hold strategy
with half the cash invested in the risky asset.}
\end{document}