microsoft / microsoft/qlib

AttributeError: module 'qlib.contrib.report' has no attribute 'cumulative_return_graph'

Open
#394 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
48.7k
Forks
7.7k
PR merge metrics
No merged PRs in 30d

Description

🐛 Bug Description

To Reproduce

Steps to reproduce the behavior:

Copyright (c) Microsoft Corporation.

Licensed under the MIT License.

import sys
from pathlib import Path

import qlib
import pandas as pd
from qlib.config import REG_CN
from qlib.contrib.model.gbdt import LGBModel
from qlib.contrib.data.handler import Alpha158
from qlib.contrib.strategy.strategy import TopkDropoutStrategy
from qlib.contrib.evaluate import risk_analysis, backtest, long_short_backtest
from qlib.contrib.evaluate import (backtest as normal_backtest,risk_analysis,)
from qlib.utils import exists_qlib_data, init_instance_by_config, flatten_dict
from qlib.workflow import R
from qlib.workflow.record_temp import SignalRecord, PortAnaRecord
from qlib.tests.data import GetData

if name == "main":

# use default data
provider_uri = "~/.qlib/qlib_data/cn_data"  # target_dir
if not exists_qlib_data(provider_uri):
    print(f"Qlib data is not found in {provider_uri}")
    GetData().qlib_data(target_dir=provider_uri, region=REG_CN)

qlib.init(provider_uri=provider_uri, region=REG_CN)

market = "csi300"
# market=["SH000903"]
benchmark = "SH000300"

###################################
# train model
###################################
data_handler_config = {
    "start_time": "2008-01-01",
    "end_time": "2020-08-01",
    "fit_start_time": "2008-01-01",
    "fit_end_time": "2014-12-31",
    "instruments": market,
}

task = {
    "model": {
        "class": "LGBModel",
        "module_path": "qlib.contrib.model.gbdt",
        "kwargs": {
            "loss": "mse",
            "colsample_bytree": 0.8879,
            "learning_rate": 0.0421,
            "subsample": 0.8789,
            "lambda_l1": 205.6999,
            "lambda_l2": 580.9768,
            "max_depth": 8,
            "num_leaves": 210,
            "num_threads": 20,
        },
    },
    "dataset": {
        "class": "DatasetH",
        "module_path": "qlib.data.dataset",
        "kwargs": {
            "handler": {
                "class": "Alpha158",
                "module_path": "qlib.contrib.data.handler",
                "kwargs": data_handler_config,
            },
            "segments": {
                "train": ("2008-01-01", "2014-12-31"),
                "valid": ("2015-01-01", "2016-12-31"),
                "test": ("2017-01-01", "2020-08-01"),
            },
        },
    },
}

port_analysis_config = {
    "strategy": {
        "class": "TopkDropoutStrategy",
        "module_path": "qlib.contrib.strategy.strategy",
        "kwargs": {
            "topk": 50,
            "n_drop": 5,
        },
    },
    "backtest": {
        "verbose": False,
        "limit_threshold": 0.095,
        "account": 100000000,
        "benchmark": benchmark,
        "deal_price": "close",
        "open_cost": 0.0005,
        "close_cost": 0.0015,
        "min_cost": 5,
        "return_order": True,
    },
}

# model initialization
model = init_instance_by_config(task["model"])
dataset = init_instance_by_config(task["dataset"])

# NOTE: This line is optional
# It demonstrates that the dataset can be used standalone.
example_df = dataset.prepare("train")
print(example_df.head())

# start exp
with R.start(experiment_name="backtest_analysis"):
    R.log_params(**flatten_dict(task))
    model.fit(dataset)
    R.save_objects(**{"params.pkl": model})

    # prediction
    recorder = R.get_recorder()
    ba_rid = recorder.id
    sr = SignalRecord(model, dataset, recorder)
    sr.generate()

    # backtest. If users want to use backtest based on their own prediction,
    # please refer to https://qlib.readthedocs.io/en/latest/component/recorder.html#record-template.
    print("===PortAnaRecord===")
    par = PortAnaRecord(recorder, port_analysis_config)
    par.generate()

    # from qlib.contrib.report import analysis_model, analysis_position


    # recorder = R.get_recorder(ba_rid, experiment_name="backtest_analysis")
    import qlib.contrib.report as qcr
    from qlib.contrib.report import analysis_model, analysis_position
    from qlib.data import D

    pred_df = recorder.load_object("pred.pkl")
    pred_df_dates = pred_df.index.get_level_values(level='datetime')
    report_normal_df = recorder.load_object("portfolio_analysis/report_normal.pkl")
    positions = recorder.load_object("portfolio_analysis/positions_normal.pkl")
    analysis_df = recorder.load_object("portfolio_analysis/port_analysis.pkl")




    # from qlib.contrib.strategy import TopkDropoutStrategy

    # backtest parameters
    bparas = {}
    bparas['limit_threshold'] = 0.095
    bparas["benchmark"] = benchmark

    bparas['account'] = 1000000000

    sparas = {}
    sparas['topk'] = 50
    sparas['n_drop'] = 5
    strategy = TopkDropoutStrategy(**sparas)
    print("strategy : " , strategy)
    bparas['class'] = strategy

    report_normal_df, positions = backtest(pred_df, **bparas)
    # <qlib.contrib.strategy.strategy.TopkDropoutStrategy object at 0x7f4347ba3f28>

    pred_df_dates = pred_df.index.get_level_values(level='datetime')
    features_df = D.features(D.instruments('csi300'), ['Ref($close, -1)/$close - 1'], pred_df_dates.min(),
                             pred_df_dates.max())
    features_df.columns = ['label']
    print(qcr.GRAPH_NAME_LIST)
    qcr.cumulative_return_graph(positions, report_normal_df, features_df)

Execute the above code!!!

Expected Behavior

Screenshot

['analysis_position.report_graph', 'analysis_position.score_ic_graph', 'analysis_position.cumulative_return_graph', 'analysis_position.risk_analysis_graph', 'analysis_position.rank_label_graph', 'analysis_model.model_performance_graph']
[5151:MainThread](2021-04-19 12:38:55,455) ERROR - qlib.workflow - [utils.py:35] - An exception has been raised[AttributeError: module 'qlib.contrib.report' has no attribute 'cumulative_return_graph'].
File "examples/workflow_by_code.py", line 171, in
qcr.cumulative_return_graph(positions, report_normal_df, features_df)
AttributeError: module 'qlib.contrib.report' has no attribute 'cumulative_return_graph'

Note: User could run cd scripts && python collect_info.py all under project directory to get system information
and paste them here directly.

  • Qlib version:0.6.3.99
  • Python version:python3.7
  • OS (Windows, Linux, MacOS):linux
  • Commit number (optional, please provide it if you are using the dev version):

Additional Notes

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with examples/workflow_by_code.py and inspect the public exports under qlib/contrib/report, especially the GRAPH_NAME_LIST entries shown in the issue. Reproduce the example far enough to confirm the AttributeError, then verify that the cumulative-return graph can be invoked through the documented report API without changing the expected graph output.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
data-visualization
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.