mirror of
https://github.com/NicolasBohn/NexQuant.git
synced 2026-07-27 23:47:46 +00:00
First version of factor idea proposal (#46)
* update all code * save code * update first version of factor proposal * change a comment * remove a useless comment --------- Co-authored-by: xuyang1 <xuyang1@microsoft.com>
This commit is contained in:
@@ -1,12 +0,0 @@
|
||||
from pydantic_settings import BaseSettings
|
||||
|
||||
|
||||
class ModelPropSetting(BaseSettings):
|
||||
""""""
|
||||
|
||||
scen: str # a.b.c:XXXClass
|
||||
# TODO: inital keywards should be included in the settings
|
||||
...
|
||||
|
||||
|
||||
MODEL_PROP_SETTING = ModelPropSetting()
|
||||
@@ -0,0 +1,17 @@
|
||||
from pydantic_settings import BaseSettings
|
||||
|
||||
|
||||
class PropSetting(BaseSettings):
|
||||
""""""
|
||||
|
||||
scen: str = "rdagent.scenarios.qlib.experiment.factor_experiment.QlibFactorScenario"
|
||||
hypothesis_gen: str = "rdagent.scenarios.qlib.factor_proposal.QlibFactorHypothesisGen"
|
||||
hypothesis2experiment: str = "rdagent.scenarios.qlib.factor_proposal.QlibFactorHypothesis2Experiment"
|
||||
qlib_factor_coder: str = "rdagent.components.task_implementation.factor_implementation.CoSTEER.CoSTEERFG"
|
||||
qlib_factor_runner: str = "rdagent.scenarios.qlib.task_generator.data.QlibFactorRunner"
|
||||
qlib_factor_summarizer: str = "rdagent.scenarios.qlib.task_generator.feedback.QlibFactorExperiment2Feedback"
|
||||
|
||||
evolving_n: int = 10
|
||||
|
||||
|
||||
PROP_SETTING = PropSetting()
|
||||
@@ -0,0 +1,38 @@
|
||||
"""
|
||||
TODO: Factor Structure RD-Loop
|
||||
"""
|
||||
|
||||
# import_from
|
||||
from rdagent.app.qlib_rd_loop.conf import PROP_SETTING
|
||||
from rdagent.core.proposal import (
|
||||
Experiment2Feedback,
|
||||
Hypothesis2Experiment,
|
||||
HypothesisGen,
|
||||
HypothesisSet,
|
||||
Trace,
|
||||
)
|
||||
from rdagent.core.task_generator import TaskGenerator
|
||||
from rdagent.core.utils import import_class
|
||||
|
||||
scen = import_class(PROP_SETTING.scen)()
|
||||
|
||||
hypothesis_gen: HypothesisGen = import_class(PROP_SETTING.hypothesis_gen)(scen)
|
||||
|
||||
hypothesis2experiment: Hypothesis2Experiment = import_class(PROP_SETTING.hypothesis2experiment)()
|
||||
|
||||
qlib_factor_coder: TaskGenerator = import_class(PROP_SETTING.qlib_factor_coder)()
|
||||
qlib_factor_runner: TaskGenerator = import_class(PROP_SETTING.qlib_factor_runner)()
|
||||
|
||||
qlib_factor_summarizer: Experiment2Feedback = import_class(PROP_SETTING.qlib_factor_summarizer)()
|
||||
|
||||
|
||||
trace = Trace(scen=scen)
|
||||
hs = HypothesisSet(trace=trace)
|
||||
for _ in range(PROP_SETTING.evolving_n):
|
||||
hypothesis = hypothesis_gen.gen(trace)
|
||||
exp = hypothesis2experiment.convert(hs)
|
||||
exp = qlib_factor_coder.generate(exp)
|
||||
exp = qlib_factor_runner.generate(exp)
|
||||
feedback = qlib_factor_summarizer.summarize(exp)
|
||||
|
||||
trace.hist.append((hypothesis, exp, feedback))
|
||||
@@ -1,13 +1,18 @@
|
||||
from abc import abstractmethod
|
||||
from pathlib import Path
|
||||
from typing import Tuple
|
||||
|
||||
from jinja2 import Environment, StrictUndefined
|
||||
|
||||
from rdagent.components.task_implementation.factor_implementation.factor import (
|
||||
FactorExperiment,
|
||||
)
|
||||
from rdagent.core.prompts import Prompts
|
||||
from rdagent.core.proposal import (
|
||||
Hypothesis,
|
||||
Hypothesis2Task,
|
||||
Hypothesis2Experiment,
|
||||
HypothesisGen,
|
||||
HypothesisSet,
|
||||
Scenario,
|
||||
Trace,
|
||||
)
|
||||
@@ -22,40 +27,71 @@ FactorHypothesis = Hypothesis
|
||||
class FactorHypothesisGen(HypothesisGen):
|
||||
def __init__(self, scen: Scenario):
|
||||
super().__init__(scen)
|
||||
self.gen_context_flag = False
|
||||
self.gen_context_dict = None
|
||||
self.gen_json_flag = False
|
||||
|
||||
# The following methods are scenario related so they should be implemented in the subclass
|
||||
@abstractmethod
|
||||
def prepare_gen_context(self, trace: Trace) -> None: ...
|
||||
def prepare_context(self, trace: Trace) -> Tuple[dict, bool]: ...
|
||||
|
||||
@abstractmethod
|
||||
def gen_response_to_hypothesis_list(self, response: str) -> FactorHypothesis: ...
|
||||
def convert_response(self, response: str) -> FactorHypothesis: ...
|
||||
|
||||
def gen(self, trace: Trace) -> FactorHypothesis:
|
||||
assert self.gen_context_flag, "Please call prepare_gen_context before calling gen."
|
||||
self.gen_context_flag = False # reset the flag
|
||||
context_dict, json_flag = self.prepare_context(trace)
|
||||
|
||||
system_prompt = (
|
||||
Environment(undefined=StrictUndefined)
|
||||
.from_string(prompt_dict["factor_hypothesis_gen"]["system_prompt"])
|
||||
.render(scenario=self.scen.get_scenario_all_desc())
|
||||
.render(
|
||||
scenario=self.scen.get_scenario_all_desc(),
|
||||
hypothesis_output_format=context_dict["hypothesis_output_format"],
|
||||
)
|
||||
)
|
||||
user_prompt = (
|
||||
Environment(undefined=StrictUndefined)
|
||||
.from_string(prompt_dict["factor_hypothesis_gen"]["user_prompt"])
|
||||
.render(self.gen_context_dict)
|
||||
.render(
|
||||
hypothesis_and_feedback=context_dict["hypothesis_and_feedback"],
|
||||
RAG=context_dict["RAG"],
|
||||
)
|
||||
)
|
||||
|
||||
resp = APIBackend().build_messages_and_create_chat_completion(
|
||||
user_prompt, system_prompt, json_mode=self.gen_json_flag
|
||||
)
|
||||
resp = APIBackend().build_messages_and_create_chat_completion(user_prompt, system_prompt, json_mode=json_flag)
|
||||
|
||||
hypothesis = self.gen_response_to_hypothesis_list(resp)
|
||||
hypothesis = self.convert_response(resp)
|
||||
|
||||
return hypothesis
|
||||
|
||||
|
||||
class FactorHypothesis2Task(Hypothesis2Task):
|
||||
def convert(self, bs: FactorHypothesis) -> None: ...
|
||||
class FactorHypothesis2Experiment(Hypothesis2Experiment[FactorExperiment]):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
|
||||
@abstractmethod
|
||||
def prepare_context(self, hs: HypothesisSet) -> Tuple[dict, bool]: ...
|
||||
|
||||
@abstractmethod
|
||||
def convert_response(self, response: str) -> FactorExperiment: ...
|
||||
|
||||
def convert(self, hs: HypothesisSet) -> FactorExperiment:
|
||||
context, json_flag = self.prepare_context(hs)
|
||||
system_prompt = (
|
||||
Environment(undefined=StrictUndefined)
|
||||
.from_string(prompt_dict["factor_hypothesis2experiment"]["system_prompt"])
|
||||
.render(
|
||||
scenario=hs.trace.scen.get_scenario_all_desc(),
|
||||
experiment_output_format=context["experiment_output_format"],
|
||||
)
|
||||
)
|
||||
user_prompt = (
|
||||
Environment(undefined=StrictUndefined)
|
||||
.from_string(prompt_dict["factor_hypothesis2experiment"]["user_prompt"])
|
||||
.render(
|
||||
hypothesis_and_feedback=context["hypothesis_and_feedback"],
|
||||
factor_list=context["factor_list"],
|
||||
RAG=context["RAG"],
|
||||
)
|
||||
)
|
||||
|
||||
resp = APIBackend().build_messages_and_create_chat_completion(user_prompt, system_prompt, json_mode=json_flag)
|
||||
|
||||
return self.convert_response(resp)
|
||||
|
||||
@@ -3,20 +3,36 @@ factor_hypothesis_gen:
|
||||
The user is trying to generate new hypothesis on the factors in data-driven research and development.
|
||||
The factors are used in a certain scenario, the scenario is as follows:
|
||||
{{ scenario }}
|
||||
The user has made several hypothesis on this sencario and did several evaluation on them. The user will provide this information to you.
|
||||
The user has made several hypothesis on this scenario and did several evaluation on them. The user will provide this information to you.
|
||||
To help you generate new hypothesis, the user has prepared some additional information for you. You should use this information to help generate new factors.
|
||||
Please generate the output following the format below:
|
||||
{{ hypothesis_output_format }}
|
||||
user_prompt: |-
|
||||
The user has made several hypothesis on this sencario and did several evaluation on them.
|
||||
The user has made several hypothesis on this scenario and did several evaluation on them.
|
||||
The former hypothesis and the corresponding feedbacks are as follows:
|
||||
{{ hypothesis_and_feedback }}
|
||||
To help you generate new factors, we have prepared the following information for you:
|
||||
{{ RAG }}
|
||||
Please generate the new hypothesis based on the information above and generate the output following the format below:
|
||||
{{ factor_output_format }}
|
||||
Please generate the new hypothesis based on the information above.
|
||||
|
||||
factor_hypothesis_to_tasks:
|
||||
factor_hypothesis2experiment:
|
||||
system_prompt: |-
|
||||
The user is trying to generate new factors based on the hypothesis generated in the previous step.
|
||||
The factors are used in certain scenario, the scenario is as follows:
|
||||
{{ scenario }}
|
||||
|
||||
The user will use the factors generated to do some experiments. The user will provide this information to you:
|
||||
1. The hypothesis generated in the previous steps and their corresponding feedbacks.
|
||||
2. Former proposed factors on similar hypothesis.
|
||||
3. Some additional information to help you generate new factors.
|
||||
Please generate the output following the format below:
|
||||
{{ experiment_output_format }}
|
||||
|
||||
user_prompt: |-
|
||||
The user has made several hypothesis on this scenario and did several evaluation on them.
|
||||
The former hypothesis and the corresponding feedbacks are as follows:
|
||||
{{ hypothesis_and_feedback }}
|
||||
The former proposed factors on similar hypothesis are as follows:
|
||||
{{ factor_list }}
|
||||
To help you generate new factors, we have prepared the following information for you:
|
||||
{{ RAG }}
|
||||
Please generate the new factors based on the information above.
|
||||
+1
-1
@@ -7,7 +7,7 @@ from rdagent.core.evolving_framework import EvolvableSubjects
|
||||
from rdagent.core.log import RDAgentLog
|
||||
|
||||
|
||||
class FactorEvolvingItem(FactorExperiment[FactorTask, FileBasedFactorImplementation], EvolvableSubjects):
|
||||
class FactorEvolvingItem(FactorExperiment, EvolvableSubjects):
|
||||
"""
|
||||
Intermediate item of factor implementation.
|
||||
"""
|
||||
|
||||
@@ -220,4 +220,4 @@ class FileBasedFactorImplementation(FBImplementation):
|
||||
return FileBasedFactorImplementation(task, code=code, **kwargs)
|
||||
|
||||
|
||||
FactorExperiment = Experiment
|
||||
class FactorExperiment(Experiment[FactorTask, FileBasedFactorImplementation]): ...
|
||||
|
||||
@@ -119,7 +119,7 @@ class Experiment(ABC, Generic[ASpecificTask, ASpecificImp]):
|
||||
The experiment is a sequence of tasks and the implementations of the tasks after generated by the TaskGenerator.
|
||||
"""
|
||||
|
||||
def __init__(self, sub_tasks: Sequence[Task]) -> None:
|
||||
def __init__(self, sub_tasks: Sequence[ASpecificTask]) -> None:
|
||||
self.sub_tasks = sub_tasks
|
||||
self.sub_implementations: Sequence[ASpecificImp] = [None for _ in self.sub_tasks]
|
||||
|
||||
|
||||
+42
-17
@@ -2,7 +2,8 @@
|
||||
|
||||
"""
|
||||
|
||||
from typing import Dict, List, Tuple
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Dict, Generic, List, Tuple, TypeVar
|
||||
|
||||
from rdagent.core.evolving_framework import Feedback
|
||||
from rdagent.core.experiment import Experiment, Implementation, Loader, Task
|
||||
@@ -18,8 +19,9 @@ class Hypothesis:
|
||||
- Belief
|
||||
"""
|
||||
|
||||
hypothesis: str = None
|
||||
reason: str = None
|
||||
def __init__(self, hypothesis: str, reason: str) -> None:
|
||||
self.hypothesis: str = hypothesis
|
||||
self.reason: str = reason
|
||||
|
||||
# source: data_ana | model_nan = None
|
||||
|
||||
@@ -27,16 +29,29 @@ class Hypothesis:
|
||||
# Origin(path of repo/data/feedback) => view/summarization => generated Hypothesis
|
||||
|
||||
|
||||
class Scenario:
|
||||
def get_repo_path(self):
|
||||
"""codebase"""
|
||||
class Scenario(ABC):
|
||||
|
||||
def get_data(self):
|
||||
""" "data info"""
|
||||
@property
|
||||
@abstractmethod
|
||||
def background(self):
|
||||
"""Background information"""
|
||||
|
||||
def get_env(self):
|
||||
"""env description"""
|
||||
@property
|
||||
@abstractmethod
|
||||
def source_data(self):
|
||||
"""Source data description"""
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def interface(self):
|
||||
"""Interface description about how to run the code"""
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def simulator(self):
|
||||
"""Simulator description"""
|
||||
|
||||
@abstractmethod
|
||||
def get_scenario_all_desc(self) -> str:
|
||||
"""Combine all the description together"""
|
||||
|
||||
@@ -44,9 +59,13 @@ class Scenario:
|
||||
class HypothesisFeedback(Feedback): ...
|
||||
|
||||
|
||||
class Trace:
|
||||
scen: Scenario
|
||||
hist: list[Tuple[Hypothesis, Experiment, HypothesisFeedback]]
|
||||
ASpecificScen = TypeVar("ASpecificScen", bound=Scenario)
|
||||
|
||||
|
||||
class Trace(Generic[ASpecificScen]):
|
||||
def __init__(self, scen: ASpecificScen) -> None:
|
||||
self.scen: ASpecificScen = scen
|
||||
self.hist: list[Tuple[Hypothesis, Experiment, HypothesisFeedback]] = []
|
||||
|
||||
|
||||
class HypothesisGen:
|
||||
@@ -74,16 +93,21 @@ class HypothesisSet:
|
||||
true_hypothesis or false_hypothesis
|
||||
"""
|
||||
|
||||
hypothesis_list: list[Hypothesis]
|
||||
trace: Trace
|
||||
def __init__(self, trace: Trace, hypothesis_list: list[Hypothesis] = []) -> None:
|
||||
self.hypothesis_list: list[Hypothesis] = hypothesis_list
|
||||
self.trace: Trace = trace
|
||||
|
||||
|
||||
class Hypothesis2Experiment(Loader[Experiment]):
|
||||
ASpecificExp = TypeVar("ASpecificExp", bound=Experiment)
|
||||
|
||||
|
||||
class Hypothesis2Experiment(ABC, Generic[ASpecificExp]):
|
||||
"""
|
||||
[Abstract description => concrete description] => Code implement
|
||||
"""
|
||||
|
||||
def convert(self, bs: HypothesisSet) -> Experiment:
|
||||
@abstractmethod
|
||||
def convert(self, hs: HypothesisSet) -> ASpecificExp:
|
||||
"""Connect the idea proposal to implementation"""
|
||||
...
|
||||
|
||||
@@ -99,3 +123,4 @@ class Experiment2Feedback:
|
||||
The `ti` should be executed and the results should be included.
|
||||
For example: `mlflow` of Qlib will be included.
|
||||
"""
|
||||
return HypothesisFeedback()
|
||||
|
||||
@@ -1,5 +1,43 @@
|
||||
from pathlib import Path
|
||||
|
||||
from rdagent.components.task_implementation.factor_implementation.factor import (
|
||||
FactorExperiment,
|
||||
)
|
||||
from rdagent.components.task_implementation.factor_implementation.utils import (
|
||||
get_data_folder_intro,
|
||||
)
|
||||
from rdagent.core.prompts import Prompts
|
||||
from rdagent.core.proposal import Scenario
|
||||
|
||||
prompt_dict = Prompts(file_path=Path(__file__).parent / "prompts.yaml")
|
||||
|
||||
QlibFactorExperiment = FactorExperiment
|
||||
|
||||
|
||||
class QlibFactorScenario(Scenario):
|
||||
@property
|
||||
def background(self) -> str:
|
||||
return prompt_dict["qlib_factor_background"]
|
||||
|
||||
@property
|
||||
def source_data(self) -> str:
|
||||
return get_data_folder_intro()
|
||||
|
||||
@property
|
||||
def interface(self) -> str:
|
||||
return prompt_dict["qlib_factor_interface"]
|
||||
|
||||
@property
|
||||
def simulator(self) -> str:
|
||||
return prompt_dict["qlib_factor_simulator"]
|
||||
|
||||
def get_scenario_all_desc(self) -> str:
|
||||
return f"""Background of the scenario:
|
||||
{self.background}
|
||||
The source data you can use:
|
||||
{self.source_data}
|
||||
The interface you should follow to write the runnable code:
|
||||
{self.interface}
|
||||
The simulator user can use to test your factor:
|
||||
{self.simulator}
|
||||
"""
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
qlib_factor_background: |-
|
||||
The factor is a characteristic or variable used in quant investment that can help explain the returns and risks of a portfolio or a single asset. Factors are used by investors to identify and exploit sources of excess returns, and they are central to many quantitative investment strategies.
|
||||
Each number in the factor represents a physics value to an instrument on a day.
|
||||
User will train a model to predict the next several days return based on the factor values of the previous days.
|
||||
The factor is defined in the following parts:
|
||||
1. Name: The name of the factor.
|
||||
2. Description: The description of the factor.
|
||||
3. Formulation: The formulation of the factor.
|
||||
4. Variables: The variables or functions used in the formulation of the factor.
|
||||
The factor might not provide all the parts of the information above since some might not be applicable.
|
||||
Please specifically give all the hyperparameter in the factors like the window size, look back period, and so on. One factor should statically defines one output with a static source data. For example, last 10 days momentum and last 20 days momentum should be two different factors.
|
||||
|
||||
qlib_factor_interface: |-
|
||||
Your code should follow the interface to better interact with the user's system.
|
||||
Your code should contain the following part: the import part, the function part, and the main part. You should write a main function name: "calculate_{function_name}" and call this function in "if __name__ == __main__" part. Don't write any try-except block in your code. The user will catch the exception message and provide the feedback to you.
|
||||
User will write your code into a python file and execute the file directly with "python {your_file_name}.py". You should calculate the factor values and save the result into a HDF5(H5) file named "result.h5" in the same directory as your python file. The result file is a HDF5(H5) file containing a pandas dataframe. The index of the dataframe is the "datetime" and "instrument", and the single column name is the factor name,and the value is the factor value. The result file should be saved in the same directory as your python file.
|
||||
|
||||
qlib_factor_simulator: |-
|
||||
The factors will be sent into Qlib to train a model to predict the next several days return based on the factor values of the previous days.
|
||||
Qlib is an AI-oriented quantitative investment platform that aims to realize the potential, empower research, and create value using AI technologies in quantitative investment, from exploring ideas to implementing productions. Qlib supports diverse machine learning modeling paradigms. including supervised learning, market dynamics modeling, and RL.
|
||||
User will use Qlib to automatically do the following things:
|
||||
1. generate a new factor table based on the factor values.
|
||||
2. train a model like LightGBM, CatBoost, LSTM or simple PyTorch model to predict the next several days return based on the factor values.
|
||||
3. build a portfolio based on the predicted return based on a strategy.
|
||||
4. evaluate the portfolio's performance including the return, sharpe ratio, max drawdown, and so on.
|
||||
@@ -1,40 +0,0 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from jinja2 import Environment, StrictUndefined
|
||||
|
||||
from rdagent.components.idea_proposal.factor_proposal import (
|
||||
FactorHypothesis,
|
||||
FactorHypothesisGen,
|
||||
)
|
||||
from rdagent.core.prompts import Prompts
|
||||
from rdagent.core.proposal import Scenario, Trace
|
||||
|
||||
prompt_dict = Prompts(file_path=Path(__file__).parent / "prompts.yaml")
|
||||
|
||||
QlibFactorHypothesis = FactorHypothesis
|
||||
|
||||
|
||||
class QlibFactorHypothesisGen(FactorHypothesisGen):
|
||||
def __init__(self, scen: Scenario):
|
||||
super().__init__(scen)
|
||||
self.gen_json_flag = True
|
||||
|
||||
def prepare_gen_context(self, trace: Trace) -> None:
|
||||
self.gen_context_flag = True
|
||||
|
||||
hypothesis_feedback = (
|
||||
Environment(undefined=StrictUndefined)
|
||||
.from_string(prompt_dict["hypothesis_and_feedback"])
|
||||
.render(trace=trace)
|
||||
)
|
||||
self.gen_context_dict = {
|
||||
"hypothesis_and_feedback": hypothesis_feedback,
|
||||
"RAG": ...,
|
||||
"factor_output_format": prompt_dict["output_format"],
|
||||
}
|
||||
|
||||
def gen_response_to_hypothesis_list(self, response: str) -> FactorHypothesis:
|
||||
response_dict = json.loads(response)
|
||||
hypothesis = QlibFactorHypothesis(hypothesis=response_dict["hypothesis"], reason=response_dict["reason"])
|
||||
return hypothesis
|
||||
@@ -0,0 +1,83 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import List, Tuple
|
||||
|
||||
from jinja2 import Environment, StrictUndefined
|
||||
|
||||
from rdagent.components.idea_proposal.factor_proposal import (
|
||||
FactorHypothesis,
|
||||
FactorHypothesis2Experiment,
|
||||
FactorHypothesisGen,
|
||||
)
|
||||
from rdagent.components.task_implementation.factor_implementation.factor import (
|
||||
FactorExperiment,
|
||||
FactorTask,
|
||||
)
|
||||
from rdagent.components.task_implementation.factor_implementation.utils import (
|
||||
get_data_folder_intro,
|
||||
)
|
||||
from rdagent.core.prompts import Prompts
|
||||
from rdagent.core.proposal import HypothesisSet, Scenario, Trace
|
||||
|
||||
prompt_dict = Prompts(file_path=Path(__file__).parent / "prompts.yaml")
|
||||
|
||||
QlibFactorHypothesis = FactorHypothesis
|
||||
|
||||
|
||||
class QlibFactorHypothesisGen(FactorHypothesisGen):
|
||||
def __init__(self, scen: Scenario) -> Tuple[dict, bool]:
|
||||
super().__init__(scen)
|
||||
|
||||
def prepare_context(self, trace: Trace) -> None:
|
||||
hypothesis_feedback = (
|
||||
Environment(undefined=StrictUndefined)
|
||||
.from_string(prompt_dict["hypothesis_and_feedback"])
|
||||
.render(trace=trace)
|
||||
)
|
||||
context_dict = {
|
||||
"hypothesis_and_feedback": hypothesis_feedback,
|
||||
"RAG": ...,
|
||||
"hypothesis_output_format": prompt_dict["hypothesis_output_format"],
|
||||
}
|
||||
return context_dict, True
|
||||
|
||||
def convert_response(self, response: str) -> FactorHypothesis:
|
||||
response_dict = json.loads(response)
|
||||
hypothesis = QlibFactorHypothesis(hypothesis=response_dict["hypothesis"], reason=response_dict["reason"])
|
||||
return hypothesis
|
||||
|
||||
|
||||
class QlibFactorHypothesis2Experiment(FactorHypothesis2Experiment):
|
||||
def prepare_context(self, hs: HypothesisSet) -> Tuple[dict | bool]:
|
||||
scenario = hs.trace.scen.get_scenario_all_desc()
|
||||
experiment_output_format = prompt_dict["experiment_output_format"]
|
||||
|
||||
hypothesis_and_feedback = (
|
||||
Environment(undefined=StrictUndefined)
|
||||
.from_string(prompt_dict["hypothesis_and_feedback"])
|
||||
.render(trace=hs.trace)
|
||||
)
|
||||
|
||||
experiment_list: List[FactorExperiment] = [t[1] for t in hs.trace.hist]
|
||||
|
||||
factor_list = []
|
||||
for experiment in experiment_list:
|
||||
factor_list.extend(experiment.sub_tasks)
|
||||
|
||||
return {
|
||||
"scenario": scenario,
|
||||
"hypothesis_and_feedback": hypothesis_and_feedback,
|
||||
"experiment_output_format": experiment_output_format,
|
||||
"factor_list": factor_list,
|
||||
"RAG": ...,
|
||||
}, True
|
||||
|
||||
def convert_response(self, response: str) -> FactorExperiment:
|
||||
response_dict = json.loads(response)
|
||||
tasks = []
|
||||
for factor_name in response_dict:
|
||||
description = response_dict[factor_name]["description"]
|
||||
formulation = response_dict[factor_name]["formulation"]
|
||||
variables = response_dict[factor_name]["variables"]
|
||||
tasks.append(FactorTask(factor_name, description, formulation, variables))
|
||||
return FactorExperiment(tasks)
|
||||
@@ -1,12 +1,34 @@
|
||||
hypothesis_and_feedback: |-
|
||||
{% for hypothesis, feedback in trace %}
|
||||
{% for hypothesis, experiment, feedback in trace.hist %}
|
||||
Hypothesis {{ loop.index }}: {{ hypothesis }}
|
||||
Feedback: {{ feedback }}
|
||||
{% endfor %}
|
||||
|
||||
output_format: |-
|
||||
hypothesis_output_format: |-
|
||||
The output should follow JSON format. The schema is as follows:
|
||||
{
|
||||
"hypothesis": "The new hypothesis generated based on the information provided.",
|
||||
"reason": "The reason why you generate this hypothesis."
|
||||
}
|
||||
}
|
||||
|
||||
experiment_output_format: |-
|
||||
The output should follow JSON format. The schema is as follows:
|
||||
{
|
||||
"factor name 1": {
|
||||
"description": "description of factor 1",
|
||||
"formulation": "latex formulation of factor 1",
|
||||
"variables": {
|
||||
"variable or function name 1": "description of variable or function 1",
|
||||
"variable or function name 2": "description of variable or function 2"
|
||||
}
|
||||
},
|
||||
"factor name 2": {
|
||||
"description": "description of factor 1",
|
||||
"formulation": "latex formulation of factor 2",
|
||||
"variables": {
|
||||
"variable or function name 1": "description of variable or function 1",
|
||||
"variable or function name 2": "description of variable or function 2"
|
||||
}
|
||||
}
|
||||
# Don't add ellipsis (...) or any filler text that might cause JSON parsing errors here!
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ from rdagent.core.task_generator import TaskGenerator
|
||||
from rdagent.scenarios.qlib.experiment.factor_experiment import QlibFactorExperiment
|
||||
|
||||
|
||||
class QlibDataImplementation(TaskGenerator[QlibFactorExperiment]):
|
||||
class QlibFactorRunner(TaskGenerator[QlibFactorExperiment]):
|
||||
"""
|
||||
Docker run
|
||||
Everything in a folder
|
||||
@@ -13,3 +13,6 @@ class QlibDataImplementation(TaskGenerator[QlibFactorExperiment]):
|
||||
|
||||
- TODO: implement a qlib handler
|
||||
"""
|
||||
|
||||
def generate(self, exp: QlibFactorExperiment) -> QlibFactorExperiment:
|
||||
return exp # TODO IMPLEMENT THIS
|
||||
|
||||
@@ -1,2 +1,7 @@
|
||||
# TODO:
|
||||
# Implement to feedback.
|
||||
|
||||
from rdagent.core.proposal import Experiment2Feedback
|
||||
|
||||
|
||||
class QlibFactorExperiment2Feedback(Experiment2Feedback): ...
|
||||
|
||||
Reference in New Issue
Block a user