Skip to content

Commit 9ab195d

Browse files
Split config
1 parent a9dabcd commit 9ab195d

File tree

4 files changed

+174
-306
lines changed

4 files changed

+174
-306
lines changed

config.py

Lines changed: 25 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
from __future__ import annotations
2-
from typing import List, Optional
2+
from typing import List, Optional, Union, Dict
33

44
import os
55
from pathlib import Path
66
import json
77
from enum import Enum
8-
from typing import Union
98

109
from pydantic import BaseModel, HttpUrl, ValidationError, validator, DirectoryPath
1110

@@ -17,12 +16,10 @@
1716
class Exchanges(Enum):
1817
BYBIT = "bybit"
1918

20-
2119
class Messengers(Enum):
2220
DISCORD = "discord"
2321
TELEGRAM = "telegram"
2422

25-
2623
class API(BaseModel):
2724
filename: str = "quantdatav2.json"
2825
mode: str = "remote"
@@ -36,7 +33,6 @@ class Hotkeys(BaseModel):
3633
enter_short: str = "3"
3734
take_profit_short: str = "4"
3835

39-
4036
class Bot(BaseModel):
4137
bot_name: str
4238
volume_check: bool = True
@@ -75,10 +71,8 @@ class Bot(BaseModel):
7571
whitelist: List[str] = []
7672
dashboard_enabled: bool = False
7773
shared_data_path: Optional[str] = None
78-
#risk_management: Optional[dict] = None
7974
linear_grid: Optional[dict] = None
8075
hotkeys: Hotkeys
81-
# shared_data_path: Optional[DirectoryPath] = None
8276

8377
@validator('hotkeys')
8478
def validate_hotkeys(cls, value):
@@ -211,13 +205,13 @@ def check_volume_check_is_bool(cls, v):
211205
if not isinstance(v, bool):
212206
raise ValueError("volume_check must be a boolean")
213207
return v
214-
208+
215209
class Exchange(BaseModel):
216210
name: str
217211
account_name: str
218212
api_key: str
219213
api_secret: str
220-
passphrase: str = None
214+
passphrase: Optional[str] = None
221215
symbols_allowed: int = 12
222216

223217
class Logger(BaseModel):
@@ -251,13 +245,12 @@ class Telegram(BaseModel):
251245
bot_token: str
252246
chat_id: str
253247

254-
255248
class Config(BaseModel):
256249
api: API
257250
bot: Bot
258-
exchanges: List[Exchange] # <-- Changed from List[Exchange]
251+
exchanges: List[Exchange]
259252
logger: Logger
260-
messengers: dict[str, Union[Discord, Telegram]]
253+
messengers: Dict[str, Union[Discord, Telegram]]
261254

262255
def resolve_shared_data_path(relative_path: str) -> Path:
263256
# Get the directory of the config file
@@ -271,47 +264,26 @@ def resolve_shared_data_path(relative_path: str) -> Path:
271264

272265
return absolute_path
273266

274-
def load_config(path):
275-
if not path.is_file():
276-
raise ValueError(f"{path} does not exist")
277-
else:
278-
with open(path) as f:
279-
try:
280-
data = json.load(f)
281-
except json.JSONDecodeError as exc:
282-
raise ValueError(
283-
f"ERROR: Invalid JSON: {exc.msg}, line {exc.lineno}, column {exc.colno}"
284-
)
285-
try:
286-
config_data = Config(**data)
287-
288-
# Resolve shared_data_path if it's provided
289-
if config_data.bot.shared_data_path:
290-
config_data.bot.shared_data_path = str(resolve_shared_data_path(config_data.bot.shared_data_path))
291-
292-
return config_data
293-
except ValidationError as e:
294-
# Enhanced error output
295-
error_details = "\n".join([f"{err['loc']} - {err['msg']}" for err in e.errors()])
296-
raise ValueError(f"Configuration Error(s):\n{error_details}")
297-
298-
# def load_config(path):
299-
# if not path.is_file():
300-
# raise ValueError(f"{path} does not exist")
301-
# else:
302-
# f = open(path)
303-
# try:
304-
# data = json.load(f)
305-
# except json.JSONDecodeError as exc:
306-
# raise ValueError(
307-
# f"ERROR: Invalid JSON: {exc.msg}, line {exc.lineno}, column {exc.colno}"
308-
# )
309-
# try:
310-
# return Config(**data)
311-
# except ValidationError as e:
312-
# # Enhancing the error output for better clarity
313-
# error_details = "\n".join([f"{err['loc']} - {err['msg']}" for err in e.errors()])
314-
# raise ValueError(f"Configuration Error(s):\n{error_details}")
267+
def load_json(file_path: Path) -> dict:
268+
with open(file_path, 'r') as file:
269+
return json.load(file)
270+
271+
def load_config(config_path: Path, account_path: Path) -> Config:
272+
config_data = load_json(config_path)
273+
account_data = load_json(account_path)
274+
275+
# Merge account data into config data
276+
for exchange in config_data['exchanges']:
277+
for account in account_data['exchanges']:
278+
if exchange['name'] == account['name'] and exchange['account_name'] == account['account_name']:
279+
exchange.update({
280+
'api_key': account['api_key'],
281+
'api_secret': account['api_secret'],
282+
'passphrase': account.get('passphrase', None)
283+
})
284+
break
285+
286+
return Config(**config_data)
315287

316288
def get_exchange_name(cli_exchange_name):
317289
if cli_exchange_name:
@@ -344,70 +316,3 @@ def get_exchange_credentials(exchange_name, account_name):
344316
return api_key, secret_key, passphrase, symbols_allowed
345317
else:
346318
raise ValueError(f"Account {account_name} for exchange {exchange_name} not found in the config file.")
347-
348-
# def get_exchange_credentials(exchange_name, account_name):
349-
# with open('config.json') as file:
350-
# data = json.load(file)
351-
# exchange_data = None
352-
# for exchange in data['exchanges']:
353-
# if exchange['name'] == exchange_name and exchange['account_name'] == account_name:
354-
# exchange_data = exchange
355-
# break
356-
# if exchange_data:
357-
# api_key = exchange_data['api_key']
358-
# secret_key = exchange_data['api_secret']
359-
# passphrase = exchange_data.get('passphrase')
360-
# symbols_allowed = exchange_data.get('symbols_allowed', 12) # Default to 12 if not specified
361-
# return api_key, secret_key, passphrase, symbols_allowed
362-
# else:
363-
# raise ValueError(f"Account {account_name} for exchange {exchange_name} not found in the config file.")
364-
365-
# def get_exchange_credentials(exchange_name, account_name):
366-
# with open('config.json') as file:
367-
# data = json.load(file)
368-
# exchange_data = None
369-
# for exchange in data['exchanges']:
370-
# if exchange['name'] == exchange_name and exchange['account_name'] == account_name:
371-
# exchange_data = exchange
372-
# break
373-
# if exchange_data:
374-
# api_key = exchange_data['api_key']
375-
# secret_key = exchange_data['api_secret']
376-
# passphrase = exchange_data.get('passphrase') # Not all exchanges require a passphrase
377-
# return api_key, secret_key, passphrase
378-
# else:
379-
# raise ValueError(f"Account {account_name} for exchange {exchange_name} not found in the config file.")
380-
381-
# def get_exchange_credentials(exchange_name):
382-
# with open('config.json') as file:
383-
# data = json.load(file)
384-
# exchange_data = None
385-
# for exchange in data['exchanges']:
386-
# if exchange['name'] == exchange_name:
387-
# exchange_data = exchange
388-
# break
389-
# if exchange_data:
390-
# api_key = exchange_data['api_key']
391-
# secret_key = exchange_data['api_secret']
392-
# passphrase = exchange_data.get('passphrase') # Not all exchanges require a passphrase
393-
# return api_key, secret_key, passphrase
394-
# else:
395-
# raise ValueError(f"Exchange {exchange_name} not found in the config file.")
396-
397-
398-
# def get_exchange_name(cli_exchange_name):
399-
# if cli_exchange_name:
400-
# return cli_exchange_name
401-
# else:
402-
# with open('config.json') as file:
403-
# data = json.load(file)
404-
# return data['exchange']
405-
406-
# def get_exchange_credentials(exchange_name):
407-
# with open('config.json') as file:
408-
# data = json.load(file)
409-
# exchange_data = data['exchanges'][exchange_name]
410-
# api_key = exchange_data['api_key']
411-
# secret_key = exchange_data['secret_key']
412-
# passphrase = exchange_data.get('passphrase') # Not all exchanges require a passphrase
413-
# return api_key, secret_key, passphrase

configs/account_example.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"exchanges": [
3+
{
4+
"name": "bybit",
5+
"account_name": "account_1",
6+
"api_key": "your_api_key",
7+
"api_secret": "your_api_secret"
8+
},
9+
{
10+
"name": "bybit_spot",
11+
"account_name": "account_2",
12+
"api_key": "your_api_key",
13+
"api_secret": "your_api_secret"
14+
},
15+
{
16+
"name": "bybit_unified",
17+
"account_name": "account_3",
18+
"api_key": "your_api_key",
19+
"api_secret": "your_api_secret"
20+
}
21+
]
22+
}

0 commit comments

Comments
 (0)