Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .github/actions/ci/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Plugin Checks
description: The checks every change to the plugin passes, run from the directory holding its pyproject.toml.

inputs:
directory:
description: The directory holding the plugin's pyproject.toml.
required: false
default: "."
python-version:
description: The Python version the checks run under.
required: false
default: "3.13"

runs:
using: composite
steps:
- name: Install uv
uses: astral-sh/setup-uv@v10.0.1
with:
enable-cache: true
python-version: ${{ inputs.python-version }}

- name: Install Dependencies
shell: bash
working-directory: ${{ inputs.directory }}
run: uv sync

- name: Run Formatter Check
shell: bash
working-directory: ${{ inputs.directory }}
run: uv run ruff format --check

- name: Run Linter
shell: bash
working-directory: ${{ inputs.directory }}
run: uv run ruff check

- name: Run Static Type Checking
shell: bash
working-directory: ${{ inputs.directory }}
run: uv run mypy

- name: Run Tests (with coverage)
shell: bash
working-directory: ${{ inputs.directory }}
run: uv run pytest --cov=src --cov-report=term

- name: Bandit Security Analysis
shell: bash
working-directory: ${{ inputs.directory }}
run: uv run bandit -c pyproject.toml --recursive src --exclude tests
25 changes: 25 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: CI Pipeline

on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened, ready_for_review]

jobs:
ci:
name: Continuous Integration
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.13]
steps:
- name: Checkout Repository
uses: actions/checkout@v7

- name: Run the Plugin Checks
uses: ./.github/actions/ci
with:
python-version: ${{ matrix.python-version }}
54 changes: 53 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "robottraderslab-envelope"
version = "0.1.0"
version = "0.1.1"
description = "Envelope trading strategy plugin for the RobotTradersLab engine"
readme = "README.md"
requires-python = ">=3.13,<3.14"
Expand Down Expand Up @@ -32,3 +32,55 @@ build-backend = "uv_build"

[tool.uv.build-backend]
module-name = "robottraderslab_envelope"

[dependency-groups]
dev = [
"bandit[toml]==1.9.4",
"mypy==1.20.0",
"pandas-stubs==3.0.0.260204",
"pytest==9.0.3",
"pytest-asyncio==1.3.0",
"pytest-cov==7.1.0",
"ruff==0.15.10",
]

[tool.coverage.run]
omit = ["*/tests/*", "*/test_*.py"]

[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
filterwarnings = [
"ignore:enable_cleanup_closed ignored because.*:DeprecationWarning:aiohttp.connector",
]

[tool.mypy]
packages = ["robottraderslab_envelope"]
follow_imports = "normal"
python_version = "3.13"
color_output = true
show_error_codes = true
check_untyped_defs = true
disallow_untyped_defs = true
no_implicit_optional = true
warn_return_any = true
warn_unreachable = true
warn_unused_ignores = true
ignore_missing_imports = true
namespace_packages = true
incremental = true
cache_dir = ".mypy_cache"
exclude = '^(build/|dist/|\.venv/|.*tests/)'

[tool.bandit]
skips = ["B101"]

[tool.ruff]
target-version = "py313"

[tool.ruff.lint]
extend-select = ["I", "PT"]

[tool.ruff.lint.isort]
known-first-party = ["robottraderslab"]
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ ohlcv_provider = "ccxt_bitget"
ohlcv_provider = "bitget"

[live.trading_account]
exchange = "bitget"
demo_trading = true
secret_name = "envelope-example"

[report]
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from unittest.mock import Mock

import pytest
from robottraderslab_envelope import EnvelopeStrategy

from robottraderslab.exchanges import FuturesExchangeProtocol
from robottraderslab.strategies import Balance, TradingMode, TradingSystem
Expand All @@ -14,6 +13,7 @@
MarginMode,
MarginSettings,
)
from robottraderslab_envelope import EnvelopeStrategy


@pytest.fixture
Expand Down
2 changes: 1 addition & 1 deletion tests/test_envelope_book_trading_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import pandas as pd
import pytest
from robottraderslab_envelope import EnvelopeStrategy

from robottraderslab import Symbol
from robottraderslab.exchanges import OrderType
Expand Down Expand Up @@ -37,6 +36,7 @@
UpdatePositionStopLossAction,
UpdatePositionTakeProfitAction,
)
from robottraderslab_envelope import EnvelopeStrategy

BTC = Symbol.create("BTC/USDT:USDT")
ACCOUNT_NAME = "test"
Expand Down
2 changes: 1 addition & 1 deletion tests/test_envelope_chart_indicators.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import numpy as np
import pytest
from robottraderslab_envelope.chart_indicators import get_lightweight_chart_indicators

from robottraderslab.strategies import Candles, ChartLine
from robottraderslab_envelope.chart_indicators import get_lightweight_chart_indicators

CLOSES = np.array([100.0 + i * 2.0 for i in range(50)])
CANDLES = Candles(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_envelope_entry_order.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from unittest.mock import Mock

import pytest
from robottraderslab_envelope.entry_order import LimitEntryOrder, TriggerEntryOrder

from robottraderslab.strategies.futures import FuturesOrderBuilder
from robottraderslab_envelope.entry_order import LimitEntryOrder, TriggerEntryOrder


@pytest.fixture
Expand Down
2 changes: 1 addition & 1 deletion tests/test_envelope_generate_trading_signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import pandas as pd
import pytest
from robottraderslab_envelope import EnvelopeStrategy

from robottraderslab import Symbol
from robottraderslab.exceptions import MissingOhlcvDataError
from robottraderslab.strategies import OHLCVs, TradingMode
from robottraderslab_envelope import EnvelopeStrategy

BTC = Symbol.create("BTC/USDT:USDT")
TIMEFRAME = "1d"
Expand Down
4 changes: 2 additions & 2 deletions tests/test_envelope_indicator.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import pandas as pd
import pytest
from robottraderslab_envelope.envelope_indicator import compute_envelope
from robottraderslab_envelope.profile_config import AverageType

from robottraderslab.indicators import MAType
from robottraderslab.strategies import PositionSide
from robottraderslab_envelope.envelope_indicator import compute_envelope
from robottraderslab_envelope.profile_config import AverageType

LONG = PositionSide.LONG
SHORT = PositionSide.SHORT
Expand Down
2 changes: 1 addition & 1 deletion tests/test_envelope_profile_config.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import re

import pytest
from robottraderslab_envelope.profile_config import AverageType, ProfileConfig

from robottraderslab.exceptions import StrategyCriticalError
from robottraderslab.strategies import PositionSide
from robottraderslab.strategies.futures import (
MarginMode,
TotalBalanceRatio,
)
from robottraderslab_envelope.profile_config import AverageType, ProfileConfig

SYMBOL = "BTC/USDT:USDT"
LONG = PositionSide.LONG
Expand Down
2 changes: 1 addition & 1 deletion tests/test_envelope_profile_isolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from datetime import datetime

import pandas as pd
from robottraderslab_envelope import EnvelopeStrategy

from robottraderslab import Symbol
from robottraderslab.strategies import (
Expand All @@ -20,6 +19,7 @@
MarginMode,
MarginSettings,
)
from robottraderslab_envelope import EnvelopeStrategy

BTC = Symbol.create("BTC/USDT:USDT")
ETH = Symbol.create("ETH/USDT:USDT")
Expand Down
14 changes: 7 additions & 7 deletions tests/test_envelope_profile_snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@

import pandas as pd
import pytest
from robottraderslab_envelope.entry_order import (
EntryOrder,
LimitEntryOrder,
TriggerEntryOrder,
)
from robottraderslab_envelope.profile_config import AverageType, ProfileConfig
from robottraderslab_envelope.profile_snapshot import ProfileSnapshot

from robottraderslab import Symbol
from robottraderslab.strategies import (
Expand All @@ -24,6 +17,13 @@
MarginSettings,
TotalBalanceRatio,
)
from robottraderslab_envelope.entry_order import (
EntryOrder,
LimitEntryOrder,
TriggerEntryOrder,
)
from robottraderslab_envelope.profile_config import AverageType, ProfileConfig
from robottraderslab_envelope.profile_snapshot import ProfileSnapshot

BTC = Symbol.create("BTC/USDT:USDT")
TIMEFRAME = "1h"
Expand Down
2 changes: 1 addition & 1 deletion tests/test_envelope_reentry_guard.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

import pandas as pd
import pytest
from robottraderslab_envelope.reentry_guard import ReentryGuard, ReentryState

from robottraderslab import Symbol
from robottraderslab.strategies import Execution, OHLCVs, OrderSide, PositionSide
from robottraderslab_envelope.reentry_guard import ReentryGuard, ReentryState

BTC = Symbol.create("BTC/USDT:USDT")
ETH = Symbol.create("ETH/USDT:USDT")
Expand Down
4 changes: 2 additions & 2 deletions tests/test_envelope_reentry_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

import pandas as pd
import pytest
from robottraderslab_envelope import EnvelopeStrategy
from robottraderslab_envelope.reentry_guard import ReentryGuard

from robottraderslab import Symbol
from robottraderslab.backtester.simulator import (
Expand All @@ -29,6 +27,8 @@
FuturesMarketOrderAction,
FuturesOrderBatchAction,
)
from robottraderslab_envelope import EnvelopeStrategy
from robottraderslab_envelope.reentry_guard import ReentryGuard

BTC = Symbol.create("BTC/USDT:USDT")
ETH = Symbol.create("ETH/USDT:USDT")
Expand Down
2 changes: 1 addition & 1 deletion tests/test_envelope_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
from typing import Any

import pytest
from robottraderslab_envelope import EnvelopeStrategy

from robottraderslab import Symbol
from robottraderslab.exceptions import StrategyCriticalError
from robottraderslab.strategies import StrategyRequirements
from robottraderslab_envelope import EnvelopeStrategy


def _sized_profile(
Expand Down
Loading