Quickstart¶
This tutorial serves as an overview of the main functionality of the Garpar system.
Imports¶
There are two important subpackages in Garpar:
optimizeallows applying optimization models.datasetscontains tools for market simulation.
You would generally import them as:
[1]:
from garpar import datasets, optimize
The StocksSet class¶
Most of the time the system will interact between modules with instances of the StocksSet class. This has the following representation:
[2]:
datasets.make_risso_normal()
[2]:
| Stocks | S0[W 1.0, H 0.5] | S1[W 1.0, H 0.5] | S2[W 1.0, H 0.5] | S3[W 1.0, H 0.5] | S4[W 1.0, H 0.5] | S5[W 1.0, H 0.5] | S6[W 1.0, H 0.5] | S7[W 1.0, H 0.5] | S8[W 1.0, H 0.5] | S9[W 1.0, H 0.5] |
|---|---|---|---|---|---|---|---|---|---|---|
| Days | ||||||||||
| 0 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 |
| 1 | 99.255892 | 98.643424 | 101.182556 | 100.976145 | 101.142664 | 99.229344 | 98.820761 | 99.197104 | 100.881702 | 100.798837 |
| 2 | 98.403726 | 97.941513 | 102.689855 | 100.055446 | 100.220380 | 98.205988 | 97.837035 | 99.885786 | 100.130212 | 99.650853 |
| 3 | 97.739785 | 99.010624 | 101.689523 | 100.938276 | 99.031921 | 99.265086 | 96.822695 | 101.121811 | 99.251223 | 98.828421 |
| 4 | 97.012671 | 98.355857 | 102.628715 | 100.388073 | 97.985321 | 98.237598 | 97.643243 | 99.908517 | 98.337190 | 99.621729 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 361 | 84.350353 | 103.526064 | 97.581859 | 121.705135 | 84.452154 | 99.770152 | 121.838193 | 80.917318 | 138.589922 | 96.987257 |
| 362 | 83.722518 | 102.315907 | 98.734285 | 122.937505 | 83.512030 | 98.965622 | 122.643050 | 81.689852 | 140.146500 | 95.750841 |
| 363 | 82.865639 | 101.536066 | 97.587011 | 124.154504 | 82.554307 | 99.997622 | 123.731972 | 82.316293 | 139.043815 | 96.653080 |
| 364 | 83.772011 | 103.128469 | 96.521585 | 122.928053 | 83.382551 | 99.131031 | 121.950915 | 81.557621 | 140.198926 | 95.810688 |
| 365 | 82.980717 | 101.904244 | 95.531620 | 121.637567 | 84.322867 | 98.034875 | 120.471671 | 82.182295 | 138.488500 | 94.909318 |
A StocksSet instance unifies the representation of a market and a portfolio, simplifying stock tracking and weight (W) management. It streamlines data handling and serves as a shared concept across all system modules. A market reflects the current stock values, while a portfolio consists (in this context) of assigned weights for each stock. We will explore these components in more detail throughout the tutorials. For now, let’s start with a basic example.
In this tutorial, we will simulate a market and apply an optimization model to demonstrate basic interactions with the system, providing an introduction to its functionality.
We can simulate a market by calling the make_risso_normal function from the datasets subpackage. This function will create an instance of StocksSet through a simulation. For consistency, we’ll specify just one parameter: random_state, which acts as the seed.
[3]:
ss = datasets.make_risso_normal(random_state=23)
ss
[3]:
| Stocks | S0[W 1.0, H 0.5] | S1[W 1.0, H 0.5] | S2[W 1.0, H 0.5] | S3[W 1.0, H 0.5] | S4[W 1.0, H 0.5] | S5[W 1.0, H 0.5] | S6[W 1.0, H 0.5] | S7[W 1.0, H 0.5] | S8[W 1.0, H 0.5] | S9[W 1.0, H 0.5] |
|---|---|---|---|---|---|---|---|---|---|---|
| Days | ||||||||||
| 0 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 |
| 1 | 100.766064 | 101.126354 | 101.056170 | 100.520483 | 99.278068 | 101.231624 | 101.454794 | 101.363444 | 100.618480 | 98.850608 |
| 2 | 101.767974 | 100.260879 | 100.115244 | 99.516454 | 98.228567 | 100.214519 | 102.472212 | 100.074498 | 101.245075 | 98.005358 |
| 3 | 103.171863 | 101.187614 | 99.261945 | 100.561238 | 97.054380 | 99.457204 | 101.534985 | 100.942186 | 100.124496 | 97.030506 |
| 4 | 104.240403 | 102.423134 | 98.378702 | 101.551601 | 95.927476 | 100.246909 | 102.232905 | 100.196595 | 98.964000 | 96.428484 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 361 | 104.845268 | 121.219172 | 131.868621 | 104.611151 | 142.212483 | 106.411823 | 100.923496 | 92.259337 | 120.218776 | 90.228541 |
| 362 | 105.897108 | 122.295360 | 130.769070 | 103.710214 | 143.863287 | 107.679350 | 102.327765 | 93.440659 | 121.197158 | 91.080514 |
| 363 | 107.368403 | 123.454928 | 132.064844 | 104.970441 | 142.355648 | 108.778114 | 103.399001 | 92.368845 | 120.270729 | 90.469203 |
| 364 | 108.435637 | 122.318475 | 133.215786 | 105.868644 | 140.662842 | 107.785096 | 104.275516 | 91.656621 | 121.732478 | 91.496238 |
| 365 | 107.026179 | 121.488850 | 134.581393 | 104.821875 | 139.648724 | 109.153324 | 105.619600 | 90.699211 | 123.443885 | 92.091881 |
Now that we have a StocksSet instance, let’s apply an optimization model and observe how the weights change. To analyze the effect, focus on the Ws in the top section of the StocksSet representation and compare them with their updated values after applying the following model:
[4]:
mk = optimize.mean_variance.Markowitz(target_risk=0.1)
mk.optimize(ss)
[4]:
| Stocks | S0[W 3.711507e-09, H 0.5] | S1[W 7.229484e-03, H 0.5] | S2[W 3.709488e-01, H 0.5] | S3[W 2.995300e-09, H 0.5] | S4[W 5.030012e-01, H 0.5] | S5[W 4.103622e-09, H 0.5] | S6[W 3.458309e-09, H 0.5] | S7[W 1.305153e-09, H 0.5] | S8[W 1.188205e-01, H 0.5] | S9[W 1.288363e-09, H 0.5] |
|---|---|---|---|---|---|---|---|---|---|---|
| Days | ||||||||||
| 0 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 |
| 1 | 100.766064 | 101.126354 | 101.056170 | 100.520483 | 99.278068 | 101.231624 | 101.454794 | 101.363444 | 100.618480 | 98.850608 |
| 2 | 101.767974 | 100.260879 | 100.115244 | 99.516454 | 98.228567 | 100.214519 | 102.472212 | 100.074498 | 101.245075 | 98.005358 |
| 3 | 103.171863 | 101.187614 | 99.261945 | 100.561238 | 97.054380 | 99.457204 | 101.534985 | 100.942186 | 100.124496 | 97.030506 |
| 4 | 104.240403 | 102.423134 | 98.378702 | 101.551601 | 95.927476 | 100.246909 | 102.232905 | 100.196595 | 98.964000 | 96.428484 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 361 | 104.845268 | 121.219172 | 131.868621 | 104.611151 | 142.212483 | 106.411823 | 100.923496 | 92.259337 | 120.218776 | 90.228541 |
| 362 | 105.897108 | 122.295360 | 130.769070 | 103.710214 | 143.863287 | 107.679350 | 102.327765 | 93.440659 | 121.197158 | 91.080514 |
| 363 | 107.368403 | 123.454928 | 132.064844 | 104.970441 | 142.355648 | 108.778114 | 103.399001 | 92.368845 | 120.270729 | 90.469203 |
| 364 | 108.435637 | 122.318475 | 133.215786 | 105.868644 | 140.662842 | 107.785096 | 104.275516 | 91.656621 | 121.732478 | 91.496238 |
| 365 | 107.026179 | 121.488850 | 134.581393 | 104.821875 | 139.648724 | 109.153324 | 105.619600 | 90.699211 | 123.443885 | 92.091881 |
The change in weights is what we aim for when applying optimization models.
This concludes the quickstart. We recommend continuing with this tutorial.