mirror of
https://github.com/freqtrade/freqtrade.git
synced 2026-01-26 08:50:47 +00:00
Merge branch 'develop' into pr/initrv/8426
This commit is contained in:
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@@ -57,7 +57,7 @@ jobs:
|
||||
- name: Installation - *nix
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
python -m pip install --upgrade pip wheel
|
||||
python -m pip install --upgrade pip==23.0.1 wheel
|
||||
export LD_LIBRARY_PATH=${HOME}/dependencies/lib:$LD_LIBRARY_PATH
|
||||
export TA_LIBRARY_PATH=${HOME}/dependencies/lib
|
||||
export TA_INCLUDE_PATH=${HOME}/dependencies/include
|
||||
@@ -163,7 +163,7 @@ jobs:
|
||||
rm /usr/local/bin/python3.11-config || true
|
||||
|
||||
brew install hdf5 c-blosc
|
||||
python -m pip install --upgrade pip wheel
|
||||
python -m pip install --upgrade pip==23.0.1 wheel
|
||||
export LD_LIBRARY_PATH=${HOME}/dependencies/lib:$LD_LIBRARY_PATH
|
||||
export TA_LIBRARY_PATH=${HOME}/dependencies/lib
|
||||
export TA_INCLUDE_PATH=${HOME}/dependencies/include
|
||||
@@ -352,7 +352,7 @@ jobs:
|
||||
- name: Installation - *nix
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
python -m pip install --upgrade pip wheel
|
||||
python -m pip install --upgrade pip==23.0.1 wheel
|
||||
export LD_LIBRARY_PATH=${HOME}/dependencies/lib:$LD_LIBRARY_PATH
|
||||
export TA_LIBRARY_PATH=${HOME}/dependencies/lib
|
||||
export TA_INCLUDE_PATH=${HOME}/dependencies/include
|
||||
|
||||
@@ -25,7 +25,7 @@ FROM base as python-deps
|
||||
RUN apt-get update \
|
||||
&& apt-get -y install build-essential libssl-dev git libffi-dev libgfortran5 pkg-config cmake gcc \
|
||||
&& apt-get clean \
|
||||
&& pip install --upgrade pip
|
||||
&& pip install --upgrade pip==23.0.1
|
||||
|
||||
# Install TA-lib
|
||||
COPY build_helpers/* /tmp/
|
||||
|
||||
@@ -210,6 +210,6 @@ To run this bot we recommend you a cloud instance with a minimum of:
|
||||
- [Python >= 3.8](http://docs.python-guide.org/en/latest/starting/installation/)
|
||||
- [pip](https://pip.pypa.io/en/stable/installing/)
|
||||
- [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
|
||||
- [TA-Lib](https://mrjbq7.github.io/ta-lib/install.html)
|
||||
- [TA-Lib](https://ta-lib.github.io/ta-lib-python/)
|
||||
- [virtualenv](https://virtualenv.pypa.io/en/stable/installation.html) (Recommended)
|
||||
- [Docker](https://www.docker.com/products/docker) (Recommended)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build_helpers/TA_Lib-0.4.26-cp310-cp310-win_amd64.whl
Normal file
BIN
build_helpers/TA_Lib-0.4.26-cp310-cp310-win_amd64.whl
Normal file
Binary file not shown.
BIN
build_helpers/TA_Lib-0.4.26-cp311-cp311-win_amd64.whl
Normal file
BIN
build_helpers/TA_Lib-0.4.26-cp311-cp311-win_amd64.whl
Normal file
Binary file not shown.
BIN
build_helpers/TA_Lib-0.4.26-cp38-cp38-win_amd64.whl
Normal file
BIN
build_helpers/TA_Lib-0.4.26-cp38-cp38-win_amd64.whl
Normal file
Binary file not shown.
BIN
build_helpers/TA_Lib-0.4.26-cp39-cp39-win_amd64.whl
Normal file
BIN
build_helpers/TA_Lib-0.4.26-cp39-cp39-win_amd64.whl
Normal file
Binary file not shown.
@@ -1,21 +1,21 @@
|
||||
# Downloads don't work automatically, since the URL is regenerated via javascript.
|
||||
# Downloaded from https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib
|
||||
|
||||
python -m pip install --upgrade pip wheel
|
||||
python -m pip install --upgrade pip==23.0.1 wheel
|
||||
|
||||
$pyv = python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"
|
||||
|
||||
if ($pyv -eq '3.8') {
|
||||
pip install build_helpers\TA_Lib-0.4.25-cp38-cp38-win_amd64.whl
|
||||
pip install build_helpers\TA_Lib-0.4.26-cp38-cp38-win_amd64.whl
|
||||
}
|
||||
if ($pyv -eq '3.9') {
|
||||
pip install build_helpers\TA_Lib-0.4.25-cp39-cp39-win_amd64.whl
|
||||
pip install build_helpers\TA_Lib-0.4.26-cp39-cp39-win_amd64.whl
|
||||
}
|
||||
if ($pyv -eq '3.10') {
|
||||
pip install build_helpers\TA_Lib-0.4.25-cp310-cp310-win_amd64.whl
|
||||
pip install build_helpers\TA_Lib-0.4.26-cp310-cp310-win_amd64.whl
|
||||
}
|
||||
if ($pyv -eq '3.11') {
|
||||
pip install build_helpers\TA_Lib-0.4.25-cp311-cp311-win_amd64.whl
|
||||
pip install build_helpers\TA_Lib-0.4.26-cp311-cp311-win_amd64.whl
|
||||
}
|
||||
pip install -r requirements-dev.txt
|
||||
pip install -e .
|
||||
|
||||
@@ -52,7 +52,7 @@ These requirements apply to both [Script Installation](#script-installation) and
|
||||
* [pip](https://pip.pypa.io/en/stable/installing/)
|
||||
* [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
|
||||
* [virtualenv](https://virtualenv.pypa.io/en/stable/installation.html) (Recommended)
|
||||
* [TA-Lib](https://mrjbq7.github.io/ta-lib/install.html) (install instructions [below](#install-ta-lib))
|
||||
* [TA-Lib](https://ta-lib.github.io/ta-lib-python/) (install instructions [below](#install-ta-lib))
|
||||
|
||||
### Install code
|
||||
|
||||
@@ -210,7 +210,7 @@ sudo ./build_helpers/install_ta-lib.sh
|
||||
|
||||
##### TA-Lib manual installation
|
||||
|
||||
Official webpage: https://mrjbq7.github.io/ta-lib/install.html
|
||||
[Official installation guide](https://ta-lib.github.io/ta-lib-python/install.html)
|
||||
|
||||
```bash
|
||||
wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz
|
||||
|
||||
@@ -24,9 +24,9 @@ git clone https://github.com/freqtrade/freqtrade.git
|
||||
|
||||
Install ta-lib according to the [ta-lib documentation](https://github.com/mrjbq7/ta-lib#windows).
|
||||
|
||||
As compiling from source on windows has heavy dependencies (requires a partial visual studio installation), there is also a repository of unofficial pre-compiled windows Wheels [here](https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib), which need to be downloaded and installed using `pip install TA_Lib-0.4.25-cp38-cp38-win_amd64.whl` (make sure to use the version matching your python version).
|
||||
As compiling from source on windows has heavy dependencies (requires a partial visual studio installation), Freqtrade provides these dependencies (in the binary wheel format) for the latest 3 Python versions (3.8, 3.9, 3.10 and 3.11) and for 64bit Windows.
|
||||
These Wheels are also used by CI running on windows, and are therefore tested together with freqtrade.
|
||||
|
||||
Freqtrade provides these dependencies for the latest 3 Python versions (3.8, 3.9, 3.10 and 3.11) and for 64bit Windows.
|
||||
Other versions must be downloaded from the above link.
|
||||
|
||||
``` powershell
|
||||
@@ -45,8 +45,6 @@ freqtrade
|
||||
The above installation script assumes you're using powershell on a 64bit windows.
|
||||
Commands for the legacy CMD windows console may differ.
|
||||
|
||||
> Thanks [Owdr](https://github.com/Owdr) for the commands. Source: [Issue #222](https://github.com/freqtrade/freqtrade/issues/222)
|
||||
|
||||
### Error during installation on Windows
|
||||
|
||||
``` bash
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -886,7 +886,7 @@ class Exchange:
|
||||
'filled': _amount,
|
||||
'remaining': 0.0,
|
||||
'status': "closed",
|
||||
'cost': (dry_order['amount'] * average) / leverage
|
||||
'cost': (dry_order['amount'] * average)
|
||||
})
|
||||
# market orders will always incurr taker fees
|
||||
dry_order = self.add_dry_order_fee(pair, dry_order, 'taker')
|
||||
|
||||
@@ -45,5 +45,6 @@ class BasePyTorchRegressor(BasePyTorchModel):
|
||||
device=self.device
|
||||
)
|
||||
y = self.model.model(x)
|
||||
y = y.cpu()
|
||||
pred_df = DataFrame(y.detach().numpy(), columns=[dk.label_list[0]])
|
||||
return (pred_df, dk.do_predict)
|
||||
|
||||
@@ -143,8 +143,8 @@ class PyTorchModelTrainer(PyTorchTrainerInterface):
|
||||
"""
|
||||
data_loader_dictionary = {}
|
||||
for split in splits:
|
||||
x = self.data_convertor.convert_x(data_dictionary[f"{split}_features"])
|
||||
y = self.data_convertor.convert_y(data_dictionary[f"{split}_labels"])
|
||||
x = self.data_convertor.convert_x(data_dictionary[f"{split}_features"], self.device)
|
||||
y = self.data_convertor.convert_y(data_dictionary[f"{split}_labels"], self.device)
|
||||
dataset = TensorDataset(*x, *y)
|
||||
data_loader = DataLoader(
|
||||
dataset,
|
||||
|
||||
@@ -66,10 +66,7 @@ def authorized_only(command_handler: Callable[..., None]) -> Callable[..., Any]:
|
||||
|
||||
chat_id = int(self._config['telegram']['chat_id'])
|
||||
if cchat_id != chat_id:
|
||||
logger.info(
|
||||
'Rejected unauthorized message from: %s',
|
||||
update.message.chat_id
|
||||
)
|
||||
logger.info(f'Rejected unauthorized message from: {update.message.chat_id}')
|
||||
return wrapper
|
||||
# Rollback session to avoid getting data stored in a transaction.
|
||||
Trade.rollback()
|
||||
|
||||
@@ -12,7 +12,7 @@ cachetools==4.2.2
|
||||
requests==2.28.2
|
||||
urllib3==1.26.15
|
||||
jsonschema==4.17.3
|
||||
TA-Lib==0.4.25
|
||||
TA-Lib==0.4.26
|
||||
technical==1.4.0
|
||||
tabulate==0.9.0
|
||||
pycoingecko==3.1.0
|
||||
|
||||
2
setup.sh
2
setup.sh
@@ -50,7 +50,7 @@ function updateenv() {
|
||||
SYS_ARCH=$(uname -m)
|
||||
echo "pip install in-progress. Please wait..."
|
||||
# Setuptools 65.5.0 is the last version that can install gym==0.21.0
|
||||
${PYTHON} -m pip install --upgrade pip wheel setuptools==65.5.1
|
||||
${PYTHON} -m pip install --upgrade pip==23.0.1 wheel setuptools==65.5.1
|
||||
REQUIREMENTS_HYPEROPT=""
|
||||
REQUIREMENTS_PLOT=""
|
||||
REQUIREMENTS_FREQAI=""
|
||||
|
||||
@@ -504,7 +504,7 @@ def get_default_conf(testdatadir):
|
||||
{"method": "StaticPairList"}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": True,
|
||||
"enabled": False,
|
||||
"token": "token",
|
||||
"chat_id": "0",
|
||||
"notification_settings": {},
|
||||
|
||||
@@ -1255,9 +1255,10 @@ def test_create_dry_run_order_fees(
|
||||
("buy", 29.563, True, True),
|
||||
("sell", 21.563, True, True),
|
||||
])
|
||||
@pytest.mark.parametrize("leverage", [1, 2, 5])
|
||||
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
||||
def test_create_dry_run_order_limit_fill(default_conf, mocker, side, price, filled, caplog,
|
||||
exchange_name, order_book_l2_usd, converted):
|
||||
exchange_name, order_book_l2_usd, converted, leverage):
|
||||
default_conf['dry_run'] = True
|
||||
exchange = get_patched_exchange(mocker, default_conf, id=exchange_name)
|
||||
mocker.patch.multiple(EXMS,
|
||||
@@ -1271,7 +1272,7 @@ def test_create_dry_run_order_limit_fill(default_conf, mocker, side, price, fill
|
||||
side=side,
|
||||
amount=1,
|
||||
rate=price,
|
||||
leverage=1.0
|
||||
leverage=leverage,
|
||||
)
|
||||
assert order_book_l2_usd.call_count == 1
|
||||
assert 'id' in order
|
||||
@@ -1295,6 +1296,7 @@ def test_create_dry_run_order_limit_fill(default_conf, mocker, side, price, fill
|
||||
assert order_book_l2_usd.call_count == (1 if not filled else 0)
|
||||
assert order_closed['status'] == ('open' if not filled else 'closed')
|
||||
assert order_closed['filled'] == (0 if not filled else 1)
|
||||
assert order_closed['cost'] == 1 * order_closed['average']
|
||||
|
||||
order_book_l2_usd.reset_mock()
|
||||
|
||||
@@ -1317,9 +1319,10 @@ def test_create_dry_run_order_limit_fill(default_conf, mocker, side, price, fill
|
||||
("sell", 25.564, 1000, 25.5555), # More than orderbook return
|
||||
("sell", 27, 10000, 25.65), # max-slippage 5%
|
||||
])
|
||||
@pytest.mark.parametrize("leverage", [1, 2, 5])
|
||||
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
||||
def test_create_dry_run_order_market_fill(default_conf, mocker, side, rate, amount, endprice,
|
||||
exchange_name, order_book_l2_usd):
|
||||
exchange_name, order_book_l2_usd, leverage):
|
||||
default_conf['dry_run'] = True
|
||||
exchange = get_patched_exchange(mocker, default_conf, id=exchange_name)
|
||||
mocker.patch.multiple(EXMS,
|
||||
@@ -1333,7 +1336,7 @@ def test_create_dry_run_order_market_fill(default_conf, mocker, side, rate, amou
|
||||
side=side,
|
||||
amount=amount,
|
||||
rate=rate,
|
||||
leverage=1.0
|
||||
leverage=leverage,
|
||||
)
|
||||
assert 'id' in order
|
||||
assert f'dry_run_{side}_' in order["id"]
|
||||
@@ -1342,6 +1345,8 @@ def test_create_dry_run_order_market_fill(default_conf, mocker, side, rate, amou
|
||||
assert order["symbol"] == "LTC/USDT"
|
||||
assert order['status'] == 'closed'
|
||||
assert order['filled'] == amount
|
||||
assert order['amount'] == amount
|
||||
assert pytest.approx(order['cost']) == amount * order['average']
|
||||
assert round(order["average"], 4) == round(endprice, 4)
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ def test_init_telegram_disabled(mocker, default_conf, caplog) -> None:
|
||||
|
||||
def test_init_telegram_enabled(mocker, default_conf, caplog) -> None:
|
||||
caplog.set_level(logging.DEBUG)
|
||||
default_conf['telegram']['enabled'] = True
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
||||
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
||||
|
||||
@@ -52,6 +53,7 @@ def test_cleanup_telegram_disabled(mocker, default_conf, caplog) -> None:
|
||||
|
||||
def test_cleanup_telegram_enabled(mocker, default_conf, caplog) -> None:
|
||||
caplog.set_level(logging.DEBUG)
|
||||
default_conf['telegram']['enabled'] = True
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
||||
telegram_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.cleanup', MagicMock())
|
||||
|
||||
@@ -85,7 +87,7 @@ def test_send_msg_telegram_disabled(mocker, default_conf, caplog) -> None:
|
||||
def test_send_msg_telegram_error(mocker, default_conf, caplog) -> None:
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', side_effect=ValueError())
|
||||
|
||||
default_conf['telegram']['enabled'] = True
|
||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||
rpc_manager = RPCManager(freqtradebot)
|
||||
rpc_manager.send_msg({
|
||||
@@ -99,6 +101,7 @@ def test_send_msg_telegram_error(mocker, default_conf, caplog) -> None:
|
||||
|
||||
def test_process_msg_queue(mocker, default_conf, caplog) -> None:
|
||||
telegram_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg')
|
||||
default_conf['telegram']['enabled'] = True
|
||||
default_conf['telegram']['allow_custom_messages'] = True
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init')
|
||||
|
||||
@@ -115,9 +118,9 @@ def test_process_msg_queue(mocker, default_conf, caplog) -> None:
|
||||
|
||||
|
||||
def test_send_msg_telegram_enabled(mocker, default_conf, caplog) -> None:
|
||||
default_conf['telegram']['enabled'] = True
|
||||
telegram_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg')
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init')
|
||||
|
||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||
rpc_manager = RPCManager(freqtradebot)
|
||||
rpc_manager.send_msg({
|
||||
@@ -166,7 +169,8 @@ def test_send_msg_webhook_CustomMessagetype(mocker, default_conf, caplog) -> Non
|
||||
caplog)
|
||||
|
||||
|
||||
def test_startupmessages_telegram_enabled(mocker, default_conf, caplog) -> None:
|
||||
def test_startupmessages_telegram_enabled(mocker, default_conf) -> None:
|
||||
default_conf['telegram']['enabled'] = True
|
||||
telegram_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock())
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
||||
|
||||
|
||||
@@ -36,6 +36,13 @@ from tests.conftest import (CURRENT_TEST_STRATEGY, EXMS, create_mock_trades,
|
||||
patch_exchange, patch_get_signal, patch_whitelist)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def default_conf(default_conf) -> dict:
|
||||
# Telegram is enabled by default
|
||||
default_conf['telegram']['enabled'] = True
|
||||
return default_conf
|
||||
|
||||
|
||||
class DummyCls(Telegram):
|
||||
"""
|
||||
Dummy class for testing the Telegram @authorized_only decorator
|
||||
|
||||
Reference in New Issue
Block a user