mirror of
https://github.com/freqtrade/freqtrade.git
synced 2026-03-03 00:32:20 +00:00
Merge branch 'develop' into feature/hyperliquid-hip3-support
This commit is contained in:
@@ -39,12 +39,6 @@ def populate_dataframe_with_trades_trades(testdatadir):
|
||||
return pd.read_feather(testdatadir / "orderflow/populate_dataframe_with_trades_TRADES.feather")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def candles(testdatadir):
|
||||
# TODO: this fixture isn't really necessary and could be removed
|
||||
return pd.read_json(testdatadir / "orderflow/candles.json").copy()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def public_trades_list(testdatadir):
|
||||
return read_csv(testdatadir / "orderflow/public_trades_list.csv").copy()
|
||||
@@ -293,7 +287,7 @@ def test_public_trades_trades_mock_populate_dataframe_with_trades__check_trades(
|
||||
assert t["price"] == 234.72
|
||||
|
||||
|
||||
def test_public_trades_put_volume_profile_into_ohlcv_candles(public_trades_list_simple, candles):
|
||||
def test_public_trades_put_volume_profile_into_ohlcv_candles(public_trades_list_simple):
|
||||
"""
|
||||
Tests the integration of volume profile data into OHLCV candles.
|
||||
|
||||
@@ -412,13 +406,11 @@ def test_public_trades_config_max_trades(
|
||||
|
||||
|
||||
def test_public_trades_testdata_sanity(
|
||||
candles,
|
||||
public_trades_list,
|
||||
public_trades_list_simple,
|
||||
populate_dataframe_with_trades_dataframe,
|
||||
populate_dataframe_with_trades_trades,
|
||||
):
|
||||
assert 10999 == len(candles)
|
||||
assert 1000 == len(public_trades_list)
|
||||
assert 999 == len(populate_dataframe_with_trades_dataframe)
|
||||
assert 293532 == len(populate_dataframe_with_trades_trades)
|
||||
|
||||
@@ -1012,7 +1012,7 @@ def test_validate_required_startup_candles(default_conf, mocker, caplog):
|
||||
ex._ft_has["ohlcv_has_history"] = False
|
||||
with pytest.raises(
|
||||
OperationalException,
|
||||
match=r"This strategy requires 2500.*, " r"which is more than the amount.*",
|
||||
match=r"This strategy requires 2500.*, " r"which is more than .* the amount",
|
||||
):
|
||||
ex.validate_required_startup_candles(2500, "5m")
|
||||
|
||||
|
||||
@@ -515,7 +515,6 @@ EXCHANGES = {
|
||||
],
|
||||
},
|
||||
"hyperliquid": {
|
||||
# TODO: Should be UBTC/USDC - probably needs a fix in ccxt
|
||||
"pair": "BTC/USDC",
|
||||
"stake_currency": "USDC",
|
||||
"hasQuoteVolume": False,
|
||||
|
||||
@@ -31,9 +31,6 @@ from tests.freqai.conftest import (
|
||||
def can_run_model(model: str) -> None:
|
||||
is_pytorch_model = "Reinforcement" in model or "PyTorch" in model
|
||||
|
||||
if is_arm() and "Catboost" in model:
|
||||
pytest.skip("CatBoost is not supported on ARM.")
|
||||
|
||||
if is_pytorch_model and is_mac():
|
||||
pytest.skip("Reinforcement learning / PyTorch module not available on intel based Mac OS.")
|
||||
|
||||
@@ -44,7 +41,6 @@ def can_run_model(model: str) -> None:
|
||||
("LightGBMRegressor", True, False, True, True, False, 0, 0),
|
||||
("XGBoostRegressor", False, True, False, True, False, 10, 0.05),
|
||||
("XGBoostRFRegressor", False, False, False, True, False, 0, 0),
|
||||
("CatboostRegressor", False, False, False, True, True, 0, 0),
|
||||
("PyTorchMLPRegressor", False, False, False, False, False, 0, 0),
|
||||
("PyTorchTransformerRegressor", False, False, False, False, False, 0, 0),
|
||||
("ReinforcementLearner", False, True, False, True, False, 0, 0),
|
||||
@@ -138,9 +134,7 @@ def test_extract_data_and_train_model_Standard(
|
||||
[
|
||||
("LightGBMRegressorMultiTarget", "freqai_test_multimodel_strat"),
|
||||
("XGBoostRegressorMultiTarget", "freqai_test_multimodel_strat"),
|
||||
("CatboostRegressorMultiTarget", "freqai_test_multimodel_strat"),
|
||||
("LightGBMClassifierMultiTarget", "freqai_test_multimodel_classifier_strat"),
|
||||
("CatboostClassifierMultiTarget", "freqai_test_multimodel_classifier_strat"),
|
||||
],
|
||||
)
|
||||
@pytest.mark.filterwarnings(r"ignore:.*__sklearn_tags__.*:DeprecationWarning")
|
||||
@@ -184,7 +178,6 @@ def test_extract_data_and_train_model_MultiTargets(mocker, freqai_conf, model, s
|
||||
"model",
|
||||
[
|
||||
"LightGBMClassifier",
|
||||
"CatboostClassifier",
|
||||
"XGBoostClassifier",
|
||||
"XGBoostRFClassifier",
|
||||
"SKLearnRandomForestClassifier",
|
||||
@@ -246,13 +239,11 @@ def test_extract_data_and_train_model_Classifiers(mocker, freqai_conf, model):
|
||||
[
|
||||
("LightGBMRegressor", 2, "freqai_test_strat"),
|
||||
("XGBoostRegressor", 2, "freqai_test_strat"),
|
||||
("CatboostRegressor", 2, "freqai_test_strat"),
|
||||
("PyTorchMLPRegressor", 2, "freqai_test_strat"),
|
||||
("PyTorchTransformerRegressor", 2, "freqai_test_strat"),
|
||||
("ReinforcementLearner", 3, "freqai_rl_test_strat"),
|
||||
("XGBoostClassifier", 2, "freqai_test_classifier"),
|
||||
("LightGBMClassifier", 2, "freqai_test_classifier"),
|
||||
("CatboostClassifier", 2, "freqai_test_classifier"),
|
||||
("PyTorchMLPClassifier", 2, "freqai_test_classifier"),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -64,7 +64,6 @@ def test_hyperopt_real_parameter():
|
||||
|
||||
def test_hyperopt_decimal_parameter():
|
||||
HyperoptStateContainer.set_state(HyperoptState.INDICATORS)
|
||||
# TODO: Check for get_space??
|
||||
from freqtrade.optimize.space import SKDecimal
|
||||
|
||||
with pytest.raises(OperationalException, match=r"DecimalParameter space must be.*"):
|
||||
|
||||
92
tests/test_pip_audit.py
Normal file
92
tests/test_pip_audit.py
Normal file
@@ -0,0 +1,92 @@
|
||||
"""
|
||||
Run pip audit to check for known security vulnerabilities in installed packages.
|
||||
Original Idea and base for this implementation by Michael Kennedy's blog:
|
||||
https://mkennedy.codes/posts/python-supply-chain-security-made-easy/
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def test_pip_audit_no_vulnerabilities():
|
||||
"""
|
||||
Run pip-audit to check for known security vulnerabilities.
|
||||
|
||||
This test will fail if any vulnerabilities are detected in the installed packages.
|
||||
|
||||
Note: CVE-2025-53000 (nbconvert Windows vulnerability) is ignored as it only affects
|
||||
Windows platforms and is a known acceptable risk for this project.
|
||||
"""
|
||||
# Get the project root directory
|
||||
project_root = Path(__file__).parent.parent
|
||||
command = [
|
||||
sys.executable,
|
||||
"-m",
|
||||
"pip_audit",
|
||||
# "--format=json",
|
||||
"--progress-spinner=off",
|
||||
"--ignore-vuln",
|
||||
"CVE-2025-53000",
|
||||
"--skip-editable",
|
||||
]
|
||||
|
||||
# Run pip-audit with JSON output for easier parsing
|
||||
try:
|
||||
result = subprocess.run(
|
||||
command,
|
||||
cwd=project_root,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=120, # 2 minute timeout
|
||||
)
|
||||
except subprocess.TimeoutExpired:
|
||||
pytest.fail("pip-audit command timed out after 120 seconds")
|
||||
except FileNotFoundError:
|
||||
pytest.fail("pip-audit not installed or not accessible")
|
||||
|
||||
# Check if pip-audit found any vulnerabilities
|
||||
if result.returncode != 0:
|
||||
# pip-audit returns non-zero when vulnerabilities are found
|
||||
error_output = result.stdout + "\n" + result.stderr
|
||||
|
||||
# Check if it's an actual vulnerability vs an error
|
||||
if "vulnerabilities found" in error_output.lower() or '"dependencies"' in result.stdout:
|
||||
pytest.fail(
|
||||
f"pip-audit detected security vulnerabilities!\n\n"
|
||||
f"Output:\n{result.stdout}\n\n"
|
||||
f"Please review and update vulnerable packages.\n"
|
||||
f"Run manually with: {' '.join(command)}"
|
||||
)
|
||||
else:
|
||||
# Some other error occurred
|
||||
pytest.fail(
|
||||
f"pip-audit failed to run properly:\n\nReturn code: {result.returncode}\n"
|
||||
f"Output: {error_output}\n"
|
||||
)
|
||||
|
||||
# Success - no vulnerabilities found
|
||||
assert result.returncode == 0, "pip-audit should return 0 when no vulnerabilities are found"
|
||||
|
||||
|
||||
def test_pip_audit_runs_successfully():
|
||||
"""
|
||||
Verify that pip-audit can run successfully (even if vulnerabilities are found).
|
||||
|
||||
This is a smoke test to ensure pip-audit is properly installed and functional.
|
||||
"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
[sys.executable, "-m", "pip_audit", "--version"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10,
|
||||
)
|
||||
assert result.returncode == 0, f"pip-audit --version failed: {result.stderr}"
|
||||
assert "pip-audit" in result.stdout.lower(), "pip-audit version output unexpected"
|
||||
except FileNotFoundError:
|
||||
pytest.fail("pip-audit not installed")
|
||||
except subprocess.TimeoutExpired:
|
||||
pytest.fail("pip-audit --version timed out")
|
||||
1
tests/testdata/orderflow/candles.json
vendored
1
tests/testdata/orderflow/candles.json
vendored
File diff suppressed because one or more lines are too long
@@ -82,7 +82,7 @@ def test_dt_humanize() -> None:
|
||||
assert dt_humanize_delta(dt_now() - timedelta(minutes=50)) == "50 minutes ago"
|
||||
assert dt_humanize_delta(dt_now() - timedelta(hours=16)) == "16 hours ago"
|
||||
assert dt_humanize_delta(dt_now() - timedelta(hours=16, minutes=30)) == "16 hours ago"
|
||||
assert dt_humanize_delta(dt_now() - timedelta(days=16, hours=10, minutes=25)) == "16 days ago"
|
||||
assert dt_humanize_delta(dt_now() - timedelta(days=16, hours=10, minutes=25)) == "a month ago"
|
||||
assert dt_humanize_delta(dt_now() - timedelta(minutes=50)) == "50 minutes ago"
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user