File size: 114,253 Bytes
5e78fe5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d0f2aec
 
 
 
 
 
 
 
 
 
 
 
5e78fe5
 
d0f2aec
 
 
 
5e78fe5
 
 
 
5d5dd44
5e78fe5
 
 
d0f2aec
 
 
 
 
 
 
 
 
5e78fe5
 
 
 
a39f235
5e78fe5
 
 
 
 
 
 
 
 
 
 
d0f2aec
5e78fe5
 
 
5d5dd44
 
 
 
 
d0f2aec
 
5d5dd44
 
 
5e78fe5
 
 
 
5d5dd44
 
 
 
 
 
 
 
 
 
 
5e78fe5
 
 
 
5d5dd44
5e78fe5
 
 
 
 
 
 
 
 
 
d0f2aec
5e78fe5
 
 
 
 
 
5d5dd44
 
 
 
 
 
 
 
5e78fe5
 
ab0f626
5e78fe5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5d5dd44
5e78fe5
 
 
 
 
 
5d5dd44
 
5e78fe5
 
 
 
 
 
 
 
 
 
 
ab0f626
5e78fe5
 
 
 
 
 
 
 
 
 
 
 
 
 
5d5dd44
 
 
 
5e78fe5
 
 
 
d0f2aec
5e78fe5
 
 
 
 
 
 
 
 
 
 
d0f2aec
5e78fe5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d0f2aec
5e78fe5
 
 
d0f2aec
 
 
 
 
 
 
 
5e78fe5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5d5dd44
5e78fe5
 
 
 
 
 
 
 
5d5dd44
5e78fe5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5d5dd44
5e78fe5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d0f2aec
5e78fe5
 
 
 
5d5dd44
 
5e78fe5
 
 
 
 
 
 
5d5dd44
5e78fe5
5d5dd44
5e78fe5
 
 
 
 
d0f2aec
5e78fe5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d0f2aec
5e78fe5
 
 
 
 
 
 
 
 
 
 
 
 
d0f2aec
5e78fe5
 
 
 
 
d0f2aec
5e78fe5
 
d0f2aec
5e78fe5
 
 
 
 
5d5dd44
 
5e78fe5
5d5dd44
 
 
 
 
 
 
5e78fe5
 
 
 
d0f2aec
5e78fe5
 
 
 
 
 
 
 
 
 
 
d0f2aec
5e78fe5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d0f2aec
5e78fe5
 
 
 
 
d0f2aec
5e78fe5
 
d0f2aec
5e78fe5
 
 
 
 
 
 
 
 
 
5d5dd44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d0f2aec
5e78fe5
 
 
d0f2aec
5e78fe5
 
 
 
 
 
 
 
 
d0f2aec
5e78fe5
 
 
 
 
 
 
 
d0f2aec
 
 
 
 
5e78fe5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d0f2aec
5e78fe5
 
 
 
 
d0f2aec
5e78fe5
 
 
 
5d5dd44
5e78fe5
 
 
 
 
 
 
 
d0f2aec
 
 
 
5e78fe5
 
d0f2aec
5e78fe5
 
 
 
 
 
d0f2aec
5d5dd44
5e78fe5
 
 
 
 
 
d0f2aec
5e78fe5
 
 
 
d0f2aec
5e78fe5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5d5dd44
 
d0f2aec
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5d5dd44
 
 
 
 
 
d0f2aec
5d5dd44
 
 
d0f2aec
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d577657
d0f2aec
 
 
 
 
 
 
 
5d5dd44
 
 
 
 
 
 
 
 
 
 
 
 
 
5e78fe5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nwaAZRu1NTiI"
      },
      "source": [
        "# Q-learning \n",
        "\n",
        "#### This version implements q-learning using a custom enviroment \n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "DDf1gLC2NTiK"
      },
      "outputs": [
        {
          "ename": "",
          "evalue": "",
          "output_type": "error",
          "traceback": [
            "\u001b[1;31mFailed to start the Kernel. \n",
            "Cannot execute code, session has been disposed. \n",
            "View Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details."
          ]
        }
      ],
      "source": [
        "# !pip install -r ./requirements.txt\n",
        "# !pip install stable_baselines3[extra]\n",
        "# !pip install yfinance\n",
        "# !pip install talib-binary\n",
        "# !pip install huggingface_sb3\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "id": "LNXxxKojNTiL"
      },
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "\n"
          ]
        }
      ],
      "source": [
        "import gym\n",
        "from gym import spaces\n",
        "from gym.utils import seeding\n",
        "\n",
        "import talib as ta\n",
        "from tqdm.notebook import tqdm\n",
        "\n",
        "import yfinance as yf\n",
        "import pandas as pd\n",
        "import numpy as np\n",
        "from matplotlib import pyplot as plt\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "dmAuEhZZNTiL"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "3024\n",
            "1875\n"
          ]
        }
      ],
      "source": [
        "# Get data\n",
        "eth_usd = yf.Ticker(\"ETH-USD\")\n",
        "eth = eth_usd.history(period=\"max\")\n",
        "\n",
        "btc_usd = yf.Ticker(\"BTC-USD\")\n",
        "btc = btc_usd.history(period=\"max\")\n",
        "print(len(btc))\n",
        "print(len(eth))\n",
        "\n",
        "btc_train = eth[-3015:-200]\n",
        "# btc_test = eth[-200:]\n",
        "eth_train = eth[-1864:-200]\n",
        "eth_test = eth[-200:]\n",
        "# len(eth_train)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {},
      "outputs": [],
      "source": [
        "def initialize_q_table(state_space, action_space):\n",
        "  Qtable = np.zeros((state_space, action_space))\n",
        "  return Qtable"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Policy\n",
        "\n",
        "def greedy_policy(Qtable, state):\n",
        "    # Exploitation: take the action with the highest state, action value\n",
        "    # if we dont have a state with values return DO_NOTHING \n",
        "    if abs(np.max(Qtable[state])) > 0:\n",
        "        action = np.argmax(Qtable[state])\n",
        "    else:\n",
        "        action = 2\n",
        "    # action = np.argmax(Qtable[state])\n",
        "    return action\n",
        "\n",
        "\n",
        "def epsilon_greedy_policy(Qtable, state, epsilon, env):\n",
        "  # Randomly generate a number between 0 and 1\n",
        "  random_num = np.random.uniform(size=1)\n",
        "  # if random_num > greater than epsilon --> exploitation\n",
        "  if random_num > epsilon:\n",
        "    # Take the action with the highest value given a state\n",
        "    # np.argmax can be useful here\n",
        "    action = greedy_policy(Qtable, state)\n",
        "  # else --> exploration\n",
        "  else:\n",
        "    # action = np.random.random_integers(4,size=1)[0]\n",
        "    action = env.action_space.sample()\n",
        "  \n",
        "  return action"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "id": "wlC-EdLENTiN"
      },
      "outputs": [],
      "source": [
        "def train(n_training_episodes, min_epsilon, max_epsilon, decay_rate, env, max_steps, Qtable, learning_rate, gamma):\n",
        "  state_history = []\n",
        "  \n",
        "  for episode in range(n_training_episodes):\n",
        "    # Reduce epsilon (because we need less and less exploration)\n",
        "    epsilon = min_epsilon + (max_epsilon - min_epsilon)*np.exp(-decay_rate*episode)\n",
        "    # Reset the environment\n",
        "    state = env.reset()\n",
        "    step = 0\n",
        "    done = False\n",
        "\n",
        "    # repeat\n",
        "    for step in range(max_steps):\n",
        "      # Choose the action At using epsilon greedy policy\n",
        "      action = epsilon_greedy_policy(Qtable, state, epsilon, env)\n",
        "\n",
        "      # Take action At and observe Rt+1 and St+1\n",
        "      # Take the action (a) and observe the outcome state(s') and reward (r)\n",
        "      new_state, reward, done, info = env.step(action)\n",
        "\n",
        "      # Update Q(s,a):= Q(s,a) + lr [R(s,a) + gamma * max Q(s',a') - Q(s,a)]\n",
        "      Qtable[state][action] = Qtable[state][action] + learning_rate * (reward + gamma * ( np.max(Qtable[new_state])  ) -  Qtable[state][action] )\n",
        "\n",
        "      # If done, finish the episode\n",
        "      if done:\n",
        "        break\n",
        "      \n",
        "      # Our next state is the new state\n",
        "      state = new_state\n",
        "\n",
        "      state_history.append(state)  \n",
        "\n",
        "  return Qtable, state_history"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "metadata": {},
      "outputs": [],
      "source": [
        "from enum import Enum\n",
        "class Actions(Enum):\n",
        "    Sell = 0\n",
        "    Buy = 1\n",
        "    Do_nothing = 2\n",
        "\n",
        "class CustTradingEnv(gym.Env):\n",
        "\n",
        "    def __init__(self, df, max_steps=0, random_start=True):\n",
        "        self.seed()\n",
        "        self.df = df\n",
        "        self.prices, self.signal_features = self._process_data()\n",
        "\n",
        "        # spaces\n",
        "        self.action_space = spaces.Discrete(3)\n",
        "        self.observation_space = spaces.Box(low=0, high=1999, shape=(1,) , dtype=np.float64)\n",
        "\n",
        "        # episode\n",
        "        self._start_tick = 0\n",
        "        self._end_tick = 0\n",
        "        self._done = None\n",
        "        self._current_tick = None\n",
        "        self._last_trade_tick = None\n",
        "        self._position = None\n",
        "        self._position_history = None\n",
        "        self._total_reward = None\n",
        "        self._total_profit = None\n",
        "        self._first_rendering = None\n",
        "        self.history = None\n",
        "        self._max_steps = max_steps\n",
        "        self._start_episode_tick = None\n",
        "        self._trade_history = None\n",
        "        self._random_start = random_start\n",
        "\n",
        "    def reset(self):\n",
        "        self._done = False\n",
        "        if self._random_start:\n",
        "            self._start_episode_tick = np.random.randint(1,high=len(self.df)- self._max_steps )\n",
        "            self._end_tick = self._start_episode_tick + self._max_steps\n",
        "        else:\n",
        "            self._start_episode_tick = 1\n",
        "            self._end_tick = len(self.df)-1\n",
        "        # self._start_episode_tick = np.random.randint(1,len(self.df)- self._max_steps )\n",
        "        # self._end_tick = self._start_episode_tick + self._max_steps\n",
        "        self._current_tick = self._start_episode_tick\n",
        "        self._last_trade_tick = self._current_tick - 1\n",
        "        self._position = 0\n",
        "        self._position_history = []\n",
        "        # self._position_history = (self.window_size * [None]) + [self._position]\n",
        "        self._total_reward = 0.\n",
        "        self._total_profit = 0.\n",
        "        self._trade_history = []\n",
        "        self.history = {}\n",
        "        return self._get_observation()\n",
        "\n",
        "\n",
        "    def step(self, action):\n",
        "        self._done = False\n",
        "        self._current_tick += 1\n",
        "\n",
        "        if self._current_tick == self._end_tick:\n",
        "            self._done = True\n",
        "\n",
        "        step_reward = self._calculate_reward(action)\n",
        "        self._total_reward += step_reward\n",
        "\n",
        "        observation = self._get_observation()\n",
        "        info = dict(\n",
        "            total_reward = self._total_reward,\n",
        "            total_profit = self._total_profit,\n",
        "            position = self._position,\n",
        "            action = action\n",
        "        )\n",
        "        self._update_history(info)\n",
        "\n",
        "        return observation, step_reward, self._done, info\n",
        "\n",
        "    def seed(self, seed=None):\n",
        "        self.np_random, seed = seeding.np_random(seed)\n",
        "        return [seed]\n",
        "        \n",
        "    def _get_observation(self):\n",
        "        return self.signal_features[self._current_tick]\n",
        "\n",
        "    def _update_history(self, info):\n",
        "        if not self.history:\n",
        "            self.history = {key: [] for key in info.keys()}\n",
        "\n",
        "        for key, value in info.items():\n",
        "            self.history[key].append(value)\n",
        "\n",
        "\n",
        "    def render(self, mode='human'):\n",
        "        window_ticks = np.arange(len(self._position_history))\n",
        "        prices = self.prices[self._start_episode_tick:self._end_tick+1]\n",
        "        plt.plot(prices)\n",
        "\n",
        "        open_buy = []\n",
        "        close_buy = []\n",
        "        open_sell = []\n",
        "        close_sell = []\n",
        "        do_nothing = []\n",
        "\n",
        "        for i, tick in enumerate(window_ticks):\n",
        "            if self._position_history[i] == 1:\n",
        "                open_buy.append(tick)\n",
        "            elif self._position_history[i] == 2 :\n",
        "                close_buy.append(tick)\n",
        "            elif self._position_history[i] == 3 :\n",
        "                open_sell.append(tick)\n",
        "            elif self._position_history[i] == 4 :\n",
        "                close_sell.append(tick)\n",
        "            elif self._position_history[i] == 0 :\n",
        "                do_nothing.append(tick)\n",
        "\n",
        "        plt.plot(open_buy, prices[open_buy], 'go', marker=\"^\")\n",
        "        plt.plot(close_buy, prices[close_buy], 'go', marker=\"v\")\n",
        "        plt.plot(open_sell, prices[open_sell], 'ro', marker=\"v\")\n",
        "        plt.plot(close_sell, prices[close_sell], 'ro', marker=\"^\")\n",
        "    \n",
        "        plt.plot(do_nothing, prices[do_nothing], 'yo')\n",
        "\n",
        "        plt.suptitle(\n",
        "            \"Total Reward: %.6f\" % self._total_reward + ' ~ ' +\n",
        "            \"Total Profit: %.6f\" % self._total_profit\n",
        "        )\n",
        "\n",
        "    def _calculate_reward(self, action):\n",
        "        step_reward = 0\n",
        "\n",
        "        current_price = self.prices[self._current_tick]\n",
        "        last_price = self.prices[self._current_tick - 1]\n",
        "        price_diff = current_price - last_price\n",
        "\n",
        "        penalty = -1 * last_price * 0.01\n",
        "        # OPEN BUY - 1\n",
        "        if action == Actions.Buy.value and self._position == 0:\n",
        "            self._position = 1\n",
        "            step_reward += price_diff\n",
        "            self._last_trade_tick = self._current_tick - 1\n",
        "            self._position_history.append(1)\n",
        "\n",
        "        elif action == Actions.Buy.value and self._position > 0:\n",
        "            step_reward += penalty\n",
        "            self._position_history.append(-1)\n",
        "        # CLOSE SELL - 4\n",
        "        elif action == Actions.Buy.value and self._position < 0:\n",
        "            self._position = 0\n",
        "            step_reward += -1 * (self.prices[self._current_tick -1] - self.prices[self._last_trade_tick]) \n",
        "            self._total_profit += step_reward\n",
        "            self._position_history.append(4)\n",
        "            self._trade_history.append(step_reward)\n",
        "\n",
        "        # OPEN SELL - 3\n",
        "        elif action == Actions.Sell.value and self._position == 0:\n",
        "            self._position = -1\n",
        "            step_reward += -1 * price_diff\n",
        "            self._last_trade_tick = self._current_tick - 1\n",
        "            self._position_history.append(3)\n",
        "        # CLOSE BUY - 2\n",
        "        elif action == Actions.Sell.value and self._position > 0:\n",
        "            self._position = 0\n",
        "            step_reward += self.prices[self._current_tick -1] - self.prices[self._last_trade_tick] \n",
        "            self._total_profit += step_reward\n",
        "            self._position_history.append(2)\n",
        "            self._trade_history.append(step_reward)\n",
        "        elif action == Actions.Sell.value and self._position < 0:\n",
        "            step_reward += penalty\n",
        "            self._position_history.append(-1)\n",
        "\n",
        "        # DO NOTHING - 0\n",
        "        elif action == Actions.Do_nothing.value and self._position > 0:\n",
        "            step_reward += price_diff\n",
        "            self._position_history.append(0)\n",
        "        elif action == Actions.Do_nothing.value and self._position < 0:\n",
        "            step_reward += -1 * price_diff\n",
        "            self._position_history.append(0)\n",
        "        elif action == Actions.Do_nothing.value and self._position == 0:\n",
        "            step_reward += -1 * abs(price_diff)\n",
        "            self._position_history.append(0)\n",
        "\n",
        "        return step_reward\n",
        "\n",
        "    def _do_bin(self,df):\n",
        "        df = pd.cut(df,bins=[0,10,20,30,40,50,60,70,80,90,100],labels=False, include_lowest=True)\n",
        "        return df\n",
        "    # Our state will be encode with 4 features MFI and Stochastic(only D line), ADX and DI+DI-\n",
        "    # the values of each feature will be binned in 10 bins, ex:\n",
        "    # MFI goes from 0-100, if we get 25 will put on the second bin \n",
        "    # DI+DI-  if DI+ is over DI- set (1 otherwise 0) \n",
        "    # \n",
        "    # that will give a state space of 10(MFI) * 10(STOCH) * 10(ADX) * 2(DI) = 2000 states\n",
        "    # encoded as bins of  DI MFI STOCH ADX = 1 45.2  25.4  90.1 , binned = 1 4 2 9 state = 1429   \n",
        "    def _process_data(self):\n",
        "        timeperiod = 14\n",
        "        self.df = self.df.copy()\n",
        "        \n",
        "        self.df['mfi_r'] = ta.MFI(self.df['High'], self.df['Low'], self.df['Close'],self.df['Volume'], timeperiod=timeperiod)\n",
        "        _, self.df['stock_d_r'] = ta.STOCH(self.df['High'], self.df['Low'], self.df['Close'], fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3, slowd_matype=0)\n",
        "        self.df['adx_r'] = ta.ADX(self.df['High'], self.df['Low'], self.df['Close'], timeperiod=timeperiod)\n",
        "        self.df['p_di'] = ta.PLUS_DI(self.df['High'], self.df['Low'], self.df['Close'], timeperiod=timeperiod)\n",
        "        self.df['m_di'] = ta.MINUS_DI(self.df['High'], self.df['Low'], self.df['Close'], timeperiod=timeperiod)\n",
        "        self.df['di'] = np.where( self.df['p_di'] > self.df['m_di'], 1, 0)\n",
        "\n",
        "        self.df = self.df.dropna()\n",
        "        self.df['mfi'] = self._do_bin(self.df['mfi_r'])\n",
        "        self.df['stock_d'] = self._do_bin(self.df['stock_d_r'])\n",
        "        self.df['adx'] = self._do_bin(self.df['adx_r'])\n",
        "        self.df['state'] = self.df['di']*1000+ self.df['mfi']*100 + self.df['stock_d']*10 + self.df['adx']\n",
        "\n",
        "        prices = self.df.loc[:, 'Close'].to_numpy()\n",
        "        # print(self.df.head(30))\n",
        "\n",
        "        signal_features = self.df.loc[:, 'state'].to_numpy()\n",
        "\n",
        "        return prices, signal_features"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Training parameters\n",
        "n_training_episodes = 20000  # Total training episodes\n",
        "learning_rate = 0.2          # Learning rate\n",
        "\n",
        "# Environment parameters\n",
        "max_steps = 20   # Max steps per episode\n",
        "gamma = 0.95                 # Discounting rate\n",
        "\n",
        "# Exploration parameters\n",
        "max_epsilon = 1.0             # Exploration probability at start\n",
        "# max_epsilon = 1.0             # Exploration probability at start\n",
        "min_epsilon = 0.05            # Minimum exploration probability \n",
        "# min_epsilon = 0.05            # Minimum exploration probability \n",
        "decay_rate = 0.0005            # Exponential decay rate for exploration prob"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "REhmfLkYNTiN",
        "outputId": "cf676f6d-83df-43f5-89fe-3258e0041d9d"
      },
      "outputs": [],
      "source": [
        "# create env\n",
        "env = CustTradingEnv(df=eth_train, max_steps=max_steps)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {},
      "outputs": [],
      "source": [
        "# create q-table\n",
        "\n",
        "action_space = env.action_space.n # buy sell do_nothing\n",
        "state_space = 2000\n",
        "\n",
        "Qtable_trading = initialize_q_table(state_space, action_space)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "981"
            ]
          },
          "execution_count": 11,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# train with ETH\n",
        "Qtable_trading, state_history = train(n_training_episodes, min_epsilon, max_epsilon, \n",
        "                        decay_rate, env, max_steps, Qtable_trading, learning_rate, gamma )\n",
        "len(np.where( Qtable_trading > 0 )[0])\n",
        "\n",
        "# #train with BTC\n",
        "# env = CustTradingEnv(df=btc_train, max_steps=max_steps)\n",
        "# Qtable_trading, state_history = train(n_training_episodes, min_epsilon, max_epsilon, \n",
        "#                         decay_rate, env, max_steps, Qtable_trading, learning_rate, gamma )\n",
        "# len(np.where( Qtable_trading > 0 )[0])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 417
        },
        "id": "FIQ0OqtsO3jo",
        "outputId": "f98374ad-c7de-4dc4-80b1-25f018ad96eb"
      },
      "outputs": [
        {
          "data": {
            "image/png": "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",
            "text/plain": [
              "<Figure size 1080x432 with 1 Axes>"
            ]
          },
          "metadata": {
            "needs_background": "light"
          },
          "output_type": "display_data"
        }
      ],
      "source": [
        "plt.figure(figsize=(15,6))\n",
        "plt.cla()\n",
        "env.render()\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "[-168.9210205078125, 187.22998046875, 218.34100341796875]"
            ]
          },
          "execution_count": 12,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "env._trade_history"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "351"
            ]
          },
          "execution_count": 14,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "len(np.unique(state_history, return_counts=True)[1])\n",
        "# count = 0\n",
        "# for i in range(len(state_history)):\n",
        "#     if state_history[i] == 1987:\n",
        "#         count +=1\n",
        "# count"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {},
      "outputs": [],
      "source": [
        "def evaluate_agent(env, max_steps, n_eval_episodes, Q, random=False):\n",
        "  \"\"\"\n",
        "  Evaluate the agent for ``n_eval_episodes`` episodes and returns average reward and std of reward.\n",
        "  :param env: The evaluation environment\n",
        "  :param n_eval_episodes: Number of episode to evaluate the agent\n",
        "  :param Q: The Q-table\n",
        "  :param seed: The evaluation seed array (for taxi-v3)\n",
        "  \"\"\"\n",
        "  episode_rewards = []\n",
        "  episode_profits = []\n",
        "  for episode in tqdm(range(n_eval_episodes), disable=random):\n",
        "    state = env.reset()\n",
        "    step = 0\n",
        "    done = False\n",
        "    total_rewards_ep = 0\n",
        "    total_profit_ep = 0\n",
        "    \n",
        "    for step in range(max_steps):\n",
        "      # Take the action (index) that have the maximum expected future reward given that state\n",
        "      if random:\n",
        "        action = env.action_space.sample()\n",
        "      else:\n",
        "        action = greedy_policy(Q, state)\n",
        "\n",
        "      new_state, reward, done, info = env.step(action)\n",
        "      total_rewards_ep += reward\n",
        "        \n",
        "      if done:\n",
        "        break\n",
        "      state = new_state\n",
        "\n",
        "    episode_rewards.append(total_rewards_ep)\n",
        "    episode_profits.append(env.history['total_profit'][-1])\n",
        "    # print(env.history)\n",
        "    # env.render()\n",
        "    # assert 0\n",
        "\n",
        "  mean_reward = np.mean(episode_rewards)\n",
        "  std_reward = np.std(episode_rewards)\n",
        "  mean_profit = np.mean(episode_profits)\n",
        "  std_profit = np.std(episode_profits)\n",
        "\n",
        "  return mean_reward, std_reward, mean_profit, std_profit"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "metadata": {},
      "outputs": [
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "629507e6932b49d381644ae851b9f08e",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "  0%|          | 0/1000 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/plain": [
              "(-25.214183127441423,\n",
              " 305.1328994776763,\n",
              " 113.14856896972657,\n",
              " 195.77032459962064)"
            ]
          },
          "execution_count": 23,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "max_steps = 20 \n",
        "env_test = CustTradingEnv(df=eth_test, max_steps=max_steps, random_start=True)\n",
        "n_eval_episodes = 1000\n",
        "\n",
        "evaluate_agent(env_test, max_steps, n_eval_episodes, Qtable_trading)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "metadata": {},
      "outputs": [
        {
          "data": {
            "image/png": "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",
            "text/plain": [
              "<Figure size 1080x432 with 1 Axes>"
            ]
          },
          "metadata": {
            "needs_background": "light"
          },
          "output_type": "display_data"
        }
      ],
      "source": [
        "plt.figure(figsize=(15,6))\n",
        "plt.cla()\n",
        "env_test.render()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "metadata": {},
      "outputs": [
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "65be242101434cab9057cda9dd230391",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "  0%|          | 0/1 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/plain": [
              "(-654.2524291992195, 0.0, 563.6707763671875, 0.0)"
            ]
          },
          "execution_count": 22,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# trade sequential\n",
        "max_steps = len(eth_test)\n",
        "env_test = CustTradingEnv(df=eth_test, max_steps=max_steps, random_start=False)\n",
        "n_eval_episodes = 1\n",
        "\n",
        "evaluate_agent(env_test, max_steps, n_eval_episodes, Qtable_trading)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "(-196.17019008178713, 392.3658082003918, -18.1048154296875, 210.9968436183694)"
            ]
          },
          "execution_count": 17,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Test for random n_eval_episodes\n",
        "max_steps = 20 \n",
        "env_test_rand = CustTradingEnv(df=eth_test, max_steps=max_steps, random_start=True)\n",
        "n_eval_episodes = 1000\n",
        "\n",
        "evaluate_agent(env_test_rand, max_steps, n_eval_episodes, Qtable_trading, random=True)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Mean profit 39.304194213867184\n"
          ]
        }
      ],
      "source": [
        "# trade sequentially with random actions \n",
        "max_steps = len(eth_test)\n",
        "env_test = CustTradingEnv(df=eth_test, max_steps=max_steps, random_start=False)\n",
        "n_eval_episodes = 1\n",
        "\n",
        "all_profit=[]\n",
        "for i in range(1000):\n",
        "    _,_,profit,_=evaluate_agent(env_test, max_steps, n_eval_episodes, Qtable_trading, random=True)\n",
        "    all_profit.append(profit)\n",
        "print(f\"Mean profit {np.mean(all_profit)}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## This is the result\n",
        "\n",
        "| Model      | 1000 trades 20 steps | Sequential trading | 1000 trades 20 steps random actions | Sequential random|\n",
        "|------------|----------------------|--------------------|-------------------------------------|------------------|\n",
        "|Q-learning  | 113.14               | 563.67             | -18.10                              | 39.30            |\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "def count_equal(env, Qtable):\n",
        "    count=0\n",
        "    for i in env.signal_features:\n",
        "        if abs(np.max(Qtable[i])) > 0:\n",
        "            count+=1\n",
        "        # else:\n",
        "        #     print(i)\n",
        "        #     assert 0\n",
        "    \n",
        "    print(len(env.signal_features), count, count / len(env.signal_features))\n",
        "\n",
        "count_equal(env_test, Qtable_trading)"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3.8.13 ('rl2')",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.8.13"
    },
    "orig_nbformat": 4,
    "vscode": {
      "interpreter": {
        "hash": "cd60ab8388a66026f336166410d6a8a46ddf65ece2e85ad2d46c8b98d87580d1"
      }
    },
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "01a2dbcb714e40148b41c761fcf43147": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "20b0f38ec3234ff28a62a286cd57b933": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "PasswordModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "PasswordModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "PasswordView",
            "continuous_update": true,
            "description": "Token:",
            "description_tooltip": null,
            "disabled": false,
            "layout": "IPY_MODEL_01a2dbcb714e40148b41c761fcf43147",
            "placeholder": "​",
            "style": "IPY_MODEL_90c874e91b304ee1a7ef147767ac00ce",
            "value": ""
          }
        },
        "270cbb5d6e9c4b1e9e2f39c8b3b0c15f": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "VBoxModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "VBoxModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "VBoxView",
            "box_style": "",
            "children": [
              "IPY_MODEL_a02224a43d8d4af3bd31d326540d25da",
              "IPY_MODEL_20b0f38ec3234ff28a62a286cd57b933",
              "IPY_MODEL_f6c845330d6743c0b35c2c7ad834de77",
              "IPY_MODEL_f1675c09d16a4251b403f9c56255f168",
              "IPY_MODEL_c1a82965ae26479a98e4fdbde1e64ec2"
            ],
            "layout": "IPY_MODEL_3fa248114ac24656ba74923936a94d2d"
          }
        },
        "2dc5fa9aa3334dfcbdee9c238f2ef60b": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "3e753b0212644990b558c68853ff2041": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "3fa248114ac24656ba74923936a94d2d": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": "center",
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": "flex",
            "flex": null,
            "flex_flow": "column",
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": "50%"
          }
        },
        "42d140b838b844819bc127afc1b7bc84": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "90c874e91b304ee1a7ef147767ac00ce": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "9d847f9a7d47458d8cd57d9b599e47c6": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "a02224a43d8d4af3bd31d326540d25da": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "HTMLModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_caef095934ec47bbb8b64eab22049284",
            "placeholder": "​",
            "style": "IPY_MODEL_2dc5fa9aa3334dfcbdee9c238f2ef60b",
            "value": "<center> <img\nsrc=https://huggingface.co/front/assets/huggingface_logo-noborder.svg\nalt='Hugging Face'> <br> Copy a token from <a\nhref=\"https://huggingface.co/settings/tokens\" target=\"_blank\">your Hugging Face\ntokens page</a> and paste it below. <br> Immediately click login after copying\nyour token or it might be stored in plain text in this notebook file. </center>"
          }
        },
        "a2cfb91cf66447d7899292854bd64a07": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "c1a82965ae26479a98e4fdbde1e64ec2": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "HTMLModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_9d847f9a7d47458d8cd57d9b599e47c6",
            "placeholder": "​",
            "style": "IPY_MODEL_42d140b838b844819bc127afc1b7bc84",
            "value": "\n<b>Pro Tip:</b> If you don't already have one, you can create a dedicated\n'notebooks' token with 'write' access, that you can then easily reuse for all\nnotebooks. </center>"
          }
        },
        "caef095934ec47bbb8b64eab22049284": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "eaba3f1de4444aabadfea2a3dadb1d80": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "ee4a21bedc504171ad09d205d634b528": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "ButtonStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "ButtonStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "button_color": null,
            "font_weight": ""
          }
        },
        "f1675c09d16a4251b403f9c56255f168": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "ButtonModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "ButtonModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "ButtonView",
            "button_style": "",
            "description": "Login",
            "disabled": false,
            "icon": "",
            "layout": "IPY_MODEL_a2cfb91cf66447d7899292854bd64a07",
            "style": "IPY_MODEL_ee4a21bedc504171ad09d205d634b528",
            "tooltip": ""
          }
        },
        "f6c845330d6743c0b35c2c7ad834de77": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "CheckboxModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "CheckboxModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "CheckboxView",
            "description": "Add token as git credential?",
            "description_tooltip": null,
            "disabled": false,
            "indent": true,
            "layout": "IPY_MODEL_3e753b0212644990b558c68853ff2041",
            "style": "IPY_MODEL_eaba3f1de4444aabadfea2a3dadb1d80",
            "value": true
          }
        }
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}