1
0
mirror of https://github.com/microsoft/qlib.git synced 2026-07-17 17:34:35 +08:00

Remove arctic from Qlib core to Contrib (#865)

* Remove arctic from Qlib core to Contrib

* fix empty df bug
This commit is contained in:
you-n-g
2022-01-19 10:39:37 +08:00
committed by GitHub
parent a79e446724
commit 1a0ac1ab6d
6 changed files with 62 additions and 45 deletions

View File

@@ -17,6 +17,7 @@ Current version of script with default value tries to connect localhost **via de
Run following command to install necessary libraries Run following command to install necessary libraries
``` ```
pip install pytest pip install pytest
pip install arctic # NOTE: pip may fail to resolve the right package dependency !!! Please make sure the dependency are satisfied.
``` ```
# Importing example data # Importing example data

View File

@@ -25,7 +25,11 @@ class TestClass(unittest.TestCase):
mem_cache_type="sizeof", mem_cache_type="sizeof",
kernels=1, kernels=1,
expression_provider={"class": "LocalExpressionProvider", "kwargs": {"time2idx": False}}, expression_provider={"class": "LocalExpressionProvider", "kwargs": {"time2idx": False}},
feature_provider={"class": "ArcticFeatureProvider", "kwargs": {"uri": "127.0.0.1"}}, feature_provider={
"class": "ArcticFeatureProvider",
"module_path": "qlib.contrib.data.data",
"kwargs": {"uri": "127.0.0.1"},
},
dataset_provider={ dataset_provider={
"class": "LocalDatasetProvider", "class": "LocalDatasetProvider",
"kwargs": { "kwargs": {

55
qlib/contrib/data/data.py Normal file
View File

@@ -0,0 +1,55 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# We remove arctic from core framework of Qlib to contrib due to
# - Arctic has very strict limitation on pandas and numpy version
# - https://github.com/man-group/arctic/pull/908
# - pip fail to computing the right version number!!!!
# - Maybe we can solve this problem by poetry
# FIXME: So if you want to use arctic-based provider, please install arctic manually
# `pip install arctic` may not be enough.
from arctic import Arctic
import pandas as pd
import pymongo
from qlib.data.data import FeatureProvider
class ArcticFeatureProvider(FeatureProvider):
def __init__(
self, uri="127.0.0.1", retry_time=0, market_transaction_time_list=[("09:15", "11:30"), ("13:00", "15:00")]
):
super().__init__()
self.uri = uri
# TODO:
# retry connecting if error occurs
# does it real matters?
self.retry_time = retry_time
# NOTE: this is especially important for TResample operator
self.market_transaction_time_list = market_transaction_time_list
def feature(self, instrument, field, start_index, end_index, freq):
field = str(field)[1:]
with pymongo.MongoClient(self.uri) as client:
# TODO: this will result in frequently connecting the server and performance issue
arctic = Arctic(client)
if freq not in arctic.list_libraries():
raise ValueError("lib {} not in arctic".format(freq))
if instrument not in arctic[freq].list_symbols():
# instruments does not exist
return pd.Series()
else:
df = arctic[freq].read(instrument, columns=[field], chunk_range=(start_index, end_index))
s = df[field]
if not s.empty:
s = pd.concat(
[
s.between_time(time_tuple[0], time_tuple[1])
for time_tuple in self.market_transaction_time_list
]
)
return s

View File

@@ -15,7 +15,6 @@ from .data import (
LocalCalendarProvider, LocalCalendarProvider,
LocalInstrumentProvider, LocalInstrumentProvider,
LocalFeatureProvider, LocalFeatureProvider,
ArcticFeatureProvider,
LocalExpressionProvider, LocalExpressionProvider,
LocalDatasetProvider, LocalDatasetProvider,
ClientCalendarProvider, ClientCalendarProvider,

View File

@@ -17,11 +17,9 @@ import pandas as pd
from multiprocessing import Pool from multiprocessing import Pool
from typing import Iterable, Union from typing import Iterable, Union
from typing import List, Union from typing import List, Union
from arctic import Arctic
# For supporting multiprocessing in outer code, joblib is used # For supporting multiprocessing in outer code, joblib is used
from joblib import delayed from joblib import delayed
import pymongo
from .cache import H from .cache import H
from ..config import C from ..config import C
@@ -582,7 +580,7 @@ class DatasetProvider(abc.ABC):
data.index = _calendar[data.index.values.astype(int)] data.index = _calendar[data.index.values.astype(int)]
data.index.names = ["datetime"] data.index.names = ["datetime"]
if spans is not None: if not data.empty and spans is not None:
mask = np.zeros(len(data), dtype=bool) mask = np.zeros(len(data), dtype=bool)
for begin, end in spans: for begin, end in spans:
mask |= (data.index >= begin) & (data.index <= end) mask |= (data.index >= begin) & (data.index <= end)
@@ -702,45 +700,6 @@ class LocalFeatureProvider(FeatureProvider, ProviderBackendMixin):
return self.backend_obj(instrument=instrument, field=field, freq=freq)[start_index : end_index + 1] return self.backend_obj(instrument=instrument, field=field, freq=freq)[start_index : end_index + 1]
class ArcticFeatureProvider(FeatureProvider):
def __init__(
self, uri="127.0.0.1", retry_time=0, market_transaction_time_list=[("09:15", "11:30"), ("13:00", "15:00")]
):
super().__init__()
self.uri = uri
# TODO:
# retry connecting if error occurs
# does it real matters?
self.retry_time = retry_time
# NOTE: this is especially important for TResample operator
self.market_transaction_time_list = market_transaction_time_list
def feature(self, instrument, field, start_index, end_index, freq):
field = str(field)[1:]
with pymongo.MongoClient(self.uri) as client:
# TODO: this will result in frequently connecting the server and performance issue
arctic = Arctic(client)
if freq not in arctic.list_libraries():
raise ValueError("lib {} not in arctic".format(freq))
if instrument not in arctic[freq].list_symbols():
# instruments does not exist
return pd.Series()
else:
df = arctic[freq].read(instrument, columns=[field], chunk_range=(start_index, end_index))
s = df[field]
if not s.empty:
s = pd.concat(
[
s.between_time(time_tuple[0], time_tuple[1])
for time_tuple in self.market_transaction_time_list
]
)
return s
class LocalExpressionProvider(ExpressionProvider): class LocalExpressionProvider(ExpressionProvider):
"""Local expression data provider class """Local expression data provider class

View File

@@ -78,7 +78,6 @@ REQUIRED = [
"dill", "dill",
"dataclasses;python_version<'3.7'", "dataclasses;python_version<'3.7'",
"filelock", "filelock",
"arctic",
] ]
# Numpy include # Numpy include