-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhyperparam_search.py
More file actions
130 lines (103 loc) · 5.03 KB
/
hyperparam_search.py
File metadata and controls
130 lines (103 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
""" examples/hyperparam_search.py
An example of how to use the hyperparameter search functionality of Tradeforce.
Technically, the hyperparameter search could include any kind of configuration
option Tradeforce offers. However, the primariy use case is to optimize the
trade strategy parameters. The default buy / sell strategy implementations
offer following parameters:
- moving_window_hours: Timeframe for moving window to calulate the price signal scores.
- buy_signal_score: Price signal score within the moving window.
- buy_signal_boundary: Range of acceptable 'buy_signal_score's as buy signals.
- buy_signal_preference: Preference for positive, negative, or closest to buy_signal_score.
- profit_factor_target: Target profit factor to sell assets. e.g. 1.10 = 10% profit.
- amount_invest_per_asset: Amount of base_currency to invest per asset.
- hold_time_days: Number of days to hold an asset before reducing to profit_factor_target_min.
- profit_factor_target_min: Minimum profit factor to sell assets. e.g. 1.01 = 1% profit.
Tradeforce accepts some basic functionality of Optuna. It is mapped to the 'optuna_config' dict.
Which contains two keys: 'config' and 'search_params'.
The 'config' key defines the Optuna configuration options:
- study_name: Name of the Optuna study. It identifies the current
optimization process.
- n_trials: Number of trials to run. A trial is a single run of the
optimization function.
- direction: Direction of the optimization. Either 'minimize' or 'maximize'.
We want to maximize the profit score.
- load_if_exists: If True, the study will be loaded from the storage
if it exists. Otherwise, a new study will be created.
- sampler: Sampler to use for the study. Either 'TPESampler',
'RandomSampler' or 'BruteForceSampler'.
- pruner: Pruner to use for the study. Either 'HyperbandPruner' or 'MedianPruner'.
The 'search_params' key defines the search space for the optimization:
For example "moving_window_hours": {"min": 10, "max": 1000, "step": 10}
searches for the optimal int between 10 and 1000 in steps of 10.
To search for continous values, use floats:
For example "profit_factor_target": {"min": 1.05, "max": 2.5, "step": 0.05}
Note that only float and int values are currently supported because the values
need to be converted to floats for ease of use in combination
with Numba JIT compilation.
To utilize the full functionality of Optuna, for example many more samplers and pruners,
you can pass an Optuna instance instead of optuna_config["config"]:
The Study object can be passed as 'optuna_study' to run_sim_optuna().
The search space still needs to be declared in optuna_config["search_params"].
See the Optuna documentation for more information: https://optuna.readthedocs.io/en/stable/
See README.md for more information about the Tradeforce configuration options.
"""
from tradeforce import Tradeforce
CONFIG = {
"market_history": {
"name": "bitfinex_history",
"exchange": "bitfinex",
"base_currency": "USD",
"candle_interval": "5min",
"fetch_init_timeframe_days": 100,
"update_mode": "none",
"force_source": "local_cache",
"check_db_consistency": False,
},
"backend": {
"dbms": "postgresql",
"dbms_host": "docker_db",
"dbms_port": 5433,
"dbms_connect_db": "postgres",
"dbms_user": "postgres",
"dbms_pw": "postgres",
"local_cache": True,
"check_db_sync": False,
},
"trader": {
"budget": 1000,
"maker_fee": 0.10,
"taker_fee": 0.20,
},
"simulation": {
"subset_size_days": 30,
"subset_amount": 10,
"train_val_split_ratio": 0.8,
},
}
HYPERPARAM_SEARCH = {
"config": {
"study_name": "test_study",
"n_trials": 100,
"direction": "maximize",
"load_if_exists": True,
"sampler": "TPESampler",
"pruner": "HyperbandPruner",
},
"search_params": {
"amount_invest_per_asset": {"min": 50, "max": 250, "step": 50},
"moving_window_hours": {"min": 10, "max": 1000, "step": 10},
"buy_signal_score": {"min": -0.05, "max": 0.25, "step": 0.05},
"buy_signal_boundary": {"min": 0.0, "max": 0.15, "step": 0.05},
"buy_signal_preference": {"min": -1, "max": 1, "step": 1},
"profit_factor_target": {"min": 1.05, "max": 2.5, "step": 0.05},
"hold_time_days": {"min": 1, "max": 100, "step": 1},
"profit_factor_target_min": {"min": 0.85, "max": 1.1, "step": 0.05},
},
}
def main() -> None:
study = Tradeforce(CONFIG).run_sim_optuna(optuna_config=HYPERPARAM_SEARCH)
print("Results for study:", study.study_name)
print("Best value:", study.best_value)
print("Best parameters", study.best_params)
if __name__ == "__main__":
main()