Merge https://github.com/freqtrade/freqtrade into personal-branch
This commit is contained in:
commit
a50bde10de
@ -171,7 +171,7 @@ official commands. You can ask at any moment for help with `/help`.
|
|||||||
| `/profit [<n>]` | Display a summary of your profit/loss from close trades and some stats about your performance, over the last n days (all trades by default)
|
| `/profit [<n>]` | Display a summary of your profit/loss from close trades and some stats about your performance, over the last n days (all trades by default)
|
||||||
| `/forcesell <trade_id>` | Instantly sells the given trade (Ignoring `minimum_roi`).
|
| `/forcesell <trade_id>` | Instantly sells the given trade (Ignoring `minimum_roi`).
|
||||||
| `/forcesell all` | Instantly sells all open trades (Ignoring `minimum_roi`).
|
| `/forcesell all` | Instantly sells all open trades (Ignoring `minimum_roi`).
|
||||||
| `/forcebuy <pair> [rate]` | Instantly buys the given pair. Rate is optional. (`forcebuy_enable` must be set to True)
|
| `/forcebuy <pair> [rate]` | Instantly buys the given pair. Rate is optional and only applies to limit orders. (`forcebuy_enable` must be set to True)
|
||||||
| `/performance` | Show performance of each finished trade grouped by pair
|
| `/performance` | Show performance of each finished trade grouped by pair
|
||||||
| `/balance` | Show account balance per currency
|
| `/balance` | Show account balance per currency
|
||||||
| `/daily <n>` | Shows profit or loss per day, over the last n days (n defaults to 7)
|
| `/daily <n>` | Shows profit or loss per day, over the last n days (n defaults to 7)
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import io
|
import io
|
||||||
import logging
|
import logging
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
@ -64,10 +63,11 @@ class HyperoptTools():
|
|||||||
'export_time': datetime.now(timezone.utc),
|
'export_time': datetime.now(timezone.utc),
|
||||||
}
|
}
|
||||||
logger.info(f"Dumping parameters to {filename}")
|
logger.info(f"Dumping parameters to {filename}")
|
||||||
rapidjson.dump(final_params, filename.open('w'), indent=2,
|
with filename.open('w') as f:
|
||||||
default=hyperopt_serializer,
|
rapidjson.dump(final_params, f, indent=2,
|
||||||
number_mode=rapidjson.NM_NATIVE | rapidjson.NM_NAN
|
default=hyperopt_serializer,
|
||||||
)
|
number_mode=rapidjson.NM_NATIVE | rapidjson.NM_NAN
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def try_export_params(config: Dict[str, Any], strategy_name: str, params: Dict):
|
def try_export_params(config: Dict[str, Any], strategy_name: str, params: Dict):
|
||||||
|
@ -7,11 +7,15 @@ class SKDecimal(Integer):
|
|||||||
def __init__(self, low, high, decimals=3, prior="uniform", base=10, transform=None,
|
def __init__(self, low, high, decimals=3, prior="uniform", base=10, transform=None,
|
||||||
name=None, dtype=np.int64):
|
name=None, dtype=np.int64):
|
||||||
self.decimals = decimals
|
self.decimals = decimals
|
||||||
_low = int(low * pow(10, self.decimals))
|
|
||||||
_high = int(high * pow(10, self.decimals))
|
self.pow_dot_one = pow(0.1, self.decimals)
|
||||||
|
self.pow_ten = pow(10, self.decimals)
|
||||||
|
|
||||||
|
_low = int(low * self.pow_ten)
|
||||||
|
_high = int(high * self.pow_ten)
|
||||||
# trunc to precision to avoid points out of space
|
# trunc to precision to avoid points out of space
|
||||||
self.low_orig = round(_low * pow(0.1, self.decimals), self.decimals)
|
self.low_orig = round(_low * self.pow_dot_one, self.decimals)
|
||||||
self.high_orig = round(_high * pow(0.1, self.decimals), self.decimals)
|
self.high_orig = round(_high * self.pow_dot_one, self.decimals)
|
||||||
|
|
||||||
super().__init__(_low, _high, prior, base, transform, name, dtype)
|
super().__init__(_low, _high, prior, base, transform, name, dtype)
|
||||||
|
|
||||||
@ -25,9 +29,9 @@ class SKDecimal(Integer):
|
|||||||
return self.low_orig <= point <= self.high_orig
|
return self.low_orig <= point <= self.high_orig
|
||||||
|
|
||||||
def transform(self, Xt):
|
def transform(self, Xt):
|
||||||
aa = [int(x * pow(10, self.decimals)) for x in Xt]
|
return super().transform([int(v * self.pow_ten) for v in Xt])
|
||||||
return super().transform(aa)
|
|
||||||
|
|
||||||
def inverse_transform(self, Xt):
|
def inverse_transform(self, Xt):
|
||||||
res = super().inverse_transform(Xt)
|
res = super().inverse_transform(Xt)
|
||||||
return [round(x * pow(0.1, self.decimals), self.decimals) for x in res]
|
# equivalent to [round(x * pow(0.1, self.decimals), self.decimals) for x in res]
|
||||||
|
return [int(v) / self.pow_ten for v in res]
|
||||||
|
@ -56,17 +56,21 @@ class StrategyResolver(IResolver):
|
|||||||
if strategy._ft_params_from_file:
|
if strategy._ft_params_from_file:
|
||||||
# Set parameters from Hyperopt results file
|
# Set parameters from Hyperopt results file
|
||||||
params = strategy._ft_params_from_file
|
params = strategy._ft_params_from_file
|
||||||
strategy.minimal_roi = params.get('roi', strategy.minimal_roi)
|
strategy.minimal_roi = params.get('roi', getattr(strategy, 'minimal_roi', {}))
|
||||||
|
|
||||||
strategy.stoploss = params.get('stoploss', {}).get('stoploss', strategy.stoploss)
|
strategy.stoploss = params.get('stoploss', {}).get(
|
||||||
|
'stoploss', getattr(strategy, 'stoploss', -0.1))
|
||||||
trailing = params.get('trailing', {})
|
trailing = params.get('trailing', {})
|
||||||
strategy.trailing_stop = trailing.get('trailing_stop', strategy.trailing_stop)
|
strategy.trailing_stop = trailing.get(
|
||||||
strategy.trailing_stop_positive = trailing.get('trailing_stop_positive',
|
'trailing_stop', getattr(strategy, 'trailing_stop', False))
|
||||||
strategy.trailing_stop_positive)
|
strategy.trailing_stop_positive = trailing.get(
|
||||||
|
'trailing_stop_positive', getattr(strategy, 'trailing_stop_positive', None))
|
||||||
strategy.trailing_stop_positive_offset = trailing.get(
|
strategy.trailing_stop_positive_offset = trailing.get(
|
||||||
'trailing_stop_positive_offset', strategy.trailing_stop_positive_offset)
|
'trailing_stop_positive_offset',
|
||||||
|
getattr(strategy, 'trailing_stop_positive_offset', 0))
|
||||||
strategy.trailing_only_offset_is_reached = trailing.get(
|
strategy.trailing_only_offset_is_reached = trailing.get(
|
||||||
'trailing_only_offset_is_reached', strategy.trailing_only_offset_is_reached)
|
'trailing_only_offset_is_reached',
|
||||||
|
getattr(strategy, 'trailing_only_offset_is_reached', 0.0))
|
||||||
|
|
||||||
# Set attributes
|
# Set attributes
|
||||||
# Check if we need to override configuration
|
# Check if we need to override configuration
|
||||||
|
@ -1033,7 +1033,8 @@ class Telegram(RPCHandler):
|
|||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
forcebuy_text = ("*/forcebuy <pair> [<rate>]:* `Instantly buys the given pair. "
|
forcebuy_text = ("*/forcebuy <pair> [<rate>]:* `Instantly buys the given pair. "
|
||||||
"Optionally takes a rate at which to buy.` \n")
|
"Optionally takes a rate at which to buy "
|
||||||
|
"(only applies to limit orders).` \n")
|
||||||
message = ("*/start:* `Starts the trader`\n"
|
message = ("*/start:* `Starts the trader`\n"
|
||||||
"*/stop:* `Stops the trader`\n"
|
"*/stop:* `Stops the trader`\n"
|
||||||
"*/status <trade_id>|[table]:* `Lists all open trades`\n"
|
"*/status <trade_id>|[table]:* `Lists all open trades`\n"
|
||||||
|
@ -381,7 +381,8 @@ class HyperStrategyMixin(object):
|
|||||||
if filename.is_file():
|
if filename.is_file():
|
||||||
logger.info(f"Loading parameters from file {filename}")
|
logger.info(f"Loading parameters from file {filename}")
|
||||||
try:
|
try:
|
||||||
params = json_load(filename.open('r'))
|
with filename.open('r') as f:
|
||||||
|
params = json_load(f)
|
||||||
if params.get('strategy_name') != self.__class__.__name__:
|
if params.get('strategy_name') != self.__class__.__name__:
|
||||||
raise OperationalException('Invalid parameter file provided.')
|
raise OperationalException('Invalid parameter file provided.')
|
||||||
return params
|
return params
|
||||||
|
@ -65,9 +65,9 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
_populate_fun_len: int = 0
|
_populate_fun_len: int = 0
|
||||||
_buy_fun_len: int = 0
|
_buy_fun_len: int = 0
|
||||||
_sell_fun_len: int = 0
|
_sell_fun_len: int = 0
|
||||||
_ft_params_from_file: Dict = {}
|
_ft_params_from_file: Dict
|
||||||
# associated minimal roi
|
# associated minimal roi
|
||||||
minimal_roi: Dict
|
minimal_roi: Dict = {}
|
||||||
|
|
||||||
# associated stoploss
|
# associated stoploss
|
||||||
stoploss: float
|
stoploss: float
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
numpy==1.21.2
|
numpy==1.21.3
|
||||||
pandas==1.3.4
|
pandas==1.3.4
|
||||||
pandas-ta==0.3.14b
|
pandas-ta==0.3.14b
|
||||||
|
|
||||||
ccxt==1.58.47
|
ccxt==1.59.2
|
||||||
# Pin cryptography for now due to rust build errors with piwheels
|
# Pin cryptography for now due to rust build errors with piwheels
|
||||||
cryptography==35.0.0
|
cryptography==35.0.0
|
||||||
aiohttp==3.7.4.post0
|
aiohttp==3.7.4.post0
|
||||||
SQLAlchemy==1.4.25
|
SQLAlchemy==1.4.26
|
||||||
python-telegram-bot==13.7
|
python-telegram-bot==13.7
|
||||||
arrow==1.2.0
|
arrow==1.2.1
|
||||||
cachetools==4.2.2
|
cachetools==4.2.2
|
||||||
requests==2.26.0
|
requests==2.26.0
|
||||||
urllib3==1.26.7
|
urllib3==1.26.7
|
||||||
jsonschema==4.1.0
|
jsonschema==4.1.2
|
||||||
TA-Lib==0.4.21
|
TA-Lib==0.4.21
|
||||||
technical==1.3.0
|
technical==1.3.0
|
||||||
tabulate==0.8.9
|
tabulate==0.8.9
|
||||||
@ -41,4 +41,4 @@ psutil==5.8.0
|
|||||||
colorama==0.4.4
|
colorama==0.4.4
|
||||||
# Building config files interactively
|
# Building config files interactively
|
||||||
questionary==1.10.0
|
questionary==1.10.0
|
||||||
prompt-toolkit==3.0.20
|
prompt-toolkit==3.0.21
|
||||||
|
@ -209,7 +209,8 @@ def test_export_params(tmpdir):
|
|||||||
|
|
||||||
assert filename.is_file()
|
assert filename.is_file()
|
||||||
|
|
||||||
content = rapidjson.load(filename.open('r'))
|
with filename.open('r') as f:
|
||||||
|
content = rapidjson.load(f)
|
||||||
assert content['strategy_name'] == 'StrategyTestV2'
|
assert content['strategy_name'] == 'StrategyTestV2'
|
||||||
assert 'params' in content
|
assert 'params' in content
|
||||||
assert "buy" in content["params"]
|
assert "buy" in content["params"]
|
||||||
|
@ -62,8 +62,8 @@ def test_load_strategy(default_conf, result):
|
|||||||
|
|
||||||
|
|
||||||
def test_load_strategy_base64(result, caplog, default_conf):
|
def test_load_strategy_base64(result, caplog, default_conf):
|
||||||
with (Path(__file__).parents[2] / 'freqtrade/templates/sample_strategy.py').open("rb") as file:
|
filepath = Path(__file__).parents[2] / 'freqtrade/templates/sample_strategy.py'
|
||||||
encoded_string = urlsafe_b64encode(file.read()).decode("utf-8")
|
encoded_string = urlsafe_b64encode(filepath.read_bytes()).decode("utf-8")
|
||||||
default_conf.update({'strategy': 'SampleStrategy:{}'.format(encoded_string)})
|
default_conf.update({'strategy': 'SampleStrategy:{}'.format(encoded_string)})
|
||||||
|
|
||||||
strategy = StrategyResolver.load_strategy(default_conf)
|
strategy = StrategyResolver.load_strategy(default_conf)
|
||||||
|
Loading…
Reference in New Issue
Block a user