cryptodatapy 0.2.15__py3-none-any.whl → 0.2.17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cryptodatapy/conf/fields.csv +1 -1
- cryptodatapy/extract/data_vendors/coinmetrics_api.py +32 -32
- cryptodatapy/extract/data_vendors/cryptocompare_api.py +159 -204
- cryptodatapy/extract/data_vendors/datavendor.py +21 -0
- cryptodatapy/extract/data_vendors/tiingo_api.py +5 -1
- cryptodatapy/extract/libraries/ccxt_api.py +215 -209
- cryptodatapy/transform/convertparams.py +35 -57
- cryptodatapy/util/datacredentials.py +18 -3
- {cryptodatapy-0.2.15.dist-info → cryptodatapy-0.2.17.dist-info}/METADATA +1 -1
- {cryptodatapy-0.2.15.dist-info → cryptodatapy-0.2.17.dist-info}/RECORD +12 -12
- {cryptodatapy-0.2.15.dist-info → cryptodatapy-0.2.17.dist-info}/LICENSE +0 -0
- {cryptodatapy-0.2.15.dist-info → cryptodatapy-0.2.17.dist-info}/WHEEL +0 -0
@@ -79,6 +79,7 @@ class CCXT(Library):
|
|
79
79
|
self.exchange = None
|
80
80
|
self.exchange_async = None
|
81
81
|
self.data_req = None
|
82
|
+
self.data_resp = []
|
82
83
|
self.data = pd.DataFrame()
|
83
84
|
|
84
85
|
def get_exchanges_info(self) -> List[str]:
|
@@ -327,12 +328,12 @@ class CCXT(Library):
|
|
327
328
|
async def _fetch_ohlcv_async(self,
|
328
329
|
ticker: str,
|
329
330
|
freq: str,
|
330
|
-
start_date:
|
331
|
-
end_date:
|
331
|
+
start_date: int,
|
332
|
+
end_date: int,
|
332
333
|
exch: str,
|
333
334
|
trials: int = 3,
|
334
335
|
pause: int = 1
|
335
|
-
) -> List:
|
336
|
+
) -> Union[List, None]:
|
336
337
|
"""
|
337
338
|
Fetches OHLCV data for a specific ticker.
|
338
339
|
|
@@ -355,11 +356,11 @@ class CCXT(Library):
|
|
355
356
|
|
356
357
|
Returns
|
357
358
|
-------
|
358
|
-
|
359
|
+
data_resp: list
|
359
360
|
List of timestamps with OHLCV data.
|
360
361
|
"""
|
361
362
|
attempts = 0
|
362
|
-
|
363
|
+
data_resp = []
|
363
364
|
|
364
365
|
# inst exch
|
365
366
|
if self.exchange_async is None:
|
@@ -372,7 +373,7 @@ class CCXT(Library):
|
|
372
373
|
while start_date < end_date and attempts < trials:
|
373
374
|
|
374
375
|
try:
|
375
|
-
|
376
|
+
data = await self.exchange_async.fetch_ohlcv(
|
376
377
|
ticker,
|
377
378
|
freq,
|
378
379
|
since=start_date,
|
@@ -381,12 +382,10 @@ class CCXT(Library):
|
|
381
382
|
)
|
382
383
|
|
383
384
|
# add data to list
|
384
|
-
if
|
385
|
-
start_date =
|
386
|
-
|
385
|
+
if data:
|
386
|
+
start_date = data[-1][0] + 1
|
387
|
+
data_resp.extend(data)
|
387
388
|
else:
|
388
|
-
if not data:
|
389
|
-
logging.warning(f"No OHLCV data available for {ticker}.")
|
390
389
|
break
|
391
390
|
|
392
391
|
except Exception as e:
|
@@ -408,7 +407,7 @@ class CCXT(Library):
|
|
408
407
|
attempts)
|
409
408
|
|
410
409
|
await self.exchange_async.close()
|
411
|
-
return
|
410
|
+
return data_resp
|
412
411
|
|
413
412
|
else:
|
414
413
|
logging.warning(f"OHLCV data is not available for {self.exchange_async.id}.")
|
@@ -422,7 +421,7 @@ class CCXT(Library):
|
|
422
421
|
exch: str,
|
423
422
|
trials: int = 3,
|
424
423
|
pause: int = 1
|
425
|
-
) -> List:
|
424
|
+
) -> Union[List, None]:
|
426
425
|
"""
|
427
426
|
Fetches OHLCV data for a specific ticker.
|
428
427
|
|
@@ -445,11 +444,11 @@ class CCXT(Library):
|
|
445
444
|
|
446
445
|
Returns
|
447
446
|
-------
|
448
|
-
|
447
|
+
data_resp: list
|
449
448
|
List of timestamps with OHLCV data.
|
450
449
|
"""
|
451
450
|
attempts = 0
|
452
|
-
|
451
|
+
data_resp = []
|
453
452
|
|
454
453
|
# inst exch
|
455
454
|
if self.exchange is None:
|
@@ -462,7 +461,7 @@ class CCXT(Library):
|
|
462
461
|
while start_date < end_date and attempts < trials:
|
463
462
|
|
464
463
|
try:
|
465
|
-
|
464
|
+
data = self.exchange.fetch_ohlcv(
|
466
465
|
ticker,
|
467
466
|
freq,
|
468
467
|
since=start_date,
|
@@ -474,12 +473,10 @@ class CCXT(Library):
|
|
474
473
|
)
|
475
474
|
|
476
475
|
# add data to list
|
477
|
-
if
|
478
|
-
start_date =
|
479
|
-
|
476
|
+
if data:
|
477
|
+
start_date = data[-1][0] + 1
|
478
|
+
data_resp.extend(data)
|
480
479
|
else:
|
481
|
-
if not data:
|
482
|
-
logging.warning(f"No OHLCV data available for {ticker}.")
|
483
480
|
break
|
484
481
|
|
485
482
|
except Exception as e:
|
@@ -498,7 +495,7 @@ class CCXT(Library):
|
|
498
495
|
finally:
|
499
496
|
self.exponential_backoff_with_jitter(self.exchange.rateLimit / 1000, pause, attempts)
|
500
497
|
|
501
|
-
return
|
498
|
+
return data_resp
|
502
499
|
|
503
500
|
else:
|
504
501
|
logging.warning(f"OHLCV data is not available for {self.exchange.id}.")
|
@@ -507,12 +504,12 @@ class CCXT(Library):
|
|
507
504
|
async def _fetch_all_ohlcv_async(self,
|
508
505
|
tickers,
|
509
506
|
freq: str,
|
510
|
-
start_date:
|
511
|
-
end_date:
|
507
|
+
start_date: int,
|
508
|
+
end_date: int,
|
512
509
|
exch: str,
|
513
510
|
trials: int = 3,
|
514
511
|
pause: int = 1
|
515
|
-
):
|
512
|
+
) -> Union[List, None]:
|
516
513
|
"""
|
517
514
|
Fetches OHLCV data for a list of tickers.
|
518
515
|
|
@@ -522,9 +519,9 @@ class CCXT(Library):
|
|
522
519
|
List of ticker symbols.
|
523
520
|
freq: str
|
524
521
|
Frequency of data, e.g. '1m', '5m', '1h', '1d'.
|
525
|
-
start_date:
|
522
|
+
start_date: int
|
526
523
|
Start date in integers in milliseconds since Unix epoch.
|
527
|
-
end_date:
|
524
|
+
end_date: int
|
528
525
|
End date in integers in milliseconds since Unix epoch.
|
529
526
|
exch: str
|
530
527
|
Name of exchange.
|
@@ -535,38 +532,36 @@ class CCXT(Library):
|
|
535
532
|
|
536
533
|
Returns
|
537
534
|
-------
|
538
|
-
|
535
|
+
data_resp: list
|
539
536
|
List of lists of timestamps and OHLCV data for each ticker.
|
540
537
|
"""
|
541
538
|
# inst exch
|
542
539
|
if self.exchange_async is None:
|
543
540
|
self.exchange_async = getattr(ccxt_async, exch)()
|
544
541
|
|
545
|
-
data = []
|
546
|
-
|
547
542
|
# create progress bar
|
548
543
|
pbar = tqdm(total=len(tickers), desc="Fetching OHLCV data", unit="ticker")
|
549
544
|
|
550
545
|
# loop through tickers
|
551
546
|
for ticker in tickers:
|
552
|
-
|
547
|
+
data = await self._fetch_ohlcv_async(ticker, freq, start_date, end_date, trials=trials, exch=exch)
|
553
548
|
await asyncio.sleep(pause)
|
554
|
-
|
549
|
+
self.data_resp.append(data)
|
555
550
|
pbar.update(1)
|
556
551
|
|
557
552
|
await self.exchange_async.close()
|
558
553
|
|
559
|
-
return
|
554
|
+
return self.data_resp
|
560
555
|
|
561
556
|
def _fetch_all_ohlcv(self,
|
562
557
|
tickers,
|
563
558
|
freq: str,
|
564
|
-
start_date:
|
565
|
-
end_date:
|
559
|
+
start_date: int,
|
560
|
+
end_date: int,
|
566
561
|
exch: str,
|
567
562
|
trials: int = 3,
|
568
563
|
pause: int = 1
|
569
|
-
):
|
564
|
+
) -> Union[List, None]:
|
570
565
|
"""
|
571
566
|
Fetches OHLCV data for a list of tickers.
|
572
567
|
|
@@ -576,9 +571,9 @@ class CCXT(Library):
|
|
576
571
|
List of ticker symbols.
|
577
572
|
freq: str
|
578
573
|
Frequency of data, e.g. '1m', '5m', '1h', '1d'.
|
579
|
-
start_date:
|
574
|
+
start_date: int
|
580
575
|
Start date in integers in milliseconds since Unix epoch.
|
581
|
-
end_date:
|
576
|
+
end_date: int
|
582
577
|
End date in integers in milliseconds since Unix epoch.
|
583
578
|
exch: str
|
584
579
|
Name of exchange.
|
@@ -586,33 +581,36 @@ class CCXT(Library):
|
|
586
581
|
Number of attempts to fetch data.
|
587
582
|
pause: int, default 0.5
|
588
583
|
Pause in seconds to respect the rate limit.
|
584
|
+
|
585
|
+
Returns
|
586
|
+
-------
|
587
|
+
data_resp: list
|
588
|
+
List of lists of timestamps and OHLCV data for each ticker.
|
589
589
|
"""
|
590
590
|
# inst exch
|
591
591
|
if self.exchange is None:
|
592
592
|
self.exchange = getattr(ccxt, exch)()
|
593
593
|
|
594
|
-
data = []
|
595
|
-
|
596
594
|
# create progress bar
|
597
595
|
pbar = tqdm(total=len(tickers), desc="Fetching OHLCV data", unit="ticker")
|
598
596
|
|
599
597
|
# loop through tickers
|
600
598
|
for ticker in tickers:
|
601
|
-
|
599
|
+
data = self._fetch_ohlcv(ticker, freq, start_date, end_date, trials=trials, exch=exch)
|
602
600
|
sleep(pause)
|
603
|
-
|
601
|
+
self.data_resp.append(data)
|
604
602
|
pbar.update(1)
|
605
603
|
|
606
|
-
return
|
604
|
+
return self.data_resp
|
607
605
|
|
608
606
|
async def _fetch_funding_rates_async(self,
|
609
607
|
ticker: str,
|
610
|
-
start_date:
|
611
|
-
end_date:
|
608
|
+
start_date: int,
|
609
|
+
end_date: int,
|
612
610
|
exch: str,
|
613
611
|
trials: int = 3,
|
614
612
|
pause: int = 1
|
615
|
-
) -> List:
|
613
|
+
) -> Union[List, None]:
|
616
614
|
"""
|
617
615
|
Fetches funding rates data for a specific ticker.
|
618
616
|
|
@@ -620,9 +618,9 @@ class CCXT(Library):
|
|
620
618
|
----------
|
621
619
|
ticker: str
|
622
620
|
Ticker symbol.
|
623
|
-
start_date:
|
621
|
+
start_date: int
|
624
622
|
Start date in integers in milliseconds since Unix epoch.
|
625
|
-
end_date:
|
623
|
+
end_date: int
|
626
624
|
End date in integers in milliseconds since Unix epoch.
|
627
625
|
trials: int, default 3
|
628
626
|
Number of attempts to fetch data.
|
@@ -631,11 +629,11 @@ class CCXT(Library):
|
|
631
629
|
|
632
630
|
Returns
|
633
631
|
-------
|
634
|
-
|
632
|
+
data_resp: list
|
635
633
|
List of dictionaries with timestamps and funding rates data.
|
636
634
|
"""
|
637
635
|
attempts = 0
|
638
|
-
|
636
|
+
data_resp = []
|
639
637
|
|
640
638
|
# inst exch
|
641
639
|
if self.exchange_async is None:
|
@@ -648,7 +646,7 @@ class CCXT(Library):
|
|
648
646
|
while start_date < end_date and attempts < trials:
|
649
647
|
|
650
648
|
try:
|
651
|
-
|
649
|
+
data = await self.exchange_async.fetch_funding_rate_history(
|
652
650
|
ticker,
|
653
651
|
since=start_date,
|
654
652
|
limit=self.max_obs_per_call,
|
@@ -656,12 +654,10 @@ class CCXT(Library):
|
|
656
654
|
)
|
657
655
|
|
658
656
|
# add data to list
|
659
|
-
if
|
660
|
-
start_date =
|
661
|
-
|
657
|
+
if data:
|
658
|
+
start_date = data[-1]['timestamp'] + 1
|
659
|
+
data_resp.extend(data)
|
662
660
|
else:
|
663
|
-
if not data:
|
664
|
-
logging.warning(f"No funding rates data available for {ticker}.")
|
665
661
|
break
|
666
662
|
|
667
663
|
except Exception as e:
|
@@ -683,7 +679,7 @@ class CCXT(Library):
|
|
683
679
|
attempts)
|
684
680
|
|
685
681
|
await self.exchange_async.close()
|
686
|
-
return
|
682
|
+
return data_resp
|
687
683
|
|
688
684
|
else:
|
689
685
|
logging.warning(f"Funding rates are not available for {self.exchange_async.id}.")
|
@@ -691,12 +687,12 @@ class CCXT(Library):
|
|
691
687
|
|
692
688
|
def _fetch_funding_rates(self,
|
693
689
|
ticker: str,
|
694
|
-
start_date:
|
695
|
-
end_date:
|
690
|
+
start_date: int,
|
691
|
+
end_date: int,
|
696
692
|
exch: str,
|
697
693
|
trials: int = 3,
|
698
694
|
pause: int = 1
|
699
|
-
) -> List:
|
695
|
+
) -> Union[List, None]:
|
700
696
|
"""
|
701
697
|
Fetches funding rates data for a specific ticker.
|
702
698
|
|
@@ -704,9 +700,9 @@ class CCXT(Library):
|
|
704
700
|
----------
|
705
701
|
ticker: str
|
706
702
|
Ticker symbol.
|
707
|
-
start_date:
|
703
|
+
start_date: int
|
708
704
|
Start date in integers in milliseconds since Unix epoch.
|
709
|
-
end_date:
|
705
|
+
end_date: int
|
710
706
|
End date in integers in milliseconds since Unix epoch.
|
711
707
|
trials: int, default 3
|
712
708
|
Number of attempts to fetch data.
|
@@ -715,11 +711,11 @@ class CCXT(Library):
|
|
715
711
|
|
716
712
|
Returns
|
717
713
|
-------
|
718
|
-
|
714
|
+
data_resp: list
|
719
715
|
List of dictionaries with timestamps and funding rates data.
|
720
716
|
"""
|
721
717
|
attempts = 0
|
722
|
-
|
718
|
+
data_resp = []
|
723
719
|
|
724
720
|
# inst exch
|
725
721
|
if self.exchange is None:
|
@@ -732,7 +728,7 @@ class CCXT(Library):
|
|
732
728
|
while start_date < end_date and attempts < trials:
|
733
729
|
|
734
730
|
try:
|
735
|
-
|
731
|
+
data = self.exchange.fetch_funding_rate_history(
|
736
732
|
ticker,
|
737
733
|
since=start_date,
|
738
734
|
limit=self.max_obs_per_call,
|
@@ -740,12 +736,10 @@ class CCXT(Library):
|
|
740
736
|
)
|
741
737
|
|
742
738
|
# add data to list
|
743
|
-
if
|
744
|
-
start_date =
|
745
|
-
|
739
|
+
if data:
|
740
|
+
start_date = data[-1]['timestamp'] + 1
|
741
|
+
data_resp.extend(data)
|
746
742
|
else:
|
747
|
-
if not data:
|
748
|
-
logging.warning(f"No funding rates data available for {ticker}.")
|
749
743
|
break
|
750
744
|
|
751
745
|
except Exception as e:
|
@@ -764,7 +758,7 @@ class CCXT(Library):
|
|
764
758
|
finally:
|
765
759
|
self.exponential_backoff_with_jitter(self.exchange.rateLimit / 1000, pause, attempts)
|
766
760
|
|
767
|
-
return
|
761
|
+
return data_resp
|
768
762
|
|
769
763
|
else:
|
770
764
|
logging.warning(f"Funding rates are not available for {self.exchange.id}.")
|
@@ -772,12 +766,12 @@ class CCXT(Library):
|
|
772
766
|
|
773
767
|
async def _fetch_all_funding_rates_async(self,
|
774
768
|
tickers,
|
775
|
-
start_date:
|
776
|
-
end_date:
|
769
|
+
start_date: int,
|
770
|
+
end_date: int,
|
777
771
|
exch: str,
|
778
772
|
trials: int = 3,
|
779
773
|
pause: int = 1
|
780
|
-
):
|
774
|
+
) -> Union[List, None]:
|
781
775
|
"""
|
782
776
|
Fetches funding rates data for a list of tickers.
|
783
777
|
|
@@ -785,9 +779,9 @@ class CCXT(Library):
|
|
785
779
|
----------
|
786
780
|
tickers: list
|
787
781
|
List of ticker symbols.
|
788
|
-
start_date:
|
782
|
+
start_date: int
|
789
783
|
Start date in integers in milliseconds since Unix epoch.
|
790
|
-
end_date:
|
784
|
+
end_date: int
|
791
785
|
End date in integers in milliseconds since Unix epoch.
|
792
786
|
exch: str
|
793
787
|
Name of exchange.
|
@@ -798,37 +792,35 @@ class CCXT(Library):
|
|
798
792
|
|
799
793
|
Returns
|
800
794
|
-------
|
801
|
-
|
795
|
+
data_resp: list
|
802
796
|
List of lists of dictionaries with timestamps and funding rates data for each ticker.
|
803
797
|
"""
|
804
798
|
# inst exch
|
805
799
|
if self.exchange_async is None:
|
806
800
|
self.exchange_async = getattr(ccxt_async, exch)()
|
807
801
|
|
808
|
-
data = []
|
809
|
-
|
810
802
|
# create progress bar
|
811
803
|
pbar = tqdm(total=len(tickers), desc="Fetching funding rates", unit="ticker")
|
812
804
|
|
813
805
|
# loop through tickers
|
814
806
|
for ticker in tickers:
|
815
|
-
|
816
|
-
|
807
|
+
data = await self._fetch_funding_rates_async(ticker, start_date, end_date, trials=trials, exch=exch)
|
808
|
+
self.data_resp.append(data)
|
817
809
|
pbar.update(1)
|
818
810
|
await asyncio.sleep(pause)
|
819
811
|
|
820
812
|
await self.exchange_async.close()
|
821
813
|
|
822
|
-
return
|
814
|
+
return self.data_resp
|
823
815
|
|
824
816
|
def _fetch_all_funding_rates(self,
|
825
817
|
tickers,
|
826
|
-
start_date:
|
827
|
-
end_date:
|
818
|
+
start_date: int,
|
819
|
+
end_date: int,
|
828
820
|
exch: str,
|
829
821
|
trials: int = 3,
|
830
822
|
pause: int = 1
|
831
|
-
):
|
823
|
+
) -> Union[List, None]:
|
832
824
|
"""
|
833
825
|
Fetches funding rates data for a list of tickers.
|
834
826
|
|
@@ -836,9 +828,9 @@ class CCXT(Library):
|
|
836
828
|
----------
|
837
829
|
tickers: list
|
838
830
|
List of ticker symbols.
|
839
|
-
start_date:
|
831
|
+
start_date: int
|
840
832
|
Start date in integers in milliseconds since Unix epoch.
|
841
|
-
end_date:
|
833
|
+
end_date: int
|
842
834
|
End date in integers in milliseconds since Unix epoch.
|
843
835
|
exch: str
|
844
836
|
Name of exchange.
|
@@ -849,7 +841,7 @@ class CCXT(Library):
|
|
849
841
|
|
850
842
|
Returns
|
851
843
|
-------
|
852
|
-
|
844
|
+
data_resp: list
|
853
845
|
List of lists of dictionaries with timestamps and funding rates data for each ticker.
|
854
846
|
"""
|
855
847
|
|
@@ -857,29 +849,27 @@ class CCXT(Library):
|
|
857
849
|
if self.exchange is None:
|
858
850
|
self.exchange = getattr(ccxt, exch)()
|
859
851
|
|
860
|
-
data = []
|
861
|
-
|
862
852
|
# create progress bar
|
863
853
|
pbar = tqdm(total=len(tickers), desc="Fetching funding rates", unit="ticker")
|
864
854
|
|
865
855
|
# loop through tickers
|
866
856
|
for ticker in tickers:
|
867
|
-
|
868
|
-
|
857
|
+
data = self._fetch_funding_rates(ticker, start_date, end_date, trials=trials, exch=exch)
|
858
|
+
self.data_resp.append(data)
|
869
859
|
pbar.update(1)
|
870
860
|
sleep(pause)
|
871
861
|
|
872
|
-
return
|
862
|
+
return self.data_resp
|
873
863
|
|
874
864
|
async def _fetch_open_interest_async(self,
|
875
865
|
ticker: str,
|
876
866
|
freq: str,
|
877
|
-
start_date:
|
878
|
-
end_date:
|
867
|
+
start_date: int,
|
868
|
+
end_date: int,
|
879
869
|
exch: str,
|
880
870
|
trials: int = 3,
|
881
871
|
pause: int = 1
|
882
|
-
) -> List:
|
872
|
+
) -> Union[List, None]:
|
883
873
|
"""
|
884
874
|
Fetches open interest data for a specific ticker.
|
885
875
|
|
@@ -889,9 +879,9 @@ class CCXT(Library):
|
|
889
879
|
Ticker symbol.
|
890
880
|
freq: str
|
891
881
|
Frequency of data, e.g. '1m', '5m', '1h', '1d'.
|
892
|
-
start_date:
|
882
|
+
start_date: int
|
893
883
|
Start date in integers in milliseconds since Unix epoch.
|
894
|
-
end_date:
|
884
|
+
end_date: int
|
895
885
|
End date in integers in milliseconds since Unix epoch.
|
896
886
|
exch: str
|
897
887
|
Name of exchange.
|
@@ -902,12 +892,12 @@ class CCXT(Library):
|
|
902
892
|
|
903
893
|
Returns
|
904
894
|
-------
|
905
|
-
|
895
|
+
data_resp: list
|
906
896
|
List of dictionaries with timestamps and open interest data.
|
907
897
|
"""
|
908
898
|
# number of attempts
|
909
899
|
attempts = 0
|
910
|
-
|
900
|
+
data_resp = []
|
911
901
|
|
912
902
|
# inst exch
|
913
903
|
if self.exchange_async is None:
|
@@ -920,7 +910,7 @@ class CCXT(Library):
|
|
920
910
|
while start_date < end_date and attempts < trials:
|
921
911
|
|
922
912
|
try:
|
923
|
-
|
913
|
+
data = await self.exchange_async.fetch_open_interest_history(
|
924
914
|
ticker,
|
925
915
|
freq,
|
926
916
|
since=start_date,
|
@@ -929,12 +919,10 @@ class CCXT(Library):
|
|
929
919
|
)
|
930
920
|
|
931
921
|
# add data to list
|
932
|
-
if
|
933
|
-
start_date =
|
934
|
-
|
922
|
+
if data:
|
923
|
+
start_date = data[-1]['timestamp'] + 1
|
924
|
+
data_resp.extend(data)
|
935
925
|
else:
|
936
|
-
if not data:
|
937
|
-
logging.warning(f"No open interest data available for {ticker}.")
|
938
926
|
break
|
939
927
|
|
940
928
|
except Exception as e:
|
@@ -954,10 +942,9 @@ class CCXT(Library):
|
|
954
942
|
await self.exponential_backoff_with_jitter_async(self.exchange_async.rateLimit / 1000,
|
955
943
|
pause,
|
956
944
|
attempts)
|
957
|
-
# await asyncio.sleep(self.exchange_async.rateLimit / 1000)
|
958
945
|
|
959
946
|
await self.exchange_async.close()
|
960
|
-
return
|
947
|
+
return data_resp
|
961
948
|
|
962
949
|
else:
|
963
950
|
logging.warning(f"Open interest is not available for {self.exchange_async.id}.")
|
@@ -966,12 +953,12 @@ class CCXT(Library):
|
|
966
953
|
def _fetch_open_interest(self,
|
967
954
|
ticker: str,
|
968
955
|
freq: str,
|
969
|
-
start_date:
|
970
|
-
end_date:
|
956
|
+
start_date: int,
|
957
|
+
end_date: int,
|
971
958
|
exch: str,
|
972
959
|
trials: int = 3,
|
973
960
|
pause: int = 1
|
974
|
-
) -> List:
|
961
|
+
) -> Union[List, None]:
|
975
962
|
"""
|
976
963
|
Fetches open interest data for a specific ticker.
|
977
964
|
|
@@ -981,9 +968,9 @@ class CCXT(Library):
|
|
981
968
|
Ticker symbol.
|
982
969
|
freq: str
|
983
970
|
Frequency of data, e.g. '1m', '5m', '1h', '1d'.
|
984
|
-
start_date:
|
971
|
+
start_date: int
|
985
972
|
Start date in integers in milliseconds since Unix epoch.
|
986
|
-
end_date:
|
973
|
+
end_date: int
|
987
974
|
End date in integers in milliseconds since Unix epoch.
|
988
975
|
exch: str
|
989
976
|
Name of exchange.
|
@@ -994,12 +981,12 @@ class CCXT(Library):
|
|
994
981
|
|
995
982
|
Returns
|
996
983
|
-------
|
997
|
-
|
984
|
+
data_resp: list
|
998
985
|
List of dictionaries with timestamps and open interest data.
|
999
986
|
"""
|
1000
987
|
# number of attempts
|
1001
988
|
attempts = 0
|
1002
|
-
|
989
|
+
data_resp = []
|
1003
990
|
|
1004
991
|
# inst exch
|
1005
992
|
self.exchange = getattr(ccxt, exch)()
|
@@ -1011,7 +998,7 @@ class CCXT(Library):
|
|
1011
998
|
while start_date < end_date and attempts < trials:
|
1012
999
|
|
1013
1000
|
try:
|
1014
|
-
|
1001
|
+
data = self.exchange.fetch_open_interest_history(
|
1015
1002
|
ticker,
|
1016
1003
|
freq,
|
1017
1004
|
since=start_date,
|
@@ -1020,12 +1007,10 @@ class CCXT(Library):
|
|
1020
1007
|
)
|
1021
1008
|
|
1022
1009
|
# add data to list
|
1023
|
-
if
|
1024
|
-
start_date =
|
1025
|
-
|
1010
|
+
if data:
|
1011
|
+
start_date = data[-1]['timestamp'] + 1
|
1012
|
+
data_resp.extend(data)
|
1026
1013
|
else:
|
1027
|
-
if not data:
|
1028
|
-
logging.warning(f"No open interest data available for {ticker}.")
|
1029
1014
|
break
|
1030
1015
|
|
1031
1016
|
except Exception as e:
|
@@ -1043,9 +1028,8 @@ class CCXT(Library):
|
|
1043
1028
|
|
1044
1029
|
finally:
|
1045
1030
|
self.exponential_backoff_with_jitter(self.exchange.rateLimit / 1000, pause, attempts)
|
1046
|
-
# sleep(self.exchange.rateLimit / 1000)
|
1047
1031
|
|
1048
|
-
return
|
1032
|
+
return data_resp
|
1049
1033
|
|
1050
1034
|
else:
|
1051
1035
|
logging.warning(f"Open interest is not available for {self.exchange.id}.")
|
@@ -1054,12 +1038,12 @@ class CCXT(Library):
|
|
1054
1038
|
async def _fetch_all_open_interest_async(self,
|
1055
1039
|
tickers,
|
1056
1040
|
freq: str,
|
1057
|
-
start_date:
|
1058
|
-
end_date:
|
1041
|
+
start_date: int,
|
1042
|
+
end_date: int,
|
1059
1043
|
exch: str,
|
1060
1044
|
trials: int = 3,
|
1061
1045
|
pause: int = 1
|
1062
|
-
):
|
1046
|
+
) -> Union[List, None]:
|
1063
1047
|
"""
|
1064
1048
|
Fetches open interest data for a list of tickers.
|
1065
1049
|
|
@@ -1069,9 +1053,9 @@ class CCXT(Library):
|
|
1069
1053
|
List of ticker symbols.
|
1070
1054
|
freq: str
|
1071
1055
|
Frequency of data, e.g. '1m', '5m', '1h', '1d'.
|
1072
|
-
start_date:
|
1056
|
+
start_date: int
|
1073
1057
|
Start date in integers in milliseconds since Unix epoch.
|
1074
|
-
end_date:
|
1058
|
+
end_date: int
|
1075
1059
|
End date in integers in milliseconds since Unix epoch.
|
1076
1060
|
exch: str
|
1077
1061
|
Name of exchange.
|
@@ -1082,39 +1066,36 @@ class CCXT(Library):
|
|
1082
1066
|
|
1083
1067
|
Returns
|
1084
1068
|
-------
|
1085
|
-
|
1069
|
+
data_resp: list
|
1086
1070
|
List of lists of dictionaries with timestamps and open interest data for each ticker.
|
1087
1071
|
"""
|
1088
1072
|
# inst exch
|
1089
1073
|
if self.exchange_async is None:
|
1090
1074
|
self.exchange_async = getattr(ccxt_async, exch)()
|
1091
1075
|
|
1092
|
-
data = []
|
1093
|
-
|
1094
1076
|
# create progress bar
|
1095
1077
|
pbar = tqdm(total=len(tickers), desc="Fetching open interest", unit="ticker")
|
1096
1078
|
|
1097
1079
|
# loop through tickers
|
1098
1080
|
for ticker in tickers:
|
1099
|
-
|
1100
|
-
|
1101
|
-
data.append(data_resp)
|
1081
|
+
data = await self._fetch_open_interest_async(ticker, freq, start_date, end_date, trials=trials, exch=exch)
|
1082
|
+
self.data_resp.extend(data)
|
1102
1083
|
pbar.update(1)
|
1103
1084
|
await asyncio.sleep(pause)
|
1104
1085
|
|
1105
1086
|
await self.exchange_async.close()
|
1106
1087
|
|
1107
|
-
return
|
1088
|
+
return self.data_resp
|
1108
1089
|
|
1109
1090
|
def _fetch_all_open_interest(self,
|
1110
1091
|
tickers,
|
1111
1092
|
freq: str,
|
1112
|
-
start_date:
|
1113
|
-
end_date:
|
1093
|
+
start_date: int,
|
1094
|
+
end_date: int,
|
1114
1095
|
exch: str,
|
1115
1096
|
trials: int = 3,
|
1116
1097
|
pause: int = 1
|
1117
|
-
):
|
1098
|
+
) -> Union[List, None]:
|
1118
1099
|
"""
|
1119
1100
|
Fetches open interest data for a list of tickers.
|
1120
1101
|
|
@@ -1124,9 +1105,9 @@ class CCXT(Library):
|
|
1124
1105
|
List of ticker symbols.
|
1125
1106
|
freq: str
|
1126
1107
|
Frequency of data, e.g. '1m', '5m', '1h', '1d'.
|
1127
|
-
start_date:
|
1108
|
+
start_date: int
|
1128
1109
|
Start date in integers in milliseconds since Unix epoch.
|
1129
|
-
end_date:
|
1110
|
+
end_date: int
|
1130
1111
|
End date in integers in milliseconds since Unix epoch.
|
1131
1112
|
exch: str
|
1132
1113
|
Name of exchange.
|
@@ -1137,26 +1118,24 @@ class CCXT(Library):
|
|
1137
1118
|
|
1138
1119
|
Returns
|
1139
1120
|
-------
|
1140
|
-
|
1121
|
+
data_resp: list
|
1141
1122
|
List of lists of dictionaries with timestamps and open interest data for each ticker.
|
1142
1123
|
"""
|
1143
1124
|
# inst exch
|
1144
1125
|
if self.exchange is None:
|
1145
1126
|
self.exchange = getattr(ccxt, exch)()
|
1146
1127
|
|
1147
|
-
data = []
|
1148
|
-
|
1149
1128
|
# create progress bar
|
1150
1129
|
pbar = tqdm(total=len(tickers), desc="Fetching open interest", unit="ticker")
|
1151
1130
|
|
1152
1131
|
# loop through tickers
|
1153
1132
|
for ticker in tickers:
|
1154
|
-
|
1155
|
-
|
1133
|
+
data = self._fetch_open_interest(ticker, freq, start_date, end_date, trials=trials, exch=exch)
|
1134
|
+
self.data_resp.extend(data)
|
1156
1135
|
pbar.update(1)
|
1157
1136
|
sleep(pause)
|
1158
1137
|
|
1159
|
-
return
|
1138
|
+
return self.data_resp
|
1160
1139
|
|
1161
1140
|
def convert_params(self, data_req: DataRequest) -> DataRequest:
|
1162
1141
|
"""
|
@@ -1249,14 +1228,12 @@ class CCXT(Library):
|
|
1249
1228
|
|
1250
1229
|
return self.data_req
|
1251
1230
|
|
1252
|
-
def wrangle_data_resp(self,
|
1231
|
+
def wrangle_data_resp(self, data_type: str) -> pd.DataFrame:
|
1253
1232
|
"""
|
1254
1233
|
Wrangle data response.
|
1255
1234
|
|
1256
1235
|
Parameters
|
1257
1236
|
----------
|
1258
|
-
data_resp: pd.DataFrame
|
1259
|
-
Data response from GET request.
|
1260
1237
|
data_type: str
|
1261
1238
|
Type of data, e.g. 'ohlcv', 'funding_rate', 'open_interest'.
|
1262
1239
|
|
@@ -1265,8 +1242,7 @@ class CCXT(Library):
|
|
1265
1242
|
df: pd.DataFrame
|
1266
1243
|
Wrangled dataframe with DatetimeIndex and values in tidy format.
|
1267
1244
|
"""
|
1268
|
-
|
1269
|
-
return WrangleData(self.data_req, data_resp).ccxt(data_type=data_type)
|
1245
|
+
return WrangleData(self.data_req, self.data_resp).ccxt(data_type=data_type)
|
1270
1246
|
|
1271
1247
|
async def fetch_tidy_ohlcv_async(self, data_req: DataRequest) -> pd.DataFrame:
|
1272
1248
|
"""
|
@@ -1286,18 +1262,22 @@ class CCXT(Library):
|
|
1286
1262
|
if self.data_req is None:
|
1287
1263
|
self.convert_params(data_req)
|
1288
1264
|
|
1265
|
+
# data resp
|
1266
|
+
if self.data_resp:
|
1267
|
+
self.data_resp = []
|
1268
|
+
|
1289
1269
|
# get entire data history
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1270
|
+
await self._fetch_all_ohlcv_async(self.data_req.source_markets,
|
1271
|
+
self.data_req.source_freq,
|
1272
|
+
self.data_req.source_start_date,
|
1273
|
+
self.data_req.source_end_date,
|
1274
|
+
self.data_req.exch,
|
1275
|
+
trials=self.data_req.trials,
|
1276
|
+
pause=self.data_req.pause)
|
1297
1277
|
|
1298
1278
|
# wrangle df
|
1299
|
-
if
|
1300
|
-
df = self.wrangle_data_resp(
|
1279
|
+
if self.data_resp:
|
1280
|
+
df = self.wrangle_data_resp(data_type='ohlcv')
|
1301
1281
|
return df
|
1302
1282
|
else:
|
1303
1283
|
logging.warning("Failed to get requested OHLCV data.")
|
@@ -1320,18 +1300,22 @@ class CCXT(Library):
|
|
1320
1300
|
if self.data_req is None:
|
1321
1301
|
self.convert_params(data_req)
|
1322
1302
|
|
1303
|
+
# data resp
|
1304
|
+
if self.data_resp:
|
1305
|
+
self.data_resp = []
|
1306
|
+
|
1323
1307
|
# get entire data history
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1308
|
+
self._fetch_all_ohlcv(self.data_req.source_markets,
|
1309
|
+
self.data_req.source_freq,
|
1310
|
+
self.data_req.source_start_date,
|
1311
|
+
self.data_req.source_end_date,
|
1312
|
+
self.data_req.exch,
|
1313
|
+
trials=self.data_req.trials,
|
1314
|
+
pause=self.data_req.pause)
|
1331
1315
|
|
1332
1316
|
# wrangle df
|
1333
|
-
if
|
1334
|
-
df = self.wrangle_data_resp(
|
1317
|
+
if self.data_resp:
|
1318
|
+
df = self.wrangle_data_resp(data_type='ohlcv')
|
1335
1319
|
return df
|
1336
1320
|
else:
|
1337
1321
|
logging.warning("Failed to get requested OHLCV data.")
|
@@ -1354,17 +1338,21 @@ class CCXT(Library):
|
|
1354
1338
|
if self.data_req is None:
|
1355
1339
|
self.convert_params(data_req)
|
1356
1340
|
|
1341
|
+
# data resp
|
1342
|
+
if self.data_resp:
|
1343
|
+
self.data_resp = []
|
1344
|
+
|
1357
1345
|
# get entire data history
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1346
|
+
await self._fetch_all_funding_rates_async(self.data_req.source_markets,
|
1347
|
+
self.data_req.source_start_date,
|
1348
|
+
self.data_req.source_end_date,
|
1349
|
+
self.data_req.exch,
|
1350
|
+
trials=self.data_req.trials,
|
1351
|
+
pause=self.data_req.pause)
|
1364
1352
|
|
1365
1353
|
# wrangle df
|
1366
|
-
if
|
1367
|
-
df = self.wrangle_data_resp(
|
1354
|
+
if self.data_resp:
|
1355
|
+
df = self.wrangle_data_resp(data_type='funding_rates')
|
1368
1356
|
return df
|
1369
1357
|
else:
|
1370
1358
|
logging.warning("Failed to get requested funding rates.")
|
@@ -1387,17 +1375,21 @@ class CCXT(Library):
|
|
1387
1375
|
if self.data_req is None:
|
1388
1376
|
self.convert_params(data_req)
|
1389
1377
|
|
1378
|
+
# data resp
|
1379
|
+
if self.data_resp:
|
1380
|
+
self.data_resp = []
|
1381
|
+
|
1390
1382
|
# get entire data history
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1383
|
+
self._fetch_all_funding_rates(self.data_req.source_markets,
|
1384
|
+
self.data_req.source_start_date,
|
1385
|
+
self.data_req.source_end_date,
|
1386
|
+
self.data_req.exch,
|
1387
|
+
trials=self.data_req.trials,
|
1388
|
+
pause=self.data_req.pause)
|
1397
1389
|
|
1398
1390
|
# wrangle df
|
1399
|
-
if
|
1400
|
-
df = self.wrangle_data_resp(
|
1391
|
+
if self.data_resp:
|
1392
|
+
df = self.wrangle_data_resp(data_type='funding_rates')
|
1401
1393
|
return df
|
1402
1394
|
else:
|
1403
1395
|
logging.warning("Failed to get requested funding rates.")
|
@@ -1420,18 +1412,22 @@ class CCXT(Library):
|
|
1420
1412
|
if self.data_req is None:
|
1421
1413
|
self.convert_params(data_req)
|
1422
1414
|
|
1415
|
+
# data resp
|
1416
|
+
if self.data_resp:
|
1417
|
+
self.data_resp = []
|
1418
|
+
|
1423
1419
|
# get entire data history
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1420
|
+
await self._fetch_all_open_interest_async(self.data_req.source_markets,
|
1421
|
+
self.data_req.source_freq,
|
1422
|
+
self.data_req.source_start_date,
|
1423
|
+
self.data_req.source_end_date,
|
1424
|
+
self.data_req.exch,
|
1425
|
+
trials=self.data_req.trials,
|
1426
|
+
pause=self.data_req.pause)
|
1431
1427
|
|
1432
1428
|
# wrangle df
|
1433
|
-
if
|
1434
|
-
df = self.wrangle_data_resp(
|
1429
|
+
if self.data_resp:
|
1430
|
+
df = self.wrangle_data_resp(data_type='open_interest')
|
1435
1431
|
return df
|
1436
1432
|
else:
|
1437
1433
|
logging.warning("Failed to get requested open interest.")
|
@@ -1454,18 +1450,22 @@ class CCXT(Library):
|
|
1454
1450
|
if self.data_req is None:
|
1455
1451
|
self.convert_params(data_req)
|
1456
1452
|
|
1453
|
+
# data resp
|
1454
|
+
if self.data_resp:
|
1455
|
+
self.data_resp = []
|
1456
|
+
|
1457
1457
|
# get entire data history
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1458
|
+
self._fetch_all_open_interest(self.data_req.source_markets,
|
1459
|
+
self.data_req.source_freq,
|
1460
|
+
self.data_req.source_start_date,
|
1461
|
+
self.data_req.source_end_date,
|
1462
|
+
self.data_req.exch,
|
1463
|
+
trials=self.data_req.trials,
|
1464
|
+
pause=self.data_req.pause)
|
1465
1465
|
|
1466
1466
|
# wrangle df
|
1467
|
-
if
|
1468
|
-
df = self.wrangle_data_resp(
|
1467
|
+
if self.data_resp:
|
1468
|
+
df = self.wrangle_data_resp(data_type='open_interest')
|
1469
1469
|
return df
|
1470
1470
|
else:
|
1471
1471
|
logging.warning("Failed to get requested open interest.")
|
@@ -1488,17 +1488,20 @@ class CCXT(Library):
|
|
1488
1488
|
# get OHLCV
|
1489
1489
|
if any([field in ["open", "high", "low", "close", "volume"] for field in data_req.fields]):
|
1490
1490
|
df = await self.fetch_tidy_ohlcv_async(data_req)
|
1491
|
-
|
1491
|
+
if any(df):
|
1492
|
+
self.data = pd.concat([self.data, df])
|
1492
1493
|
|
1493
1494
|
# get funding rates
|
1494
1495
|
if any([field == "funding_rate" for field in data_req.fields]):
|
1495
1496
|
df = await self.fetch_tidy_funding_rates_async(data_req)
|
1496
|
-
|
1497
|
+
if any(df):
|
1498
|
+
self.data = pd.concat([self.data, df], axis=1)
|
1497
1499
|
|
1498
1500
|
# get open interest
|
1499
1501
|
if any([field == "oi" for field in data_req.fields]):
|
1500
1502
|
df = await self.fetch_tidy_open_interest_async(data_req)
|
1501
|
-
|
1503
|
+
if any(df):
|
1504
|
+
self.data = pd.concat([self.data, df], axis=1)
|
1502
1505
|
|
1503
1506
|
# check df
|
1504
1507
|
if self.data.empty:
|
@@ -1530,17 +1533,20 @@ class CCXT(Library):
|
|
1530
1533
|
# get OHLCV
|
1531
1534
|
if any([field in ["open", "high", "low", "close", "volume"] for field in data_req.fields]):
|
1532
1535
|
df = self.fetch_tidy_ohlcv(data_req)
|
1533
|
-
|
1536
|
+
if any(df):
|
1537
|
+
self.data = pd.concat([self.data, df])
|
1534
1538
|
|
1535
1539
|
# get funding rates
|
1536
1540
|
if any([field == "funding_rate" for field in data_req.fields]):
|
1537
1541
|
df = self.fetch_tidy_funding_rates(data_req)
|
1538
|
-
|
1542
|
+
if any(df):
|
1543
|
+
self.data = pd.concat([self.data, df], axis=1)
|
1539
1544
|
|
1540
1545
|
# get open interest
|
1541
1546
|
if any([field == "oi" for field in data_req.fields]):
|
1542
1547
|
df = self.fetch_tidy_open_interest(data_req)
|
1543
|
-
|
1548
|
+
if any(df):
|
1549
|
+
self.data = pd.concat([self.data, df], axis=1)
|
1544
1550
|
|
1545
1551
|
# check df
|
1546
1552
|
if self.data.empty:
|