Skip to content

Latest commit

 

History

History
898 lines (694 loc) · 21.9 KB

File metadata and controls

898 lines (694 loc) · 21.9 KB

Trading Platform Configuration - Contribution Guide

Welcome to the Trading Platform Configuration project! This guide will help you understand the development process, contribution standards, and best practices for extending and maintaining the configuration system.

Table of Contents

Getting Started

Prerequisites

Before contributing, ensure you have:

  • Python 3.7+ with pip
  • Node.js 16+ with npm
  • Git
  • Understanding of JSON Schema
  • Familiarity with trading/financial concepts

Quick Start

  1. Fork and clone the repository:

    git clone https://github.com/your-username/trading-platform.git
    cd trading-platform
  2. Set up development environment:

    # Create virtual environment
    python -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
    
    # Install dependencies
    pip install -r requirements.txt
    pip install -r requirements-dev.txt
    
    # Install Node.js tools
    npm install -g ajv-cli json-schema-to-markdown
  3. Validate your setup:

    # Run tests
    pytest
    
    # Validate schema
    ajv compile -s trading_platform.schema.json
    
    # Test configuration loading
    python -c "from config_loader import load_config; print('✅ Setup complete!')"

Development Environment Setup

Python Dependencies

Install development dependencies:

# Core dependencies
pip install pydantic>=2.0.0
pip install jsonschema>=4.0.0

# Development dependencies
pip install pytest>=7.0.0
pip install black>=23.0.0
pip install flake8>=5.0.0
pip install mypy>=1.0.0
pip install pre-commit>=3.0.0

Node.js Tools

Install JSON Schema tools:

# Schema validation and documentation
npm install -g ajv-cli
npm install -g json-schema-to-markdown
npm install -g @apidevtools/json-schema-ref-parser

# Optional: Interactive documentation
npm install -g docson-cli

Pre-commit Hooks

Set up pre-commit hooks for code quality:

# Install pre-commit
pip install pre-commit

# Install hooks
pre-commit install

# Test hooks
pre-commit run --all-files

IDE Configuration

VS Code Settings

Create .vscode/settings.json:

{
  "python.defaultInterpreterPath": "./venv/bin/python",
  "python.formatting.provider": "black",
  "python.linting.enabled": true,
  "python.linting.flake8Enabled": true,
  "python.linting.mypyEnabled": true,
  "files.exclude": {
    "**/__pycache__": true,
    "**/*.pyc": true,
    ".pytest_cache": true,
    ".mypy_cache": true
  },
  "json.schemas": [
    {
      "fileMatch": ["trading_platform.*.json"],
      "url": "./trading_platform.schema.json"
    }
  ]
}

Project Structure

trading-platform/
├── trading_platform.schema.json    # Main JSON Schema
├── config_loader.py               # Python configuration loader
├── integration_example.py         # Usage examples
├── trading_platform.example.json  # Example configuration
├──
├── docs/                          # Documentation
│   ├── SCHEMA_USAGE_GUIDE.md     # Schema usage and extension guide
│   ├── CONTRIBUTION_GUIDE.md     # This file
│   └── API_REFERENCE.md          # Auto-generated API docs
├──
├── tests/                         # Test suite
│   ├── test_schema_validation.py # Schema validation tests
│   ├── test_config_loader.py     # Configuration loader tests
│   ├── test_examples.py          # Example validation tests
│   └── fixtures/                 # Test data
├──
├── scripts/                       # Utility scripts
│   ├── validate_schema.py        # Schema validation script
│   ├── generate_docs.py          # Documentation generation
│   └── release_tools.py          # Release automation
├──
└── .github/                      # GitHub Actions
    └── workflows/
        ├── ci.yml               # Continuous integration
        ├── docs.yml             # Documentation updates
        └── release.yml          # Release automation

Key Files

  • trading_platform.schema.json: The main JSON Schema defining configuration structure
  • config_loader.py: Python module for loading and validating configurations
  • integration_example.py: Comprehensive example showing how to use the system
  • trading_platform.example.json: Complete example configuration
  • docs/SCHEMA_USAGE_GUIDE.md: Detailed guide for using and extending the schema

Contribution Process

1. Issue Creation

Before starting work, create or find an issue:

  • Bug Reports: Use the bug report template
  • Feature Requests: Use the feature request template
  • Documentation: Use the documentation template

2. Branch Naming

Use descriptive branch names:

# Feature branches
feature/add-td-ameritrade-broker
feature/deep-learning-models
feature/risk-management-enhancements

# Bug fixes
fix/schema-validation-error
fix/credential-loading-issue

# Documentation
docs/broker-integration-guide
docs/api-reference-update

# Maintenance
chore/update-dependencies
chore/improve-test-coverage

3. Development Workflow

# 1. Create feature branch
git checkout -b feature/your-feature-name

# 2. Make changes
# ... implement your changes ...

# 3. Run tests
pytest
ajv compile -s trading_platform.schema.json

# 4. Format code
black .
flake8 .

# 5. Update documentation
python scripts/generate_docs.py

# 6. Commit changes
git add .
git commit -m "feat: add support for TD Ameritrade broker

- Add TD Ameritrade broker configuration schema
- Update example configuration
- Add integration tests
- Update documentation

Resolves #123"

# 7. Push and create PR
git push origin feature/your-feature-name

4. Commit Messages

Follow Conventional Commits:

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

Types:

  • feat: New features
  • fix: Bug fixes
  • docs: Documentation changes
  • style: Code style changes
  • refactor: Code refactoring
  • test: Test additions/modifications
  • chore: Maintenance tasks

Examples:

feat(brokers): add TD Ameritrade integration

fix(schema): resolve validation error for crypto exchanges

docs(api): update broker configuration examples

test(config): add comprehensive validation tests

Schema Development

Adding New Sections

  1. Plan the schema structure:

    {
      "new_section": {
        "type": "object",
        "description": "Description of the new section",
        "properties": {
          "setting1": {
            "type": "string",
            "description": "Description of setting1"
          }
        }
      }
    }
  2. Add to main schema:

    {
      "properties": {
        "existing_section": { /* ... */ },
        "new_section": {
          "$ref": "#/$defs/new_section_config"
        }
      }
    }
  3. Create reusable definitions:

    {
      "$defs": {
        "new_section_config": {
          "type": "object",
          "description": "Comprehensive description",
          "properties": { /* ... */ },
          "required": ["required_field"],
          "additionalProperties": false
        }
      }
    }
  4. Update examples and tests:

    {
      "new_section": {
        "setting1": "example_value"
      }
    }

Schema Validation Rules

  1. Always use descriptions:

    {
      "property_name": {
        "type": "string",
        "description": "Clear description of what this property does"
      }
    }
  2. Set appropriate constraints:

    {
      "port": {
        "type": "integer",
        "minimum": 1024,
        "maximum": 65535,
        "description": "Network port number"
      }
    }
  3. Use enums for limited choices:

    {
      "log_level": {
        "type": "string",
        "enum": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
        "default": "INFO"
      }
    }
  4. Leverage $refs for reusability:

    {
      "database_config": {
        "$ref": "#/$defs/connection_config"
      }
    }

Code Standards

Python Code Style

Follow PEP 8 and use these tools:

# Format code
black config_loader.py

# Check style
flake8 config_loader.py

# Type checking
mypy config_loader.py

Type Annotations

Use comprehensive type hints:

from typing import Optional, Dict, Any, List, Union
from pydantic import BaseModel, Field

class BrokerConfig(BaseModel):
    """Broker configuration model"""

    credentials: CredentialsConfig
    base_url: Optional[str] = Field(None, description="API base URL")
    supported_assets: List[str] = Field(default_factory=list)

    def get_api_key(self) -> Optional[str]:
        """Get API key from credentials"""
        if self.credentials.api_key:
            return self.credentials.api_key
        return None

Documentation Strings

Use comprehensive docstrings:

class ConfigurationLoader:
    """Trading platform configuration loader.

    This class provides methods to load, validate, and access trading
    platform configurations from JSON files. It supports environment
    variable resolution and comprehensive validation.

    Attributes:
        config_path: Path to the configuration file
        config: Loaded and validated configuration

    Example:
        >>> loader = ConfigurationLoader('config.json')
        >>> config = loader.load_config()
        >>> openbb_config = loader.get_openbb_config()
    """

    def load_config(self) -> TradingPlatformConfig:
        """Load and validate configuration.

        Returns:
            Validated trading platform configuration

        Raises:
            FileNotFoundError: If configuration file doesn't exist
            ValueError: If configuration is invalid
            JSONDecodeError: If JSON is malformed
        """

Error Handling

Provide clear error messages:

def load_config(self) -> TradingPlatformConfig:
    """Load configuration with comprehensive error handling"""

    if not self.config_path.exists():
        raise FileNotFoundError(
            f"Configuration file not found: {self.config_path}\n"
            f"Create a configuration file or use the default example."
        )

    try:
        with open(self.config_path, 'r') as f:
            config_data = json.load(f)
    except json.JSONDecodeError as e:
        raise ValueError(
            f"Invalid JSON in configuration file {self.config_path}:\n"
            f"Line {e.lineno}, Column {e.colno}: {e.msg}"
        ) from e

    try:
        return TradingPlatformConfig(**config_data)
    except ValidationError as e:
        raise ValueError(
            f"Configuration validation failed:\n"
            f"{self._format_validation_errors(e.errors())}"
        ) from e

Testing Guidelines

Test Structure

Organize tests by component:

# tests/test_config_loader.py
import pytest
from config_loader import ConfigurationLoader, TradingPlatformConfig

class TestConfigurationLoader:
    """Test configuration loader functionality"""

    def test_load_valid_config(self, valid_config_file):
        """Test loading a valid configuration"""
        loader = ConfigurationLoader(valid_config_file)
        config = loader.load_config()

        assert isinstance(config, TradingPlatformConfig)
        assert config.metadata.version == "1.0.0"

    def test_invalid_config_raises_error(self, invalid_config_file):
        """Test that invalid configurations raise appropriate errors"""
        loader = ConfigurationLoader(invalid_config_file)

        with pytest.raises(ValueError) as exc_info:
            loader.load_config()

        assert "validation failed" in str(exc_info.value)

    @pytest.mark.parametrize("broker_name,expected_type", [
        ("alpaca", "AlpacaConfig"),
        ("interactive_brokers", "InteractiveBrokersConfig"),
    ])
    def test_broker_config_access(self, broker_name, expected_type, config_loader):
        """Test broker configuration access"""
        broker_config = config_loader.get_broker_config(broker_name)
        assert broker_config is not None
        assert type(broker_config).__name__ == expected_type

Test Fixtures

Create reusable test data:

# tests/conftest.py
import pytest
import tempfile
import json
from pathlib import Path

@pytest.fixture
def valid_config_data():
    """Valid configuration data for testing"""
    return {
        "metadata": {
            "version": "1.0.0",
            "environment": "testing"
        },
        "data": {
            "providers": {
                "openbb": {
                    "credentials": {
                        "environment_variable": "${TEST_API_KEY}"
                    }
                }
            }
        },
        # ... rest of configuration
    }

@pytest.fixture
def valid_config_file(valid_config_data):
    """Temporary file with valid configuration"""
    with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
        json.dump(valid_config_data, f)
        return Path(f.name)

@pytest.fixture
def config_loader(valid_config_file):
    """Configured loader instance"""
    from config_loader import ConfigurationLoader
    return ConfigurationLoader(valid_config_file)

Schema Testing

Test schema validation thoroughly:

# tests/test_schema_validation.py
import json
import jsonschema
import pytest

class TestSchemaValidation:
    """Test JSON Schema validation"""

    @pytest.fixture
    def schema(self):
        """Load the main schema"""
        with open('trading_platform.schema.json') as f:
            return json.load(f)

    def test_schema_is_valid(self, schema):
        """Test that the schema itself is valid"""
        jsonschema.Draft7Validator.check_schema(schema)

    def test_example_validates(self, schema):
        """Test that example configuration validates"""
        with open('trading_platform.example.json') as f:
            example = json.load(f)

        jsonschema.validate(example, schema)

    @pytest.mark.parametrize("invalid_config", [
        {"metadata": {}},  # Missing required fields
        {"metadata": {"version": "1.0.0", "environment": "invalid"}},  # Invalid enum
        # Add more invalid configurations
    ])
    def test_invalid_configs_fail(self, schema, invalid_config):
        """Test that invalid configurations fail validation"""
        with pytest.raises(jsonschema.ValidationError):
            jsonschema.validate(invalid_config, schema)

Integration Testing

Test end-to-end functionality:

# tests/test_integration.py
import os
import pytest
from unittest.mock import patch

class TestIntegration:
    """Integration tests for the complete system"""

    def test_environment_variable_resolution(self, config_loader):
        """Test that environment variables are resolved correctly"""
        with patch.dict(os.environ, {'TEST_API_KEY': 'test_key_123'}):
            config = config_loader.load_config()
            openbb_config = config_loader.get_openbb_config()

            assert openbb_config.credentials.api_key == 'test_key_123'

    def test_broker_integration_workflow(self, config_loader):
        """Test complete broker integration workflow"""
        config = config_loader.load_config()

        # Test Alpaca configuration
        alpaca_config = config_loader.get_broker_config('alpaca')
        assert alpaca_config is not None
        assert alpaca_config.base_url is not None

        # Test Interactive Brokers configuration
        ib_config = config_loader.get_broker_config('interactive_brokers')
        assert ib_config is not None
        assert ib_config.gateway_port > 0

Documentation Requirements

Code Documentation

  1. Module docstrings:

    """Trading Platform Configuration Loader
    
    This module provides utilities for loading and validating trading platform
    configurations using JSON Schema and Pydantic models.
    
    The module supports:
    - Multiple data providers (OpenBB, Polygon, crypto exchanges)
    - Broker integrations (Alpaca, Interactive Brokers)
    - Risk management configuration
    - Environment variable resolution
    
    Example:
        Basic usage:
    
        >>> from config_loader import load_config
        >>> config = load_config('trading_platform.example.json')
        >>> print(f"Environment: {config.metadata.environment}")
    """
  2. Class and method documentation:

    class ConfigurationLoader:
        """Load and validate trading platform configurations."""
    
        def get_risk_limits(self, asset_class: Optional[str] = None) -> Optional[RiskLimitsConfig]:
            """Get risk limits for specified asset class or portfolio level.
    
            Args:
                asset_class: Asset class name ('equities', 'crypto', etc.) or None for portfolio level
    
            Returns:
                Risk limits configuration or None if not found
    
            Example:
                >>> portfolio_limits = loader.get_risk_limits()
                >>> crypto_limits = loader.get_risk_limits('crypto')
            """

Schema Documentation

Document schema properties thoroughly:

{
  "broker_timeout": {
    "type": "integer",
    "description": "Connection timeout for broker API calls in seconds. This value determines how long the system will wait for a response from the broker's API before timing out. Recommended values: 30-60 seconds for production, 10-30 seconds for development.",
    "minimum": 5,
    "maximum": 300,
    "default": 30
  }
}

Changelog Maintenance

Keep CHANGELOG.md updated:

# Changelog

All notable changes to this project will be documented in this file.

## [1.2.0] - 2024-01-15

### Added
- Support for TD Ameritrade broker integration
- Deep learning models configuration section
- Enhanced risk management features
- Interactive documentation generation

### Changed
- Updated OpenBB integration for v4.0 compatibility
- Improved error messages for configuration validation
- Enhanced example configurations with more comprehensive settings

### Fixed
- Fixed credential loading from environment variables
- Resolved schema validation errors for complex configurations
- Fixed documentation generation script compatibility

### Deprecated
- Legacy broker authentication methods (will be removed in v2.0)

## [1.1.0] - 2024-01-01

### Added
- Initial release with core functionality

Review Process

Pull Request Requirements

Before submitting a PR, ensure:

  1. Tests pass:

    pytest --cov=. --cov-report=html
  2. Schema validates:

    ajv compile -s trading_platform.schema.json
    ajv validate -s trading_platform.schema.json -d trading_platform.example.json
  3. Code is formatted:

    black .
    flake8 .
    mypy .
  4. Documentation is updated:

    python scripts/generate_docs.py

PR Template

Use this template for pull requests:

## Description
Brief description of changes and motivation.

## Type of Change
- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that causes existing functionality to change)
- [ ] Documentation update

## Changes Made
- List specific changes
- Include schema modifications
- Note any new dependencies

## Testing
- [ ] All existing tests pass
- [ ] New tests added for new functionality
- [ ] Schema validation passes
- [ ] Example configurations validate

## Documentation
- [ ] Code is well-documented
- [ ] Schema changes are documented
- [ ] Examples are updated
- [ ] Changelog is updated

## Checklist
- [ ] Code follows project style guidelines
- [ ] Self-review completed
- [ ] Linked to relevant issue(s)
- [ ] Ready for review

Review Criteria

Reviewers should check:

  1. Code Quality:

    • Follows project conventions
    • Proper error handling
    • Comprehensive type hints
    • Clear documentation
  2. Schema Design:

    • Proper validation rules
    • Clear descriptions
    • Backward compatibility
    • Reusable patterns
  3. Testing:

    • Adequate test coverage
    • Edge cases covered
    • Integration tests included
  4. Documentation:

    • Clear and comprehensive
    • Examples are working
    • API documentation updated

Release Process

Versioning

Follow Semantic Versioning:

  • MAJOR: Breaking changes
  • MINOR: New features (backward compatible)
  • PATCH: Bug fixes (backward compatible)

Release Steps

  1. Prepare release:

    # Update version in schema
    # Update CHANGELOG.md
    # Run full test suite
    pytest
    
    # Validate all configurations
    python scripts/validate_all_configs.py
    
    # Generate documentation
    python scripts/generate_docs.py
  2. Create release PR:

    git checkout -b release/v1.2.0
    # Make version updates
    git commit -m "chore: prepare v1.2.0 release"
    git push origin release/v1.2.0
  3. Tag and publish:

    git tag -a v1.2.0 -m "Release v1.2.0"
    git push origin v1.2.0

Release Automation

The project uses GitHub Actions for automated releases:

  • CI Pipeline: Runs tests and validation on all PRs
  • Documentation: Auto-generates docs on schema changes
  • Release: Creates releases on version tags

Getting Help

  • Issues: Create GitHub issues for bugs and feature requests
  • Discussions: Use GitHub Discussions for questions and ideas
  • Documentation: Check the comprehensive guides in /docs/
  • Examples: Review integration_example.py for usage patterns

Thank you for contributing to the Trading Platform Configuration project!