Spaces:
Sleeping
Sleeping
| # 👨💻 Guia do Desenvolvedor | |
| ## Visão Geral | |
| Este guia fornece informações essenciais para desenvolvedores que desejam contribuir ou estender o Vampire Trading Bot. Inclui padrões de código, arquitetura, fluxos de desenvolvimento e melhores práticas. | |
| ## 🏗️ Arquitetura do Sistema | |
| ### Estrutura Modular | |
| ``` | |
| vampire-trading-bot/ | |
| ├── app.py # Ponto de entrada principal | |
| ├── config.py # Configurações centralizadas | |
| ├── ui.py # Interface Gradio | |
| ├── market_analysis.py # Análise técnica | |
| ├── sentiment_analysis.py # Análise de sentimento | |
| ├── fibonacci_analysis.py # Análise de Fibonacci | |
| ├── log_parser.py # Parser de logs | |
| ├── real_time_integration.py # Integração tempo real | |
| ├── performance_monitor.py # Monitoramento | |
| ├── utils.py # Utilitários | |
| ├── docs/ # Documentação | |
| └── tests/ # Testes automatizados | |
| ``` | |
| ### Princípios de Design | |
| 1. **Separação de Responsabilidades**: Cada módulo tem uma função específica | |
| 2. **Baixo Acoplamento**: Módulos independentes com interfaces bem definidas | |
| 3. **Alta Coesão**: Funcionalidades relacionadas agrupadas | |
| 4. **Extensibilidade**: Fácil adição de novos recursos | |
| 5. **Testabilidade**: Código facilmente testável | |
| ## 🔧 Configuração do Ambiente de Desenvolvimento | |
| ### Pré-requisitos | |
| ```bash | |
| # Python 3.8+ | |
| python --version | |
| # Git | |
| git --version | |
| # Editor recomendado: VS Code com extensões Python | |
| ``` | |
| ### Setup Inicial | |
| ```bash | |
| # 1. Clonar repositório | |
| git clone <repository-url> | |
| cd vampire-trading-bot | |
| # 2. Criar ambiente virtual | |
| python -m venv venv | |
| # 3. Ativar ambiente | |
| # Windows | |
| venv\Scripts\activate | |
| # Linux/macOS | |
| source venv/bin/activate | |
| # 4. Instalar dependências de desenvolvimento | |
| pip install -r requirements-dev.txt | |
| # 5. Instalar hooks de pre-commit | |
| pre-commit install | |
| ``` | |
| ### Dependências de Desenvolvimento | |
| ```txt | |
| # requirements-dev.txt | |
| pytest>=7.0.0 | |
| pytest-cov>=4.0.0 | |
| black>=22.0.0 | |
| flake8>=5.0.0 | |
| mypy>=1.0.0 | |
| pre-commit>=2.20.0 | |
| bandit>=1.7.0 | |
| isort>=5.10.0 | |
| memory-profiler>=0.60.0 | |
| line-profiler>=4.0.0 | |
| ``` | |
| ## 📝 Padrões de Código | |
| ### Estilo de Código | |
| **Formatação com Black**: | |
| ```bash | |
| # Formatar código | |
| black . | |
| # Verificar formatação | |
| black --check . | |
| ``` | |
| **Linting com Flake8**: | |
| ```bash | |
| # Verificar código | |
| flake8 . | |
| # Configuração em .flake8 | |
| [flake8] | |
| max-line-length = 88 | |
| ignore = E203, W503 | |
| exclude = venv, __pycache__ | |
| ``` | |
| **Ordenação de Imports com isort**: | |
| ```bash | |
| # Ordenar imports | |
| isort . | |
| # Configuração em pyproject.toml | |
| [tool.isort] | |
| profile = "black" | |
| line_length = 88 | |
| ``` | |
| ### Convenções de Nomenclatura | |
| ```python | |
| # Classes: PascalCase | |
| class TechnicalAnalysisEngine: | |
| pass | |
| # Funções e variáveis: snake_case | |
| def calculate_rsi_value(prices: List[float]) -> float: | |
| pass | |
| # Constantes: UPPER_SNAKE_CASE | |
| DEFAULT_RSI_PERIOD = 14 | |
| MAX_RETRY_ATTEMPTS = 3 | |
| # Arquivos: snake_case | |
| # market_analysis.py | |
| # sentiment_analysis.py | |
| ``` | |
| ### Documentação de Código | |
| ```python | |
| def analyze_market_data( | |
| self, | |
| text: str, | |
| include_fibonacci: bool = True | |
| ) -> Dict[str, Any]: | |
| """ | |
| Analisa dados de mercado extraindo indicadores técnicos. | |
| Args: | |
| text: Texto contendo dados de mercado | |
| include_fibonacci: Se deve incluir análise de Fibonacci | |
| Returns: | |
| Dict contendo: | |
| - technical_signals: Lista de sinais técnicos | |
| - market_data: Dados extraídos do mercado | |
| - fibonacci_analysis: Análise de Fibonacci (se habilitada) | |
| Raises: | |
| ValueError: Se o texto não contém dados válidos | |
| RuntimeError: Se falha na análise técnica | |
| Example: | |
| >>> engine = TechnicalAnalysisEngine() | |
| >>> result = engine.analyze_market_data("WINV25: 140135") | |
| >>> print(result['technical_signals']) | |
| """ | |
| pass | |
| ``` | |
| ### Type Hints | |
| ```python | |
| from typing import List, Dict, Optional, Union, Tuple, Any | |
| from dataclasses import dataclass | |
| from enum import Enum | |
| # Usar type hints em todas as funções | |
| def calculate_ema( | |
| prices: List[float], | |
| period: int | |
| ) -> List[float]: | |
| pass | |
| # Dataclasses para estruturas de dados | |
| @dataclass | |
| class MarketData: | |
| symbol: str | |
| price: float | |
| volume: int | |
| timestamp: Optional[str] = None | |
| # Enums para constantes | |
| class SignalType(Enum): | |
| BUY = "buy" | |
| SELL = "sell" | |
| HOLD = "hold" | |
| ``` | |
| ## 🧪 Testes | |
| ### Estrutura de Testes | |
| ``` | |
| tests/ | |
| ├── __init__.py | |
| ├── conftest.py # Fixtures compartilhadas | |
| ├── test_market_analysis.py # Testes análise técnica | |
| ├── test_sentiment_analysis.py # Testes análise sentimento | |
| ├── test_fibonacci_analysis.py # Testes Fibonacci | |
| ├── test_integration.py # Testes integração | |
| ├── test_performance.py # Testes performance | |
| └── fixtures/ # Dados de teste | |
| ├── sample_logs.txt | |
| └── market_data.json | |
| ``` | |
| ### Escrevendo Testes | |
| ```python | |
| # test_market_analysis.py | |
| import pytest | |
| from unittest.mock import Mock, patch | |
| from market_analysis import TechnicalAnalysisEngine, MarketData | |
| class TestTechnicalAnalysisEngine: | |
| @pytest.fixture | |
| def engine(self): | |
| """Fixture para engine de análise.""" | |
| return TechnicalAnalysisEngine() | |
| @pytest.fixture | |
| def sample_market_data(self): | |
| """Fixture para dados de mercado.""" | |
| return MarketData( | |
| symbol="WINV25", | |
| price=140135.0, | |
| volume=5023 | |
| ) | |
| def test_analyze_market_data_success(self, engine, sample_market_data): | |
| """Testa análise bem-sucedida de dados de mercado.""" | |
| text = "WINV25: 140135, Volume: 5023" | |
| result = engine.analyze_market_data(text) | |
| assert "technical_signals" in result | |
| assert "market_data" in result | |
| assert len(result["technical_signals"]) > 0 | |
| def test_analyze_market_data_invalid_input(self, engine): | |
| """Testa comportamento com entrada inválida.""" | |
| with pytest.raises(ValueError, match="Dados inválidos"): | |
| engine.analyze_market_data("") | |
| @patch('market_analysis.calculate_rsi') | |
| def test_rsi_calculation_called(self, mock_rsi, engine): | |
| """Testa se cálculo RSI é chamado.""" | |
| mock_rsi.return_value = 65.5 | |
| text = "WINV25: 140135" | |
| engine.analyze_market_data(text) | |
| mock_rsi.assert_called_once() | |
| @pytest.mark.parametrize("price,expected_signal", [ | |
| (140000, "buy"), | |
| (145000, "sell"), | |
| (142500, "hold") | |
| ]) | |
| def test_signal_generation(self, engine, price, expected_signal): | |
| """Testa geração de sinais para diferentes preços.""" | |
| text = f"WINV25: {price}" | |
| result = engine.analyze_market_data(text) | |
| signal = result["technical_signals"][0] | |
| assert signal["action"] == expected_signal | |
| ``` | |
| ### Executando Testes | |
| ```bash | |
| # Executar todos os testes | |
| pytest | |
| # Executar com cobertura | |
| pytest --cov=. --cov-report=html | |
| # Executar testes específicos | |
| pytest tests/test_market_analysis.py::TestTechnicalAnalysisEngine::test_analyze_market_data_success | |
| # Executar testes em paralelo | |
| pytest -n auto | |
| # Executar apenas testes rápidos | |
| pytest -m "not slow" | |
| ``` | |
| ### Fixtures Compartilhadas | |
| ```python | |
| # conftest.py | |
| import pytest | |
| from pathlib import Path | |
| @pytest.fixture | |
| def sample_log_content(): | |
| """Conteúdo de log de exemplo.""" | |
| return """ | |
| ⏰ Análise #1 - 09:46:58 | |
| 📊 DADOS DE MERCADO - WINV25 | |
| Preço Atual: 140135.00000 ↗ | |
| Variação: +5 (+0.00%) | |
| Volume: 5023 | |
| """ | |
| @pytest.fixture | |
| def temp_log_file(tmp_path, sample_log_content): | |
| """Arquivo de log temporário.""" | |
| log_file = tmp_path / "test_log.txt" | |
| log_file.write_text(sample_log_content) | |
| return log_file | |
| @pytest.fixture | |
| def mock_ai_model(): | |
| """Mock do modelo de IA.""" | |
| from unittest.mock import Mock | |
| model = Mock() | |
| model.predict.return_value = [ | |
| {"label": "POSITIVE", "score": 0.85} | |
| ] | |
| return model | |
| ``` | |
| ## 🔄 Fluxo de Desenvolvimento | |
| ### Git Workflow | |
| ```bash | |
| # 1. Criar branch para feature | |
| git checkout -b feature/nova-funcionalidade | |
| # 2. Fazer commits pequenos e frequentes | |
| git add . | |
| git commit -m "feat: adiciona cálculo de MACD" | |
| # 3. Push da branch | |
| git push origin feature/nova-funcionalidade | |
| # 4. Criar Pull Request | |
| # 5. Code Review | |
| # 6. Merge após aprovação | |
| ``` | |
| ### Convenções de Commit | |
| ```bash | |
| # Formato: tipo(escopo): descrição | |
| # Tipos: | |
| feat: nova funcionalidade | |
| fix: correção de bug | |
| docs: documentação | |
| style: formatação | |
| refactor: refatoração | |
| test: testes | |
| chore: tarefas de manutenção | |
| # Exemplos: | |
| feat(analysis): adiciona indicador MACD | |
| fix(ui): corrige erro na interface | |
| docs(api): atualiza documentação da API | |
| test(fibonacci): adiciona testes para análise | |
| ``` | |
| ### Pre-commit Hooks | |
| ```yaml | |
| # .pre-commit-config.yaml | |
| repos: | |
| - repo: https://github.com/psf/black | |
| rev: 22.10.0 | |
| hooks: | |
| - id: black | |
| language_version: python3 | |
| - repo: https://github.com/pycqa/flake8 | |
| rev: 5.0.4 | |
| hooks: | |
| - id: flake8 | |
| - repo: https://github.com/pycqa/isort | |
| rev: 5.10.1 | |
| hooks: | |
| - id: isort | |
| - repo: https://github.com/pre-commit/mirrors-mypy | |
| rev: v0.991 | |
| hooks: | |
| - id: mypy | |
| additional_dependencies: [types-all] | |
| - repo: https://github.com/PyCQA/bandit | |
| rev: 1.7.4 | |
| hooks: | |
| - id: bandit | |
| args: ['-r', '.', '-f', 'json', '-o', 'bandit-report.json'] | |
| ``` | |
| ## 🏗️ Adicionando Novas Funcionalidades | |
| ### 1. Novo Indicador Técnico | |
| ```python | |
| # Em market_analysis.py | |
| class MACDAnalyzer(BaseAnalyzer): | |
| """Analisador MACD (Moving Average Convergence Divergence).""" | |
| def __init__(self, fast_period: int = 12, slow_period: int = 26, signal_period: int = 9): | |
| self.fast_period = fast_period | |
| self.slow_period = slow_period | |
| self.signal_period = signal_period | |
| def analyze(self, prices: List[float]) -> List[TechnicalSignal]: | |
| """Calcula MACD e gera sinais.""" | |
| if len(prices) < self.slow_period: | |
| return [] | |
| # Calcular EMAs | |
| ema_fast = self._calculate_ema(prices, self.fast_period) | |
| ema_slow = self._calculate_ema(prices, self.slow_period) | |
| # Calcular MACD | |
| macd_line = [fast - slow for fast, slow in zip(ema_fast, ema_slow)] | |
| signal_line = self._calculate_ema(macd_line, self.signal_period) | |
| # Gerar sinais | |
| signals = [] | |
| for i in range(1, len(macd_line)): | |
| if macd_line[i] > signal_line[i] and macd_line[i-1] <= signal_line[i-1]: | |
| signals.append(TechnicalSignal( | |
| indicator="MACD", | |
| signal_type="buy", | |
| strength=0.7, | |
| value=macd_line[i], | |
| timestamp=datetime.now() | |
| )) | |
| return signals | |
| # Registrar no engine | |
| class TechnicalAnalysisEngine: | |
| def __init__(self): | |
| # ... outros analisadores | |
| self.macd_analyzer = MACDAnalyzer() | |
| def analyze_market_data(self, text: str) -> Dict[str, Any]: | |
| # ... análise existente | |
| macd_signals = self.macd_analyzer.analyze(prices) | |
| all_signals.extend(macd_signals) | |
| ``` | |
| ### 2. Novo Modelo de IA | |
| ```python | |
| # Em sentiment_analysis.py | |
| class CustomFinancialModel: | |
| """Modelo personalizado para análise financeira.""" | |
| def __init__(self, model_path: str): | |
| self.model_path = model_path | |
| self.model = None | |
| self.tokenizer = None | |
| def load(self): | |
| """Carrega modelo personalizado.""" | |
| from transformers import AutoTokenizer, AutoModelForSequenceClassification | |
| self.tokenizer = AutoTokenizer.from_pretrained(self.model_path) | |
| self.model = AutoModelForSequenceClassification.from_pretrained(self.model_path) | |
| def predict(self, text: str) -> Dict[str, float]: | |
| """Faz predição de sentimento.""" | |
| inputs = self.tokenizer(text, return_tensors="pt", truncation=True, padding=True) | |
| with torch.no_grad(): | |
| outputs = self.model(**inputs) | |
| probabilities = torch.nn.functional.softmax(outputs.logits, dim=-1) | |
| return { | |
| "bullish": probabilities[0][0].item(), | |
| "bearish": probabilities[0][1].item(), | |
| "neutral": probabilities[0][2].item() | |
| } | |
| # Registrar no ModelManager | |
| class ModelManager: | |
| def __init__(self): | |
| # ... modelos existentes | |
| self.custom_models = { | |
| "financial-bert": CustomFinancialModel, | |
| "trading-roberta": CustomFinancialModel | |
| } | |
| ``` | |
| ### 3. Nova Interface de Usuário | |
| ```python | |
| # Em ui.py | |
| def create_advanced_analysis_tab(): | |
| """Cria aba de análise avançada.""" | |
| with gr.Tab("🔬 Análise Avançada"): | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| # Controles | |
| timeframe_dropdown = gr.Dropdown( | |
| choices=["1m", "5m", "15m", "1h", "4h", "1d"], | |
| value="5m", | |
| label="📊 Timeframe" | |
| ) | |
| indicators_checklist = gr.CheckboxGroup( | |
| choices=["RSI", "MACD", "Bollinger", "EMA", "Fibonacci"], | |
| value=["RSI", "MACD"], | |
| label="📈 Indicadores" | |
| ) | |
| analyze_btn = gr.Button("🚀 Analisar", variant="primary") | |
| with gr.Column(scale=2): | |
| # Resultados | |
| analysis_output = gr.JSON(label="📊 Resultado da Análise") | |
| chart_output = gr.Plot(label="📈 Gráfico") | |
| # Conectar eventos | |
| analyze_btn.click( | |
| fn=advanced_analysis, | |
| inputs=[timeframe_dropdown, indicators_checklist], | |
| outputs=[analysis_output, chart_output] | |
| ) | |
| return timeframe_dropdown, indicators_checklist, analyze_btn | |
| def advanced_analysis(timeframe: str, indicators: List[str]) -> Tuple[Dict, Any]: | |
| """Executa análise avançada.""" | |
| # Implementar lógica de análise | |
| result = { | |
| "timeframe": timeframe, | |
| "indicators": indicators, | |
| "signals": [], | |
| "confidence": 0.0 | |
| } | |
| # Gerar gráfico | |
| import plotly.graph_objects as go | |
| fig = go.Figure() | |
| # ... adicionar dados ao gráfico | |
| return result, fig | |
| ``` | |
| ## 🔍 Debugging e Profiling | |
| ### Logging para Debug | |
| ```python | |
| import logging | |
| from utils import LogUtils | |
| # Configurar logging detalhado | |
| logging.basicConfig( | |
| level=logging.DEBUG, | |
| format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', | |
| handlers=[ | |
| logging.FileHandler('debug.log'), | |
| logging.StreamHandler() | |
| ] | |
| ) | |
| logger = logging.getLogger(__name__) | |
| def analyze_market_data(self, text: str) -> Dict[str, Any]: | |
| logger.debug(f"Iniciando análise para texto: {text[:100]}...") | |
| try: | |
| # Análise | |
| result = self._perform_analysis(text) | |
| logger.debug(f"Análise concluída: {len(result.get('signals', []))} sinais") | |
| return result | |
| except Exception as e: | |
| logger.error(f"Erro na análise: {e}", exc_info=True) | |
| raise | |
| ``` | |
| ### Profiling de Performance | |
| ```python | |
| # performance_profiler.py | |
| import cProfile | |
| import pstats | |
| from functools import wraps | |
| from memory_profiler import profile | |
| from line_profiler import LineProfiler | |
| def profile_time(func): | |
| """Decorator para profiling de tempo.""" | |
| @wraps(func) | |
| def wrapper(*args, **kwargs): | |
| profiler = cProfile.Profile() | |
| profiler.enable() | |
| result = func(*args, **kwargs) | |
| profiler.disable() | |
| stats = pstats.Stats(profiler) | |
| stats.sort_stats('cumulative') | |
| stats.print_stats(10) # Top 10 funções | |
| return result | |
| return wrapper | |
| @profile_time | |
| @profile # memory_profiler | |
| def analyze_large_dataset(data): | |
| """Análise de dataset grande.""" | |
| # Implementação | |
| pass | |
| # Usar line_profiler | |
| def profile_line_by_line(): | |
| profiler = LineProfiler() | |
| profiler.add_function(analyze_market_data) | |
| profiler.enable_by_count() | |
| # Executar função | |
| analyze_market_data(sample_text) | |
| profiler.print_stats() | |
| ``` | |
| ### Debugging com pdb | |
| ```python | |
| import pdb | |
| def problematic_function(data): | |
| # Ponto de breakpoint | |
| pdb.set_trace() | |
| # Código para debug | |
| processed_data = process_data(data) | |
| # Breakpoint condicional | |
| if len(processed_data) == 0: | |
| pdb.set_trace() | |
| return processed_data | |
| # Comandos úteis no pdb: | |
| # l - listar código | |
| # n - próxima linha | |
| # s - step into | |
| # c - continuar | |
| # p variable - imprimir variável | |
| # pp variable - pretty print | |
| # h - ajuda | |
| ``` | |
| ## 📊 Monitoramento e Métricas | |
| ### Métricas Customizadas | |
| ```python | |
| # custom_metrics.py | |
| from dataclasses import dataclass | |
| from typing import Dict, List | |
| import time | |
| from collections import defaultdict | |
| @dataclass | |
| class AnalysisMetrics: | |
| """Métricas de análise.""" | |
| total_analyses: int = 0 | |
| successful_analyses: int = 0 | |
| failed_analyses: int = 0 | |
| average_processing_time: float = 0.0 | |
| error_types: Dict[str, int] = None | |
| def __post_init__(self): | |
| if self.error_types is None: | |
| self.error_types = defaultdict(int) | |
| class MetricsCollector: | |
| """Coletor de métricas personalizado.""" | |
| def __init__(self): | |
| self.metrics = AnalysisMetrics() | |
| self.processing_times = [] | |
| def record_analysis_start(self) -> float: | |
| """Registra início de análise.""" | |
| return time.time() | |
| def record_analysis_success(self, start_time: float): | |
| """Registra análise bem-sucedida.""" | |
| processing_time = time.time() - start_time | |
| self.metrics.total_analyses += 1 | |
| self.metrics.successful_analyses += 1 | |
| self.processing_times.append(processing_time) | |
| # Calcular média móvel | |
| if len(self.processing_times) > 100: | |
| self.processing_times = self.processing_times[-100:] | |
| self.metrics.average_processing_time = sum(self.processing_times) / len(self.processing_times) | |
| def record_analysis_failure(self, start_time: float, error_type: str): | |
| """Registra falha na análise.""" | |
| self.metrics.total_analyses += 1 | |
| self.metrics.failed_analyses += 1 | |
| self.metrics.error_types[error_type] += 1 | |
| def get_success_rate(self) -> float: | |
| """Calcula taxa de sucesso.""" | |
| if self.metrics.total_analyses == 0: | |
| return 0.0 | |
| return self.metrics.successful_analyses / self.metrics.total_analyses | |
| def export_metrics(self) -> Dict: | |
| """Exporta métricas para análise.""" | |
| return { | |
| "total_analyses": self.metrics.total_analyses, | |
| "success_rate": self.get_success_rate(), | |
| "average_processing_time": self.metrics.average_processing_time, | |
| "error_distribution": dict(self.metrics.error_types) | |
| } | |
| ``` | |
| ## 🚀 Deploy e Produção | |
| ### Configuração para Produção | |
| ```python | |
| # production_config.py | |
| import os | |
| from dataclasses import dataclass | |
| @dataclass | |
| class ProductionConfig: | |
| """Configurações para produção.""" | |
| # Servidor | |
| HOST: str = os.getenv("HOST", "0.0.0.0") | |
| PORT: int = int(os.getenv("PORT", "7860")) | |
| WORKERS: int = int(os.getenv("WORKERS", "4")) | |
| # Logging | |
| LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO") | |
| LOG_FILE: str = os.getenv("LOG_FILE", "app.log") | |
| # Performance | |
| MAX_CONCURRENT_ANALYSES: int = int(os.getenv("MAX_CONCURRENT_ANALYSES", "10")) | |
| ANALYSIS_TIMEOUT: int = int(os.getenv("ANALYSIS_TIMEOUT", "30")) | |
| # Segurança | |
| ENABLE_AUTH: bool = os.getenv("ENABLE_AUTH", "false").lower() == "true" | |
| SECRET_KEY: str = os.getenv("SECRET_KEY", "") | |
| # Cache | |
| ENABLE_REDIS: bool = os.getenv("ENABLE_REDIS", "false").lower() == "true" | |
| REDIS_URL: str = os.getenv("REDIS_URL", "redis://localhost:6379") | |
| ``` | |
| ### Docker | |
| ```dockerfile | |
| # Dockerfile | |
| FROM python:3.9-slim | |
| # Instalar dependências do sistema | |
| RUN apt-get update && apt-get install -y \ | |
| gcc \ | |
| g++ \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # Criar usuário não-root | |
| RUN useradd --create-home --shell /bin/bash app | |
| USER app | |
| WORKDIR /home/app | |
| # Copiar requirements | |
| COPY --chown=app:app requirements.txt . | |
| # Instalar dependências Python | |
| RUN pip install --user --no-cache-dir -r requirements.txt | |
| # Copiar código | |
| COPY --chown=app:app . . | |
| # Expor porta | |
| EXPOSE 7860 | |
| # Comando de inicialização | |
| CMD ["python", "app.py", "--host", "0.0.0.0", "--port", "7860"] | |
| ``` | |
| ```yaml | |
| # docker-compose.yml | |
| version: '3.8' | |
| services: | |
| vampire-bot: | |
| build: . | |
| ports: | |
| - "7860:7860" | |
| environment: | |
| - LOG_LEVEL=INFO | |
| - MAX_CONCURRENT_ANALYSES=5 | |
| volumes: | |
| - ./logs:/home/app/logs | |
| - ./models:/home/app/models | |
| restart: unless-stopped | |
| redis: | |
| image: redis:7-alpine | |
| ports: | |
| - "6379:6379" | |
| volumes: | |
| - redis_data:/data | |
| restart: unless-stopped | |
| volumes: | |
| redis_data: | |
| ``` | |
| ## 📚 Recursos Adicionais | |
| ### Ferramentas Recomendadas | |
| - **IDE**: VS Code com extensões Python | |
| - **Debugging**: pdb, ipdb, VS Code debugger | |
| - **Profiling**: cProfile, memory_profiler, line_profiler | |
| - **Testing**: pytest, coverage.py | |
| - **Linting**: flake8, pylint, mypy | |
| - **Formatting**: black, isort | |
| - **Documentation**: Sphinx, mkdocs | |
| ### Bibliotecas Úteis | |
| ```python | |
| # Análise de dados | |
| import pandas as pd | |
| import numpy as np | |
| from scipy import stats | |
| # Visualização | |
| import matplotlib.pyplot as plt | |
| import plotly.graph_objects as go | |
| import seaborn as sns | |
| # Machine Learning | |
| from sklearn.metrics import accuracy_score, classification_report | |
| from sklearn.model_selection import train_test_split | |
| # Async/Concorrência | |
| import asyncio | |
| from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor | |
| # Monitoramento | |
| import psutil | |
| from prometheus_client import Counter, Histogram, Gauge | |
| ``` | |
| ### Padrões de Design Úteis | |
| ```python | |
| # Strategy Pattern para diferentes análises | |
| from abc import ABC, abstractmethod | |
| class AnalysisStrategy(ABC): | |
| @abstractmethod | |
| def analyze(self, data) -> Dict: | |
| pass | |
| class RSIStrategy(AnalysisStrategy): | |
| def analyze(self, data) -> Dict: | |
| # Implementar RSI | |
| pass | |
| class MACDStrategy(AnalysisStrategy): | |
| def analyze(self, data) -> Dict: | |
| # Implementar MACD | |
| pass | |
| # Factory Pattern para criação de analisadores | |
| class AnalyzerFactory: | |
| _strategies = { | |
| "rsi": RSIStrategy, | |
| "macd": MACDStrategy | |
| } | |
| @classmethod | |
| def create_analyzer(cls, analyzer_type: str) -> AnalysisStrategy: | |
| if analyzer_type not in cls._strategies: | |
| raise ValueError(f"Analisador {analyzer_type} não suportado") | |
| return cls._strategies[analyzer_type]() | |
| # Observer Pattern para notificações | |
| class Observable: | |
| def __init__(self): | |
| self._observers = [] | |
| def attach(self, observer): | |
| self._observers.append(observer) | |
| def notify(self, event): | |
| for observer in self._observers: | |
| observer.update(event) | |
| ``` | |
| ## 🤝 Contribuindo | |
| ### Processo de Contribuição | |
| 1. **Fork** do repositório | |
| 2. **Clone** do seu fork | |
| 3. **Criar branch** para feature/bugfix | |
| 4. **Implementar** mudanças com testes | |
| 5. **Executar** testes e linting | |
| 6. **Commit** seguindo convenções | |
| 7. **Push** da branch | |
| 8. **Criar Pull Request** | |
| 9. **Code Review** | |
| 10. **Merge** após aprovação | |
| ### Checklist para Pull Requests | |
| - [ ] Código segue padrões de estilo | |
| - [ ] Testes adicionados/atualizados | |
| - [ ] Documentação atualizada | |
| - [ ] Todos os testes passam | |
| - [ ] Sem warnings de linting | |
| - [ ] Performance não degradada | |
| - [ ] Compatibilidade mantida | |
| - [ ] Changelog atualizado | |
| --- | |
| **🎯 Objetivo**: Manter código limpo, testável e bem documentado para facilitar manutenção e evolução do projeto! |