mirror of
https://github.com/microsoft/qlib.git
synced 2026-07-03 02:50:58 +08:00
Initial interface for discussion
This commit is contained in:
0
qlib/finco/__init__.py
Normal file
0
qlib/finco/__init__.py
Normal file
11
qlib/finco/cli.py
Normal file
11
qlib/finco/cli.py
Normal file
@@ -0,0 +1,11 @@
|
||||
import fire
|
||||
from qlib.finco.task import WorkflowManager
|
||||
|
||||
|
||||
def main(prompt):
|
||||
wm = WorkflowManager()
|
||||
wm.run(prompt)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fire.Fire(main)
|
||||
8
qlib/finco/conf.py
Normal file
8
qlib/finco/conf.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# TODO: use pydantic for other modules in Qlib
|
||||
from pydantic import BaseSettings
|
||||
|
||||
|
||||
class Conf(BaseSettings):
|
||||
"""module specific settings."""
|
||||
|
||||
...
|
||||
14
qlib/finco/llm.py
Normal file
14
qlib/finco/llm.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import openai
|
||||
|
||||
|
||||
def example():
|
||||
response = openai.ChatCompletion.create(
|
||||
engine="gpt-35-turbo", # The deployment name you chose when you deployed the ChatGPT or GPT-4 model.
|
||||
# engine="gpt-4", # NOTE: this raises this error: openai.error.RateLimitError: Requests to the Creates a completion for the chat message Operation under Azure OpenAI API version 2023-05-15 have exceeded call rate limit of your current OpenAI S0 pricing tier
|
||||
# engine="gpt-4-32k", # This works for only;
|
||||
messages=[
|
||||
{"role": "system", "content": "Assistant is a large language model trained by OpenAI."},
|
||||
{"role": "user", "content": "Who were the founders of Microsoft?"},
|
||||
],
|
||||
)
|
||||
print(response)
|
||||
120
qlib/finco/task.py
Normal file
120
qlib/finco/task.py
Normal file
@@ -0,0 +1,120 @@
|
||||
from pathlib import Path
|
||||
from typing import Any, List
|
||||
from qlib.typehint import Literal
|
||||
|
||||
|
||||
class Task:
|
||||
"""
|
||||
The user's intention, which was initially represented by a prompt, is achieved through a sequence of tasks.
|
||||
|
||||
Some thoughts:
|
||||
- Do we have to split create a new concept of Action besides Task?
|
||||
- Most actions directly modify the disk, with their interfaces taking in and outputting text. The LLM's interface similarly takes in and outputs text.
|
||||
- Some actions will run some commands.
|
||||
|
||||
Maybe we can just categorizing tasks by following?
|
||||
- Planning task (it is at a high level and difficult to execute directly; therefore, it should be further divided):
|
||||
- Action Task
|
||||
- CMD Task: it is expected to run a cmd
|
||||
- Edit Task: it is supposed to edit the code base directly.
|
||||
"""
|
||||
|
||||
def __init__(self, context=None) -> None:
|
||||
pass
|
||||
|
||||
def summarize(self) -> str:
|
||||
"""After the execution of the task, it is supposed to generated some context about the execution"""
|
||||
return ""
|
||||
|
||||
def update_context(self, latest_context):
|
||||
...
|
||||
|
||||
def execution(self) -> Any:
|
||||
"""The execution results of the task"""
|
||||
pass
|
||||
|
||||
|
||||
class PlanTask(Task):
|
||||
def execute(self) -> List[Task]:
|
||||
return []
|
||||
|
||||
|
||||
class WorkflowTask(PlanTask):
|
||||
"""make the choice which main workflow (RL, SL) will be used"""
|
||||
|
||||
def execute(self):
|
||||
...
|
||||
|
||||
|
||||
class SLTask(PlanTask):
|
||||
def exeute(self):
|
||||
"""
|
||||
return a list of interested tasks
|
||||
Copy the template project maybe a part of the task
|
||||
"""
|
||||
return []
|
||||
|
||||
|
||||
class ActionTask(Task):
|
||||
def execute(self) -> Literal["fail", "success"]:
|
||||
return "success"
|
||||
|
||||
|
||||
class WorkflowManager:
|
||||
"""This manange the whole task automation workflow including tasks and actions"""
|
||||
|
||||
def __init__(self, name="project", output_path=None) -> None:
|
||||
|
||||
if output_path is None:
|
||||
self._output_path = Path.cwd() / name
|
||||
else:
|
||||
self._output_path = Path(output_path)
|
||||
self._context = []
|
||||
|
||||
def add_context(self, task_res):
|
||||
self._context.append(task_res)
|
||||
|
||||
def get_context(self):
|
||||
"""TODO: context manger?"""
|
||||
|
||||
def run(self, prompt: str) -> Path:
|
||||
"""
|
||||
The workflow manager is supposed to generate a codebase based on the prompt
|
||||
|
||||
Parameters
|
||||
----------
|
||||
prompt: str
|
||||
the prompt user gives
|
||||
|
||||
Returns
|
||||
-------
|
||||
Path
|
||||
The workflow manager is expected to produce output that includes a codebase containing generated code, results, and reports in a designated location.
|
||||
The path is returned
|
||||
|
||||
The output path should follow a specific format:
|
||||
- TODO: design
|
||||
There is a summarized report where user can start from.
|
||||
"""
|
||||
|
||||
# NOTE: The following items are not designed to make the workflow very flexible.
|
||||
# - The generated tasks can't be changed after geting new information from the execution retuls.
|
||||
# - But it is required in some cases, if we want to build a external dataset, it maybe have to plan like autogpt...
|
||||
|
||||
# NOTE: list may not be enough for general task list
|
||||
task_list = [WorkflowTask(prompt)]
|
||||
while len(task_list):
|
||||
# task_list.ap
|
||||
t = task_list.pop(0)
|
||||
t.update_context(self.get_context())
|
||||
res = t.execute()
|
||||
if isinstance(t, PlanTask):
|
||||
task_list.extend(res)
|
||||
elif isinstance(t, ActionTask):
|
||||
if res != "success":
|
||||
...
|
||||
# TODO: handle the unexpected execution Error
|
||||
else:
|
||||
raise NotImplementedError("Unsupported action type")
|
||||
self.add_context(t.summarize())
|
||||
return self._output_path
|
||||
6
qlib/finco/tpls/README.md
Normal file
6
qlib/finco/tpls/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
This is a set of templates that should be copied for a new project.
|
||||
|
||||
|
||||
|
||||
# TODO
|
||||
- [ ] [Copier](https://copier.readthedocs.io/en/stable/#quick-start) may be useful if the generation process becomes complicated
|
||||
72
qlib/finco/tpls/sl/workflow_config.yaml
Normal file
72
qlib/finco/tpls/sl/workflow_config.yaml
Normal file
@@ -0,0 +1,72 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &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
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: LGBModel
|
||||
module_path: qlib.contrib.model.gbdt
|
||||
kwargs:
|
||||
loss: mse
|
||||
colsample_bytree: 0.8879
|
||||
learning_rate: 0.2
|
||||
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]
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
14
scripts/finco/README.md
Normal file
14
scripts/finco/README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
|
||||
# Requirements
|
||||
|
||||
```
|
||||
pydantic
|
||||
openai
|
||||
```
|
||||
|
||||
|
||||
# TODOs
|
||||
|
||||
- [ ] Select the appropriate LLM API
|
||||
- Which API is more suitable for meeting our requirements - the original API or an alternative like LangChain?
|
||||
15
scripts/finco/cmd.sh
Normal file
15
scripts/finco/cmd.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
set -x # show command
|
||||
set -e # Error on exception
|
||||
|
||||
DIR="$(
|
||||
cd "$(dirname "$(readlink -f "$0")")" || exit
|
||||
pwd -P
|
||||
)"
|
||||
# --load the cridentials
|
||||
if [ -e $DIR/cridential.sh ]; then
|
||||
source $DIR/cridential.sh
|
||||
fi
|
||||
|
||||
# run the command
|
||||
python -m qlib.finco.cli "please help me build a low turnover strategy that focus more on longterm return"
|
||||
3
scripts/finco/cridential.sh.example
Normal file
3
scripts/finco/cridential.sh.example
Normal file
@@ -0,0 +1,3 @@
|
||||
export OPENAI_API_TYPE=azure # This only necessary for Azure OpenAI
|
||||
export OPENAI_API_KEY=
|
||||
export OPENAI_API_BASE=
|
||||
Reference in New Issue
Block a user