Skip to content

Commit ba21d98

Browse files
authored
Merge pull request #518 from luceCoding/performance-tweaks
Performance tweaks
2 parents c746934 + 4ba025e commit ba21d98

File tree

5 files changed

+118
-137
lines changed

5 files changed

+118
-137
lines changed

jesse/constants.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from jesse.enums import timeframes
2+
3+
4+
CANDLE_SOURCE_MAPPING = {
5+
"open": lambda c: c[:, 1],
6+
"close": lambda c: c[:, 2],
7+
"high": lambda c: c[:, 3],
8+
"low": lambda c: c[:, 4],
9+
"volume": lambda c: c[:, 5],
10+
"hl2": lambda c: (c[:, 3] + c[:, 4]) / 2,
11+
"hlc3": lambda c: (c[:, 3] + c[:, 4] + c[:, 2]) / 3,
12+
"ohlc4": lambda c: (c[:, 1] + c[:, 3] + c[:, 4] + c[:, 2]) / 4,
13+
}
14+
15+
16+
TIMEFRAME_PRIORITY = [
17+
timeframes.DAY_1,
18+
timeframes.HOUR_12,
19+
timeframes.HOUR_8,
20+
timeframes.HOUR_6,
21+
timeframes.HOUR_4,
22+
timeframes.HOUR_3,
23+
timeframes.HOUR_2,
24+
timeframes.HOUR_1,
25+
timeframes.MINUTE_45,
26+
timeframes.MINUTE_30,
27+
timeframes.MINUTE_15,
28+
timeframes.MINUTE_5,
29+
timeframes.MINUTE_3,
30+
timeframes.MINUTE_1,
31+
]
32+
33+
34+
TIMEFRAME_TO_ONE_MINUTES = {
35+
timeframes.MINUTE_1: 1,
36+
timeframes.MINUTE_3: 3,
37+
timeframes.MINUTE_5: 5,
38+
timeframes.MINUTE_15: 15,
39+
timeframes.MINUTE_30: 30,
40+
timeframes.MINUTE_45: 45,
41+
timeframes.HOUR_1: 60,
42+
timeframes.HOUR_2: 60 * 2,
43+
timeframes.HOUR_3: 60 * 3,
44+
timeframes.HOUR_4: 60 * 4,
45+
timeframes.HOUR_6: 60 * 6,
46+
timeframes.HOUR_8: 60 * 8,
47+
timeframes.HOUR_12: 60 * 12,
48+
timeframes.DAY_1: 60 * 24,
49+
timeframes.DAY_3: 60 * 24 * 3,
50+
timeframes.WEEK_1: 60 * 24 * 7,
51+
timeframes.MONTH_1: 60 * 24 * 30,
52+
}
53+
54+
55+
SUPPORTED_COLORS = {
56+
'black',
57+
'red',
58+
'green',
59+
'yellow',
60+
'blue',
61+
'magenta',
62+
'cyan',
63+
'white',
64+
#'gray',
65+
}

jesse/enums/__init__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1+
from dataclasses import dataclass
2+
3+
@dataclass
14
class sides:
25
BUY = 'buy'
36
SELL = 'sell'
47

58

9+
@dataclass
610
class trade_types:
711
LONG = 'long'
812
SHORT = 'short'
913

1014

15+
@dataclass
1116
class order_statuses:
1217
ACTIVE = 'ACTIVE'
1318
CANCELED = 'CANCELED'
@@ -18,6 +23,7 @@ class order_statuses:
1823
REJECTED = 'REJECTED'
1924

2025

26+
@dataclass
2127
class timeframes:
2228
MINUTE_1 = '1m'
2329
MINUTE_3 = '3m'
@@ -38,6 +44,7 @@ class timeframes:
3844
MONTH_1 = '1M'
3945

4046

47+
@dataclass
4148
class colors:
4249
GREEN = 'green'
4350
YELLOW = 'yellow'
@@ -46,6 +53,7 @@ class colors:
4653
BLACK = 'black'
4754

4855

56+
@dataclass
4957
class order_types:
5058
MARKET = 'MARKET'
5159
LIMIT = 'LIMIT'
@@ -54,6 +62,7 @@ class order_types:
5462
STOP_LIMIT = 'STOP LIMIT'
5563

5664

65+
@dataclass
5766
class exchanges:
5867
SANDBOX = 'Sandbox'
5968
COINBASE_SPOT = 'Coinbase Spot'
@@ -86,6 +95,7 @@ class exchanges:
8695
HYPERLIQUID_PERPETUAL_TESTNET = 'Hyperliquid Perpetual Testnet'
8796

8897

98+
@dataclass
8999
class migration_actions:
90100
ADD = 'add'
91101
DROP = 'drop'
@@ -97,6 +107,7 @@ class migration_actions:
97107
DROP_INDEX = 'drop_index'
98108

99109

110+
@dataclass
100111
class order_submitted_via:
101112
STOP_LOSS = 'stop-loss'
102113
TAKE_PROFIT = 'take-profit'

jesse/helpers.py

Lines changed: 31 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
import click
1515
import numpy as np
1616
import base64
17-
17+
from jesse.constants import CANDLE_SOURCE_MAPPING
18+
from jesse.constants import TIMEFRAME_PRIORITY
19+
from jesse.constants import SUPPORTED_COLORS
20+
from jesse.enums import timeframes
1821

1922
CACHED_CONFIG = dict()
2023

@@ -73,23 +76,10 @@ def color(msg_text: str, msg_color: str) -> str:
7376
if not msg_text:
7477
return ''
7578

76-
if msg_color == 'black':
77-
return click.style(msg_text, fg='black')
78-
if msg_color == 'red':
79-
return click.style(msg_text, fg='red')
80-
if msg_color == 'green':
81-
return click.style(msg_text, fg='green')
82-
if msg_color == 'yellow':
83-
return click.style(msg_text, fg='yellow')
84-
if msg_color == 'blue':
85-
return click.style(msg_text, fg='blue')
86-
if msg_color == 'magenta':
87-
return click.style(msg_text, fg='magenta')
88-
if msg_color == 'cyan':
89-
return click.style(msg_text, fg='cyan')
90-
if msg_color in {'white', 'gray'}:
79+
if msg_color in SUPPORTED_COLORS:
80+
return click.style(msg_text, fg=msg_color)
81+
if msg_color == 'gray':
9182
return click.style(msg_text, fg='white')
92-
9383
raise ValueError('unsupported color')
9484

9585

@@ -112,53 +102,27 @@ def dashless_symbol(symbol: str) -> str:
112102

113103

114104
def dashy_symbol(symbol: str) -> str:
115-
# if already has '-' in symbol, return symbol
116105
if '-' in symbol:
117106
return symbol
118107

119108
from jesse.config import config
120-
121109
for s in config['app']['considering_symbols']:
122-
compare_symbol = dashless_symbol(s)
123-
if compare_symbol == symbol:
110+
if dashless_symbol(s) == symbol:
124111
return s
125112

126-
if symbol.endswith('EUR'):
127-
return symbol[:-3] + '-EUR'
128-
if symbol.endswith('EUT'):
129-
return symbol[:-3] + '-EUT'
130-
if symbol.endswith('GBP'):
131-
return symbol[:-3] + '-GBP'
132-
if symbol.endswith('JPY'):
133-
return symbol[:-3] + '-JPY'
134-
if symbol.endswith('MIM'):
135-
return symbol[:-3] + '-MIM'
136-
if symbol.endswith('TRY'):
137-
return symbol[:-3] + '-TRY'
138-
if symbol.endswith('FDUSD'):
139-
return symbol[:-5] + '-FDUSD'
140-
if symbol.endswith('TUSD'):
141-
return symbol[:-4] + '-TUSD'
142-
if symbol.endswith('UST'):
143-
return symbol[:-3] + '-UST'
144-
if symbol.endswith('USDT'):
145-
return symbol[:-4] + '-USDT'
146-
if symbol.endswith('USDC'):
147-
return symbol[:-4] + '-USDC'
148-
if symbol.endswith('USDS'):
149-
return symbol[:-4] + '-USDS'
150-
if symbol.endswith('USDP'):
151-
return symbol[:-4] + '-USDP'
152-
if symbol.endswith('USDU'):
153-
return symbol[:-4] + '-USDU'
154-
if symbol.endswith('USD'):
155-
return symbol[:-3] + '-USD'
156-
157-
if len(symbol) > 7 and symbol.endswith('SUSDT'):
158-
# ex: SETHSUSDT => SETH-SUSDT
159-
return symbol[:-5] + '-' + symbol[-5:]
160-
161-
return f"{symbol[0:3]}-{symbol[3:]}"
113+
suffixes = [
114+
'FDUSD', 'TUSD', 'EUT', 'EUR', 'GBP', 'JPY', 'MIM', 'TRY', 'UST', 'SUSDT'
115+
]
116+
117+
for suffix in suffixes:
118+
if symbol.endswith(suffix):
119+
return f"{symbol[:-len(suffix)]}-{suffix}"
120+
121+
if "USD" in symbol[-4:]: # Only look at the last 4 letters
122+
idx = symbol.rfind("USD")
123+
return f"{symbol[:idx]}-{symbol[idx:]}"
124+
125+
return f"{symbol[:3]}-{symbol[3:]}"
162126

163127

164128
def underline_to_dashy_symbol(symbol: str) -> str:
@@ -315,31 +279,12 @@ def get_arrow(timestamp: int) -> arrow.arrow.Arrow:
315279

316280
def get_candle_source(candles: np.ndarray, source_type: str = "close") -> np.ndarray:
317281
"""
318-
Returns the candles corresponding the selected type.
319-
320-
:param candles: np.ndarray
321-
:param source_type: string
322-
:return: np.ndarray
323-
"""
324-
325-
if source_type == "close":
326-
return candles[:, 2]
327-
elif source_type == "high":
328-
return candles[:, 3]
329-
elif source_type == "low":
330-
return candles[:, 4]
331-
elif source_type == "open":
332-
return candles[:, 1]
333-
elif source_type == "volume":
334-
return candles[:, 5]
335-
elif source_type == "hl2":
336-
return (candles[:, 3] + candles[:, 4]) / 2
337-
elif source_type == "hlc3":
338-
return (candles[:, 3] + candles[:, 4] + candles[:, 2]) / 3
339-
elif source_type == "ohlc4":
340-
return (candles[:, 1] + candles[:, 3] + candles[:, 4] + candles[:, 2]) / 4
341-
else:
342-
raise ValueError('type string not recognised')
282+
Returns the candles corresponding to the selected type.
283+
"""
284+
try:
285+
return CANDLE_SOURCE_MAPPING[source_type](candles)
286+
except KeyError:
287+
raise ValueError(f"Source type '{source_type}' not recognised")
343288

344289

345290
def get_config(keys: str, default: Any = None) -> Any:
@@ -522,35 +467,11 @@ def key(exchange: str, symbol: str, timeframe: str = None):
522467

523468

524469
def max_timeframe(timeframes_list: list) -> str:
525-
from jesse.enums import timeframes
526-
527-
if timeframes.DAY_1 in timeframes_list:
528-
return timeframes.DAY_1
529-
if timeframes.HOUR_12 in timeframes_list:
530-
return timeframes.HOUR_12
531-
if timeframes.HOUR_8 in timeframes_list:
532-
return timeframes.HOUR_8
533-
if timeframes.HOUR_6 in timeframes_list:
534-
return timeframes.HOUR_6
535-
if timeframes.HOUR_4 in timeframes_list:
536-
return timeframes.HOUR_4
537-
if timeframes.HOUR_3 in timeframes_list:
538-
return timeframes.HOUR_3
539-
if timeframes.HOUR_2 in timeframes_list:
540-
return timeframes.HOUR_2
541-
if timeframes.HOUR_1 in timeframes_list:
542-
return timeframes.HOUR_1
543-
if timeframes.MINUTE_45 in timeframes_list:
544-
return timeframes.MINUTE_45
545-
if timeframes.MINUTE_30 in timeframes_list:
546-
return timeframes.MINUTE_30
547-
if timeframes.MINUTE_15 in timeframes_list:
548-
return timeframes.MINUTE_15
549-
if timeframes.MINUTE_5 in timeframes_list:
550-
return timeframes.MINUTE_5
551-
if timeframes.MINUTE_3 in timeframes_list:
552-
return timeframes.MINUTE_3
553470

471+
times = set(timeframes_list)
472+
for tf in TIMEFRAME_PRIORITY:
473+
if tf in times:
474+
return tf
554475
return timeframes.MINUTE_1
555476

556477

0 commit comments

Comments
 (0)