-
Notifications
You must be signed in to change notification settings - Fork 15
Add vpin strategies #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Pull Request Review: Add VPIN StrategiesI've reviewed the two new strategy files added in this PR. Here's my comprehensive feedback: ✅ Positive Aspects
🔴 Critical Issues1. Missing Trade Ingestion (HIGH PRIORITY)Location: Both files, VPIN logic section Problem: The # Method exists but is never invoked:
def ingest_trade(self, price: float, size: float, is_buy: bool):
""" Feed each trade into VPIN buckets. """
# ...Impact: The VPIN value will always return 0.0, making the strategy non-functional. The liquidity withdrawal logic will never trigger. Fix Required: You need to:
2. Import IssuesLocation: Problem: Uses import numpy as npBut Fix: Add numpy to dependencies or use Python's built-in 3. Unused ImportsLocation: Both files Problem: from dr_manhattan.utils.logger import Colors # Never usedPer CLAUDE.md rule #1: "The codebase should be focused, clean, and easy to understand" - remove unused imports.
|
Code Review - PR #8: Add VPIN StrategiesOverviewThis PR adds 4 new trading strategy examples totaling ~2,363 lines of code:
✅ Strengths
🔴 Critical Issues1. Security: Environment Variables in .env (violates CLAUDE.md #4)Location: All 4 files Per CLAUDE.md:
Risk:
Recommendation:
2. Missing Input Validationbinary_arb_strategy.py:230-255 - ts_int = int(ts) # No validation that ts exists or is validendgame_sweep_strategy.py:563-583 - Missing validation on market metadata timestamps Risk: Runtime crashes with malformed API responses Fix: Add null checks and type validation before conversions 3. Hardcoded Magic NumbersMultiple instances across all files:
Issue: Values should be configurable parameters, not class constants Recommendation: Move to constructor parameters with these as defaults 4. Race Conditions in Threadingvpin_strategy.py:210-256 - self.seen_trades.add(key) # Accessed from multiple threads without locks
self.flow_buy_count += 1 # Not thread-safe
self.ingest_trade(...) # Modifies shared stateRisk: Data corruption with concurrent access from main thread and trade polling thread Fix: Use 5. Resource LeaksAll files - WebSocket cleanup in finally blocks uses join with timeout but doesn't verify cleanup: finally:
self.ws.stop()
if self.ws_thread:
self.ws_thread.join(timeout=5) # What if thread doesn't stop?Risk: Orphaned threads/connections Fix: Check thread.is_alive() after join and log warnings
|
| Category | Status | Notes |
|---|---|---|
| Code Quality | Needs formatting, type hints, DRY improvements | |
| Potential Bugs | 🔴 | Race conditions, validation gaps, resource leaks |
| Performance | 🟡 | Memory leaks, inefficient patterns |
| Security | 🔴 | .env usage violates project rules, input validation gaps |
| Test Coverage | 🔴 | No tests added |
🎯 Recommendations (Priority Order)
Must Fix Before Merge:
- ✅ Add
numpyto dependencies or remove numpy usage - ✅ Fix thread safety in
vpin_strategy.pywith locks - ✅ Remove .env dependency per CLAUDE.md fix: polymarket impl #4
- ✅ Add input validation for API responses
- ✅ Fix unbounded memory growth in
seen_trades
Should Fix:
- Add
--modesupport tovpindiff_strategy.py - Extract common market-making logic to reduce duplication
- Run
uv run black examples/anduv run ruff check examples/ - Add type hints
Nice to Have:
- Add unit tests
- Improve error messages with context
- Document why polling is used vs WebSocket for trades
- Make hardcoded constants configurable
🚀 Testing Performed
Per CLAUDE.md #5 ("Run and Debug yourself PROACTIVELY"), please confirm:
- Scripts run without errors in test mode
- All dependencies are available
- WebSocket connections establish correctly
- Error paths are tested
Overall Assessment
The code demonstrates good understanding of the domain and follows existing patterns well. However, it has critical issues around thread safety, dependency management, and project conventions that must be addressed before merging. The strategies appear functionally sound but need hardening for production use.
Recommendation: Request changes before merge.
Pull Request Review - PR #8: Add VPIN StrategiesSummaryThis PR adds three sophisticated trading strategy examples to the dr-manhattan library:
Code Quality & Best PracticesStrengths
Issues & Recommendations1. Configuration Management (CLAUDE.md Violation)Severity: Medium The CLAUDE.md guideline states: "Single Source of Truth: DO NOT place many variables in .env file. Place them in the code instead." However, all three files heavily rely on environment variables:
Recommendation: Consider using a config class with reasonable defaults: class Config:
PRIVATE_KEY = os.getenv("POLYMARKET_PRIVATE_KEY", "")
FUNDER = os.getenv("POLYMARKET_FUNDER", "")
CACHE_TTL = 2.0
VERBOSE = True2. Thread Safety IssuesSeverity: High (vpin_strategy.py only)
Fix: # Consolidate all state checks under a single lock acquisition
with self.trade_lock:
if key in self.seen_trades_set or ts_int < self.last_trade_ts:
continue
new_rows.append((ts_int, key, row))3. Hardcoded Configuration ValuesSeverity: Low-Medium Multiple configuration values are hardcoded in class bodies:
Recommendation: Make these configurable via constructor parameters or a config system. 4. Input ValidationSeverity: Medium Missing validation for user inputs:
Recommendation: Add parameter validation in if order_size <= 0:
raise ValueError("order_size must be positive")
if check_interval <= 0:
raise ValueError("check_interval must be positive")5. Error Messages Could Be More InformativeSeverity: Low
Recommendation: Log the exception type or use more specific error messages. Security Concerns1. Credential ExposureSeverity: High All three files check for missing credentials but don't validate their format:
Recommendation: Add basic validation: if not private_key or not private_key.startswith("0x"):
logger.error("POLYMARKET_PRIVATE_KEY must start with 0x")2. Command Injection (Low Risk)Severity: Low The docstrings include example commands with user-provided slugs:
While the Performance Considerations1. Inefficient PollingSeverity: Medium
Recommendation: Consider using WebSocket for trade data if available, or implement exponential backoff. 2. Memory ManagementSeverity: Low
Recommendation: Consider periodic cleanup or use a LRU cache. 3. WebSocket Thread ManagementSeverity: Medium All three files create daemon threads:
Recommendation: Use context managers or ensure proper shutdown in finally blocks. Test CoverageSeverity: Medium No test files were added with these strategies. Given the financial nature of this code: Recommendation:
Example test structure: def test_vpin_calculation():
# Test bucket filling logic
# Test VPIN threshold triggers
pass
def test_arbitrage_detection():
# Test edge cases (yes+no = 1.0, yes+no < 1.0, etc.)
passPotential Bugs1. Race Condition in has_all_dataSeverity: Medium
2. Float Comparison IssuesSeverity: Low Multiple locations use direct float comparison:
3. Missing Null ChecksSeverity: Medium
DocumentationStrengths
Improvements Needed
Alignment with CLAUDE.md Guidelines
Overall AssessmentQuality: Good (7/10) Recommendations SummaryMust Fix (Before Merge)
Should Fix (High Priority)
Nice to Have
Verdict: This is solid work with well-implemented trading strategies. The code demonstrates good understanding of async programming, threading, and market microstructure. However, thread safety issues and lack of tests are concerning for production use. Recommend addressing critical issues before merge. |
Critical Issues Fixed: - #1: Status cache thread safety - protected with _instance_lock - #2: Global credentials thread safety - added _CREDENTIALS_LOCK - #3: RPC session race condition - double-checked locking pattern - #4: Signal handler deadlock - use flag instead of complex cleanup Quality Issues Fixed: - #5: Redundant singleton init - __init__ is now no-op - #6: Long if-elif chain - replaced with TOOL_DISPATCH dict - #7: ThreadPoolExecutor cleanup - unified _run_with_timeout() helper - #8: Rate limiter busy-wait - calculate exact wait time - #9: Status cache memory leak - added eviction and max size limit All 54 MCP tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Critical Issues Fixed: - #1: Credential reload race condition - move reload_credentials() inside lock - #2: Status cache size check - evict BEFORE adding, check size limit - #3: RPC response validation - add JSON parsing error handling, dict type check - #4: Rate limiter init - add _rate_limiter_lock for thread-safe singleton Quality Issues Fixed: - #5: Orphan tracking verified as complete (already implemented correctly) - #8: Standardize error messages - add expected format to all "required" errors - #9: Magic numbers - add explanatory comments for rate limiter and shutdown flag All 54 MCP tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add MCP (Model Context Protocol) server support - Add MCP server implementation for Claude Desktop integration - Support Polymarket dual-wallet system (Funder + Proxy) - Configure signature_type=0 (EOA) for normal MetaMask accounts - Add comprehensive English documentation with examples - Include security measures and troubleshooting guide - Add tests for MCP functionality Features: - Exchange management (Polymarket, Opinion, Limitless) - Market data fetching and analysis - Order creation and management - Portfolio tracking (balance, positions, NAV) - Strategy execution (market making) - Dual-wallet balance display (Funder + Proxy) Technical: - MCP protocol integration with stdio transport - Thread-safe session management - Proper error handling and translation - Environment-based configuration - Polygon RPC integration for balance queries Version: 0.0.2 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(mcp): Address code review feedback High Priority Fixes: - Fix singleton race condition in ExchangeSessionManager and StrategySessionManager (moved initialization into __new__ with proper locking) - Add price validation (0-1 range) in create_order - Improve error handling in get_usdc_balance_polygon (no longer silently returns 0.0, now logs errors and returns None with warnings) - Add RPC endpoint fallbacks for better reliability Medium Priority Fixes: - Change strategy threads to daemon=True for clean shutdown - Make POLYGON_RPC_URL configurable via environment variable - Add fallback RPC endpoints for Polygon Code Quality: - Fix all ruff lint errors (import sorting, E402 noqa comments) - Add @pytest.mark.asyncio decorators to async tests - Fix test isolation issues with singleton cleanup 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(mcp): Fix remaining lint errors and improve robustness - Add credential validation in exchange_manager.py before exchange creation - Move JSON import to module level in server.py - Add thread join timeout verification in strategy_manager.py - Fix lint errors in test files (noqa for import tests, is True comparison) - All 54 MCP tests passing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(mcp): Fix CI formatting and skip tests when mcp not installed - Apply ruff format to all MCP files - Add pytest.importorskip for mcp module in test_mcp_tools.py - Tests skip gracefully when mcp optional dependency is not installed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(mcp): Address code review feedback - Remove emojis from log messages (CLAUDE.md compliance) - Fix misleading "lazy loading" comment for MCP_CREDENTIALS - Make timeout values configurable via environment variables: - MCP_EXCHANGE_INIT_TIMEOUT (default: 10s) - MCP_CLIENT_INIT_TIMEOUT (default: 5s) - Add comprehensive logging architecture documentation in server.py 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(mcp): Address all code review feedback - Remove unused _initialized flag from session managers - Add exception chaining (raise ... from e) to all tool functions - Fix test file path from mcp_server to dr_manhattan/mcp - Improve cleanup error handling (only remove successfully cleaned items) - All 54 MCP tests passing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(mcp): Address CLAUDE.md Rule #4 and security concerns CLAUDE.md Rule #4 Compliance: - Move non-sensitive config defaults to code (signature_type, verbose) - Only keep sensitive data (private_key, funder) as required in .env - Add code constants DEFAULT_SIGNATURE_TYPE, DEFAULT_VERBOSE Security Improvements: - Add Security Warning section to documentation - Add private key security best practices - Clarify required vs optional environment variables Other: - Add clarifying comments for price validation logic - Make verbose logging configurable via MCP_VERBOSE env var 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(mcp): Address PR review - CLAUDE.md compliance and error handling CLAUDE.md Rule #4 Compliance: - Remove env var overrides for timeouts (now code constants only) - Remove POLYGON_RPC_URL env var (RPC list in code) - Remove MCP_VERBOSE env var (use DEFAULT_VERBOSE constant) - Document why only Polymarket uses MCP credentials Error Handling Improvements: - Fail fast on funder balance query failure (raise ValueError) - Proxy balance failure is non-fatal (returns error field) - Better error messages with wallet address context Code Quality: - Add ERC20_BALANCE_OF_SELECTOR constant with documentation - Add descriptive comments for POLYGON_USDC_ADDRESS - Add comments explaining RPC fallback strategy All 54 MCP tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(mcp): Address critical security and resource issues Security Improvements: - Add explicit ThreadPoolExecutor cleanup on timeout (prevent hanging threads) - Add RPC response validation for balance queries - Add connection pooling for RPC requests (requests.Session) - Add security warning comment for credential handling CLAUDE.md Rule #2 Compliance: - Remove non-existent doc references from tests - Keep only examples/mcp_usage_example.md as documentation Resource Management: - executor.shutdown(wait=False, cancel_futures=True) on timeout - Proper cleanup in finally blocks - Validate hex format before parsing RPC responses All 54 MCP tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(mcp): Address all PR review must-fix items Input Validation: - Add validation.py with comprehensive input validators - Validate all tool parameters (exchange, market_id, token_id, etc.) - Prevent injection attacks via strict format checking - Regex patterns for hex addresses, UUIDs, and alphanumeric IDs Security Improvements: - Add credential zeroization on cleanup (_zeroize_credentials) - Filter error context with SAFE_CONTEXT_FIELDS allowlist - Never expose sensitive data (private_key, funder, etc.) in errors - Add RPC session cleanup to prevent resource leaks Singleton Race Condition Fix: - Add _initialized flag in __new__ and __init__ - Defensive check in __init__ to ensure idempotency Resource Management: - cleanup_rpc_session() for HTTP connection pooling cleanup - ExchangeSessionManager.cleanup() now calls RPC session cleanup - Proper cleanup order: clients -> exchanges -> RPC -> credentials All 54 MCP tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: Fix placeholder GitHub URLs in MCP guide Replace yourusername with guzus/dr-manhattan for: - Clone URL - GitHub Issues link - Discussions link 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: Add MCP Server section to README for open source users - Add MCP to Key Features list - Add MCP Server subsection under Usage (follows existing convention) - Add MCP guide to examples list - Link to full documentation (examples/mcp_usage_example.md) - Update last updated date in MCP guide Makes it easy for open source users to discover and use the MCP server. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: Fix placeholder formatting in MCP guide - Change 'youruser' to '<username>' for clarity - Change 'YourName' to '<username>' for consistency - Makes it obvious these are placeholders to replace 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: Remove real wallet addresses from MCP guide examples Replace actual wallet address fragments with generic placeholders to avoid exposing real addresses in documentation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(mcp): Implement PR review feedback and improve signature type docs PR Review Feedback (Issues & Concerns): - Add connection pooling with retry strategy for RPC sessions - Implement thread force-kill with two-phase shutdown and orphan tracking - Add credential refresh mechanism for runtime credential reload - Add pagination support for fetch_markets (limit/offset) - Implement status caching with TTL to reduce refresh_state() calls - Add rate limiter (token bucket: 10 req/s, burst 20) Documentation: - Clarify signature type 2 allows trading from Proxy wallet - Type 0: Funder = MetaMask address, trades from Funder wallet - Type 2: Funder = Proxy wallet address, trades from Proxy wallet - Update error messages and troubleshooting guide 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(mcp): Address all PR review critical and quality issues Critical Issues Fixed: - #1: Status cache thread safety - protected with _instance_lock - #2: Global credentials thread safety - added _CREDENTIALS_LOCK - #3: RPC session race condition - double-checked locking pattern - #4: Signal handler deadlock - use flag instead of complex cleanup Quality Issues Fixed: - #5: Redundant singleton init - __init__ is now no-op - #6: Long if-elif chain - replaced with TOOL_DISPATCH dict - #7: ThreadPoolExecutor cleanup - unified _run_with_timeout() helper - #8: Rate limiter busy-wait - calculate exact wait time - #9: Status cache memory leak - added eviction and max size limit All 54 MCP tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(mcp): Fix CI formatting and skip tests when mcp not installed - Apply ruff format to all MCP files - Add pytest.importorskip for mcp module in test_mcp_server_structure.py - Tests skip gracefully when mcp optional dependency is not installed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(mcp): Address all 3rd PR review critical and quality issues Critical Issues Fixed: - #1: Credential reload race condition - move reload_credentials() inside lock - #2: Status cache size check - evict BEFORE adding, check size limit - #3: RPC response validation - add JSON parsing error handling, dict type check - #4: Rate limiter init - add _rate_limiter_lock for thread-safe singleton Quality Issues Fixed: - #5: Orphan tracking verified as complete (already implemented correctly) - #8: Standardize error messages - add expected format to all "required" errors - #9: Magic numbers - add explanatory comments for rate limiter and shutdown flag All 54 MCP tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(mcp): Address 5th review - register missing tools and improve tests 5th Review Fixes: - Register 12 missing tools in server.py (total 29 tools now) - fetch_order, fetch_positions_for_market - pause_strategy, resume_strategy, get_strategy_metrics - fetch_token_ids, find_tradeable_market, find_crypto_hourly_market - parse_market_identifier, get_tag_by_slug - Fix type hints: list[Tool] -> List[Tool] for consistency - Increase STATUS_CACHE_TTL from 1s to 3s for better performance - Fix RateLimiter.get_status() duplicate lock issue - Fix test assertions: return True/False -> proper assert statements - Remove emojis from test output (CLAUDE.md Rule #1) - Fix test_pyproject_config check for dr_manhattan package All 54 MCP tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * style(mcp): Fix formatting in test files Apply ruff format to test_comprehensive.py and test_mcp_server_structure.py 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(mcp): Fix stdout pollution causing JSON-RPC parse errors The MCP server was corrupting the JSON-RPC protocol with two issues: 1. **Logger import order bug**: dr_manhattan.utils was imported before patching setup_logger, causing default_logger to be created with stdout handler and ANSI colors. Fixed by: - Patch logger_module.setup_logger BEFORE importing dr_manhattan.utils - Recreate default_logger with patched function - Move third-party imports after patching 2. **Verbose mode stdout pollution**: DEFAULT_VERBOSE=True caused polymarket.py to print debug info (with checkmarks like ✓) to stdout. Fixed by setting DEFAULT_VERBOSE=False for MCP. These fixes prevent errors like: - "Unexpected token '✓'" - "Unexpected token '←[90m'" (ANSI escape codes) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(mcp): Fix duration_minutes parameter bug in create_strategy_session Strategy.__init__() does not accept duration_minutes parameter - it's only used by run(). The create_session() method was passing all params including duration_minutes to the constructor, causing: "Strategy.__init__() got an unexpected keyword argument 'duration_minutes'" Fix: Extract duration_minutes from params before passing to strategy constructor. Pass it directly to _run_strategy() instead. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: Update .env.example and README for new trading configurations * feat(mcp): Add search_markets tool for keyword-based market retrieval - Introduced a new tool, `search_markets`, allowing users to search for markets by keyword with pagination support. - Updated `fetch_markets` description to clarify pagination usage. - Enhanced input schema for both tools to include limit and offset parameters for better control over results. This addition improves the functionality of the MCP by enabling more targeted market searches. * fix(mcp): Improve tool descriptions for better AI tool selection - Update fetch_markets description to warn about slowness (100+ results) - Update search_markets description with RECOMMENDED prefix - Guide AI to prefer search_markets for specific market queries --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: guzus <storminggalaxys3@gmail.com> Co-authored-by: guzus <50664161+guzus@users.noreply.github.com>
Added files: