Merge branch 'develop' into backtest_live_models

This commit is contained in:
Wagner Costa Santos 2022-09-28 08:49:15 -03:00
commit df0927cdee
11 changed files with 43 additions and 19 deletions

View File

@ -407,15 +407,6 @@ jobs:
run: | run: |
build_helpers/publish_docker_multi.sh build_helpers/publish_docker_multi.sh
- name: Discord notification
uses: rjstone/discord-webhook-notify@v1
if: always() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false) && (github.event_name != 'schedule')
with:
severity: info
details: Deploy Succeeded!
webhookUrl: ${{ secrets.DISCORD_WEBHOOK }}
deploy_arm: deploy_arm:
needs: [ deploy ] needs: [ deploy ]
# Only run on 64bit machines # Only run on 64bit machines
@ -443,3 +434,11 @@ jobs:
BRANCH_NAME: ${{ steps.extract_branch.outputs.branch }} BRANCH_NAME: ${{ steps.extract_branch.outputs.branch }}
run: | run: |
build_helpers/publish_docker_arm64.sh build_helpers/publish_docker_arm64.sh
- name: Discord notification
uses: rjstone/discord-webhook-notify@v1
if: always() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false) && (github.event_name != 'schedule')
with:
severity: info
details: Deploy Succeeded!
webhookUrl: ${{ secrets.DISCORD_WEBHOOK }}

View File

@ -34,7 +34,9 @@ repos:
exclude: | exclude: |
(?x)^( (?x)^(
tests/.*| tests/.*|
.*\.svg .*\.svg|
.*\.yml|
.*\.json
)$ )$
- id: mixed-line-ending - id: mixed-line-ending
- id: debug-statements - id: debug-statements

View File

@ -78,7 +78,7 @@
10, 10,
20 20
], ],
"plot_feature_importance": false "plot_feature_importances": 0
}, },
"data_split_parameters": { "data_split_parameters": {
"test_size": 0.33, "test_size": 0.33,

View File

@ -1,7 +1,8 @@
FROM freqtradeorg/freqtrade:develop_plot FROM freqtradeorg/freqtrade:develop_plot
RUN pip install jupyterlab --user --no-cache-dir # Pin jupyter-client to avoid tornado version conflict
RUN pip install jupyterlab jupyter-client==7.3.4 --user --no-cache-dir
# Empty the ENTRYPOINT to allow all commands # Empty the ENTRYPOINT to allow all commands
ENTRYPOINT [] ENTRYPOINT []

View File

@ -10,7 +10,7 @@ services:
ports: ports:
- "127.0.0.1:8888:8888" - "127.0.0.1:8888:8888"
volumes: volumes:
- "./user_data:/freqtrade/user_data" - "../user_data:/freqtrade/user_data"
# Default command used when running `docker compose up` # Default command used when running `docker compose up`
command: > command: >
jupyter lab --port=8888 --ip 0.0.0.0 --allow-root jupyter lab --port=8888 --ip 0.0.0.0 --allow-root

View File

@ -552,7 +552,7 @@ CONF_SCHEMA = {
"weight_factor": {"type": "number", "default": 0}, "weight_factor": {"type": "number", "default": 0},
"principal_component_analysis": {"type": "boolean", "default": False}, "principal_component_analysis": {"type": "boolean", "default": False},
"use_SVM_to_remove_outliers": {"type": "boolean", "default": False}, "use_SVM_to_remove_outliers": {"type": "boolean", "default": False},
"plot_feature_importance": {"type": "boolean", "default": False}, "plot_feature_importances": {"type": "integer", "default": 0},
"svm_params": {"type": "object", "svm_params": {"type": "object",
"properties": { "properties": {
"shuffle": {"type": "boolean", "default": False}, "shuffle": {"type": "boolean", "default": False},

View File

@ -5,6 +5,7 @@ from datetime import datetime
from typing import Any, Dict, List from typing import Any, Dict, List
from fastapi import APIRouter, BackgroundTasks, Depends from fastapi import APIRouter, BackgroundTasks, Depends
from fastapi.exceptions import HTTPException
from freqtrade.configuration.config_validation import validate_config_consistency from freqtrade.configuration.config_validation import validate_config_consistency
from freqtrade.data.btanalysis import get_backtest_resultlist, load_and_merge_backtest_result from freqtrade.data.btanalysis import get_backtest_resultlist, load_and_merge_backtest_result
@ -31,6 +32,9 @@ async def api_start_backtest(bt_settings: BacktestRequest, background_tasks: Bac
if ApiServer._bgtask_running: if ApiServer._bgtask_running:
raise RPCException('Bot Background task already running') raise RPCException('Bot Background task already running')
if ':' in bt_settings.strategy:
raise HTTPException(status_code=500, detail="base64 encoded strategies are not allowed.")
btconfig = deepcopy(config) btconfig = deepcopy(config)
settings = dict(bt_settings) settings = dict(bt_settings)
# Pydantic models will contain all keys, but non-provided ones are None # Pydantic models will contain all keys, but non-provided ones are None

View File

@ -265,6 +265,8 @@ def list_strategies(config=Depends(get_config)):
@router.get('/strategy/{strategy}', response_model=StrategyResponse, tags=['strategy']) @router.get('/strategy/{strategy}', response_model=StrategyResponse, tags=['strategy'])
def get_strategy(strategy: str, config=Depends(get_config)): def get_strategy(strategy: str, config=Depends(get_config)):
if ":" in strategy:
raise HTTPException(status_code=500, detail="base64 encoded strategies are not allowed.")
config_ = deepcopy(config) config_ = deepcopy(config)
from freqtrade.resolvers.strategy_resolver import StrategyResolver from freqtrade.resolvers.strategy_resolver import StrategyResolver

View File

@ -25,7 +25,7 @@ from freqtrade.exceptions import ExchangeError, PricingError
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_msecs from freqtrade.exchange import timeframe_to_minutes, timeframe_to_msecs
from freqtrade.loggers import bufferHandler from freqtrade.loggers import bufferHandler
from freqtrade.misc import decimals_per_coin, shorten_date from freqtrade.misc import decimals_per_coin, shorten_date
from freqtrade.persistence import PairLocks, Trade from freqtrade.persistence import Order, PairLocks, Trade
from freqtrade.persistence.models import PairLock from freqtrade.persistence.models import PairLock
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
@ -166,9 +166,9 @@ class RPC:
else: else:
results = [] results = []
for trade in trades: for trade in trades:
order = None order: Optional[Order] = None
if trade.open_order_id: if trade.open_order_id:
order = self._freqtrade.exchange.fetch_order(trade.open_order_id, trade.pair) order = trade.select_order_by_order_id(trade.open_order_id)
# calculate profit and send message to user # calculate profit and send message to user
if trade.is_open: if trade.is_open:
try: try:
@ -219,7 +219,7 @@ class RPC:
stoploss_entry_dist=stoploss_entry_dist, stoploss_entry_dist=stoploss_entry_dist,
stoploss_entry_dist_ratio=round(stoploss_entry_dist_ratio, 8), stoploss_entry_dist_ratio=round(stoploss_entry_dist_ratio, 8),
open_order='({} {} rem={:.8f})'.format( open_order='({} {} rem={:.8f})'.format(
order['type'], order['side'], order['remaining'] order.order_type, order.side, order.remaining
) if order else None, ) if order else None,
)) ))
results.append(trade_dict) results.append(trade_dict)
@ -773,6 +773,9 @@ class RPC:
is_short = trade.is_short is_short = trade.is_short
if not self._freqtrade.strategy.position_adjustment_enable: if not self._freqtrade.strategy.position_adjustment_enable:
raise RPCException(f'position for {pair} already open - id: {trade.id}') raise RPCException(f'position for {pair} already open - id: {trade.id}')
else:
if Trade.get_open_trade_count() >= self._config['max_open_trades']:
raise RPCException("Maximum number of trades is reached.")
if not stake_amount: if not stake_amount:
# gen stake amount # gen stake amount

View File

@ -45,7 +45,6 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
freqtradebot.enter_positions() freqtradebot.enter_positions()
trades = Trade.get_open_trades() trades = Trade.get_open_trades()
trades[0].open_order_id = None
freqtradebot.exit_positions(trades) freqtradebot.exit_positions(trades)
results = rpc._rpc_trade_status() results = rpc._rpc_trade_status()
@ -1031,6 +1030,7 @@ def test_rpc_count(mocker, default_conf, ticker, fee) -> None:
def test_rpc_force_entry(mocker, default_conf, ticker, fee, limit_buy_order_open) -> None: def test_rpc_force_entry(mocker, default_conf, ticker, fee, limit_buy_order_open) -> None:
default_conf['force_entry_enable'] = True default_conf['force_entry_enable'] = True
default_conf['max_open_trades'] = 0
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
buy_mm = MagicMock(return_value=limit_buy_order_open) buy_mm = MagicMock(return_value=limit_buy_order_open)
mocker.patch.multiple( mocker.patch.multiple(
@ -1045,6 +1045,10 @@ def test_rpc_force_entry(mocker, default_conf, ticker, fee, limit_buy_order_open
patch_get_signal(freqtradebot) patch_get_signal(freqtradebot)
rpc = RPC(freqtradebot) rpc = RPC(freqtradebot)
pair = 'ETH/BTC' pair = 'ETH/BTC'
with pytest.raises(RPCException, match='Maximum number of trades is reached.'):
rpc._rpc_force_entry(pair, None)
freqtradebot.config['max_open_trades'] = 5
trade = rpc._rpc_force_entry(pair, None) trade = rpc._rpc_force_entry(pair, None)
assert isinstance(trade, Trade) assert isinstance(trade, Trade)
assert trade.pair == pair assert trade.pair == pair

View File

@ -1477,6 +1477,10 @@ def test_api_strategy(botclient):
rc = client_get(client, f"{BASE_URI}/strategy/NoStrat") rc = client_get(client, f"{BASE_URI}/strategy/NoStrat")
assert_response(rc, 404) assert_response(rc, 404)
# Disallow base64 strategies
rc = client_get(client, f"{BASE_URI}/strategy/xx:cHJpbnQoImhlbGxvIHdvcmxkIik=")
assert_response(rc, 500)
def test_list_available_pairs(botclient): def test_list_available_pairs(botclient):
ftbot, client = botclient ftbot, client = botclient
@ -1650,6 +1654,11 @@ def test_api_backtesting(botclient, mocker, fee, caplog, tmpdir):
assert not result['running'] assert not result['running']
assert result['status_msg'] == 'Backtest reset' assert result['status_msg'] == 'Backtest reset'
# Disallow base64 strategies
data['strategy'] = "xx:cHJpbnQoImhlbGxvIHdvcmxkIik="
rc = client_post(client, f"{BASE_URI}/backtest", data=json.dumps(data))
assert_response(rc, 500)
def test_api_backtest_history(botclient, mocker, testdatadir): def test_api_backtest_history(botclient, mocker, testdatadir):
ftbot, client = botclient ftbot, client = botclient