This commit is contained in:
2025-11-09 22:07:14 +01:00
parent 596fcde0bf
commit 1165060bc0
27 changed files with 2213 additions and 107 deletions

127
GEMINI.md Normal file
View File

@ -0,0 +1,127 @@
# Project Overview
This project is a sophisticated, multi-process automated trading bot for the Hyperliquid decentralized exchange. It is written in Python and uses a modular architecture to separate concerns like data fetching, strategy execution, and trade management.
The bot uses a high-performance data pipeline with SQLite for storing market data. Trading strategies are defined and configured in a JSON file, allowing for easy adjustments without code changes. The system supports multiple, independent trading agents for risk segregation and PNL tracking. A live terminal dashboard provides real-time monitoring of market data, strategy signals, and the status of all background processes.
## Building and Running
### 1. Setup
1. **Create and activate a virtual environment:**
```bash
# For Windows
python -m venv .venv
.\.venv\Scripts\activate
# For macOS/Linux
python3 -m venv .venv
source .venv/bin/activate
```
2. **Install dependencies:**
```bash
pip install -r requirements.txt
```
3. **Configure environment variables:**
Create a `.env` file in the root of the project (you can copy `.env.example`) and add your Hyperliquid wallet private key and any agent keys.
4. **Configure strategies:**
Edit `_data/strategies.json` to enable and configure your desired trading strategies.
### 2. Running the Bot
To run the main application, which includes the dashboard and all background processes, execute the following command:
```bash
python main_app.py
```
## Development Conventions
* **Modularity:** The project is divided into several scripts, each with a specific responsibility (e.g., `data_fetcher.py`, `trade_executor.py`).
* **Configuration-driven:** Strategies are defined in `_data/strategies.json`, not hardcoded. This allows for easy management of strategies.
* **Multi-processing:** The application uses the `multiprocessing` module to run different components in parallel for performance and stability.
* **Strategies:** Custom strategies should inherit from the `BaseStrategy` class (defined in `strategies/base_strategy.py`) and implement the `calculate_signals` method.
* **Documentation:** The `WIKI/` directory contains detailed documentation for the project. Start with `WIKI/SUMMARY.md`.
# Project Review and Recommendations
This review provides an analysis of the current state of the automated trading bot project, proposes specific code improvements, and identifies files that appear to be unused or are one-off utilities that could be reorganized.
The project is a well-structured, multi-process Python application for crypto trading. It has a clear separation of concerns between data fetching, strategy execution, and trade management. The use of `multiprocessing` and a centralized `main_app.py` orchestrator is a solid architectural choice.
The following sections detail recommendations for improving configuration management, code structure, and robustness, along with a list of files recommended for cleanup.
---
## Proposed Code Changes
### 1. Centralize Configuration
- **Issue:** Key configuration variables like `WATCHED_COINS` and `required_timeframes` are hardcoded in `main_app.py`. This makes them difficult to change without modifying the source code.
- **Proposal:**
- Create a central configuration file, e.g., `_data/config.json`.
- Move `WATCHED_COINS` and `required_timeframes` into this new file.
- Load this configuration in `main_app.py` at startup.
- **Benefit:** Decouples configuration from code, making the application more flexible and easier to manage.
### 2. Refactor `main_app.py` for Clarity
- **Issue:** `main_app.py` is long and handles multiple responsibilities: process orchestration, dashboard rendering, and data reading.
- **Proposal:**
- **Abstract Process Management:** The functions for running subprocesses (e.g., `run_live_candle_fetcher`, `run_resampler_job`) contain repetitive logic for logging, shutdown handling, and process looping. This could be abstracted into a generic `ProcessRunner` class.
- **Create a Dashboard Class:** The complex dashboard rendering logic could be moved into a separate `Dashboard` class to improve separation of concerns and make the main application loop cleaner.
- **Benefit:** Improves code readability, reduces duplication, and makes the application easier to maintain and extend.
### 3. Improve Project Structure
- **Issue:** The root directory is cluttered with numerous Python scripts, making it difficult to distinguish between core application files, utility scripts, and old/example files.
- **Proposal:**
- Create a `scripts/` directory and move all one-off utility and maintenance scripts into it.
- Consider creating a `src/` or `app/` directory to house the core application source code (`main_app.py`, `trade_executor.py`, etc.), separating it clearly from configuration, data, and documentation.
- **Benefit:** A cleaner, more organized project structure that is easier for new developers to understand.
### 4. Enhance Robustness and Error Handling
- **Issue:** The agent loading in `trade_executor.py` relies on discovering environment variables by a naming convention (`_AGENT_PK`). This is clever but can be brittle if environment variables are named incorrectly.
- **Proposal:**
- Explicitly define the agent names and their corresponding environment variable keys in the proposed `_data/config.json` file. The `trade_executor` would then load only the agents specified in the configuration.
- **Benefit:** Makes agent configuration more explicit and less prone to errors from stray environment variables.
---
## Identified Unused/Utility Files
The following files were identified as likely being unused by the core application, being obsolete, or serving as one-off utilities. It is recommended to **move them to a `scripts/` directory** or **delete them** if they are obsolete.
### Obsolete / Old Versions:
- `data_fetcher_old.py`
- `market_old.py`
- `base_strategy.py` (The one in the root directory; the one in `strategies/` is used).
### One-Off Utility Scripts (Recommend moving to `scripts/`):
- `!migrate_to_sqlite.py`
- `import_csv.py`
- `del_market_cap_tables.py`
- `fix_timestamps.py`
- `list_coins.py`
- `create_agent.py`
### Examples / Unused Code:
- `basic_ws.py` (Appears to be an example file).
- `backtester.py`
- `strategy_sma_cross.py` (A strategy file in the root, not in the `strategies` folder).
- `strategy_template.py`
### Standalone / Potentially Unused Core Files:
The following files seem to have their logic already integrated into the main multi-process application. They might be remnants of a previous architecture and may not be needed as standalone scripts.
- `address_monitor.py`
- `position_monitor.py`
- `trade_log.py`
- `wallet_data.py`
- `whale_tracker.py`
### Data / Log Files (Recommend archiving or deleting):
- `hyperliquid_wallet_data_*.json` (These appear to be backups or logs).

300
IMPROVEMENT_ROADMAP.md Normal file
View File

@ -0,0 +1,300 @@
# Improvement Roadmap - Hyperliquid Trading Bot
## Overview
This document outlines the detailed implementation plan for transforming the trading bot into a production-ready system.
## Phase 1: Foundation (Weeks 1-2)
### Week 1: Security & Stability
#### Day 1-2: Critical Security Fixes
- [ ] **Implement Encrypted Key Storage**
- Create `security/key_manager.py`
- Replace environment variable key access
- Add key rotation mechanism
- **Files**: `trade_executor.py`, `create_agent.py`
- [ ] **Add Input Validation Framework**
- Create `validation/trading_validator.py`
- Validate all trading parameters
- Add sanitization for user inputs
- **Files**: `position_manager.py`, `trade_executor.py`
#### Day 3-4: Risk Management
- [ ] **Implement Circuit Breakers**
- Create `risk/circuit_breaker.py`
- Add trading halt conditions
- Implement automatic recovery
- **Files**: `trade_executor.py`, `position_manager.py`
- [ ] **Fix Import Resolution Issues**
- Update relative imports
- Add `__init__.py` files where missing
- Test all module imports
- **Files**: `main_app.py`, all strategy files
#### Day 5-7: Code Quality
- [ ] **Refactor Dashboard Display**
- Extract `DashboardRenderer` class
- Split into market/strategy/position components
- Add configuration for display options
- **Files**: `main_app.py`
### Week 2: Configuration & Error Handling
#### Day 8-9: Configuration Management
- [ ] **Create Centralized Configuration**
- Create `config/settings.py`
- Move all magic numbers to config
- Add environment-specific configs
- **Files**: All Python files
- [ ] **Standardize Error Handling**
- Create `utils/error_handlers.py`
- Implement retry decorators
- Add structured exception classes
- **Files**: All core modules
#### Day 10-12: Database Improvements
- [ ] **Implement Connection Pool**
- Create `database/connection_pool.py`
- Replace direct SQLite connections
- Add connection health monitoring
- **Files**: `base_strategy.py`, all data access files
- [ ] **Add Database Migrations**
- Create `database/migrations/`
- Version control schema changes
- Add rollback capabilities
- **Files**: Database schema files
#### Day 13-14: Basic Testing
- [ ] **Create Test Framework**
- Set up `tests/` directory structure
- Add pytest configuration
- Create test fixtures and mocks
- **Files**: New test files
## Phase 2: Performance & Testing (Weeks 3-4)
### Week 3: Performance Optimization
#### Day 15-17: Caching Layer
- [ ] **Implement Redis/Memory Cache**
- Create `cache/cache_manager.py`
- Cache frequently accessed data
- Add cache invalidation logic
- **Files**: `data_fetcher.py`, `base_strategy.py`
#### Day 18-19: Async Operations
- [ ] **Convert to Async/Await**
- Identify blocking operations
- Convert to async patterns
- Add async context managers
- **Files**: `live_market_utils.py`, API calls
#### Day 20-21: Batch Processing
- [ ] **Implement Batch Operations**
- Batch database writes
- Bulk API requests
- Optimize data processing
- **Files**: Data processing modules
### Week 4: Testing Framework
#### Day 22-24: Unit Tests
- [ ] **Comprehensive Unit Test Suite**
- Test all core classes
- Mock external dependencies
- Achieve >80% coverage
- **Files**: `tests/unit/`
#### Day 25-26: Integration Tests
- [ ] **End-to-End Testing**
- Test complete workflows
- Mock Hyperliquid API
- Test process communication
- **Files**: `tests/integration/`
#### Day 27-28: Paper Trading
- [ ] **Paper Trading Mode**
- Create simulation environment
- Mock trade execution
- Add performance tracking
- **Files**: `trade_executor.py`, new simulation files
## Phase 3: Monitoring & Observability (Weeks 5-6)
### Week 5: Metrics & Monitoring
#### Day 29-31: Metrics Collection
- [ ] **Add Prometheus Metrics**
- Create `monitoring/metrics.py`
- Track key performance indicators
- Add custom business metrics
- **Files**: All core modules
#### Day 32-33: Health Checks
- [ ] **Health Check System**
- Create `monitoring/health_check.py`
- Monitor all system components
- Add dependency checks
- **Files**: `main_app.py`, all processes
#### Day 34-35: Alerting
- [ ] **Alerting System**
- Create `monitoring/alerts.py`
- Configure alert rules
- Add notification channels
- **Files**: New alerting files
### Week 6: Documentation & Developer Experience
#### Day 36-38: API Documentation
- [ ] **Auto-Generated Docs**
- Set up Sphinx/ MkDocs
- Document all public APIs
- Add code examples
- **Files**: `docs/` directory
#### Day 39-40: Setup Improvements
- [ ] **Interactive Setup**
- Create setup wizard
- Validate configuration
- Add guided configuration
- **Files**: `setup.py`, new setup files
#### Day 41-42: Examples & Guides
- [ ] **Strategy Examples**
- Create example strategies
- Add development tutorials
- Document best practices
- **Files**: `examples/`, `WIKI/`
## Phase 4: Advanced Features (Weeks 7-8)
### Week 7: Advanced Risk Management
#### Day 43-45: Position Sizing
- [ ] **Dynamic Position Sizing**
- Volatility-based sizing
- Portfolio risk metrics
- Kelly criterion implementation
- **Files**: `position_manager.py`, new risk modules
#### Day 46-47: Advanced Orders
- [ ] **Advanced Order Types**
- Stop-loss orders
- Take-profit orders
- Conditional orders
- **Files**: `trade_executor.py`
#### Day 48-49: Portfolio Management
- [ ] **Portfolio Optimization**
- Correlation analysis
- Risk parity allocation
- Rebalancing logic
- **Files**: New portfolio modules
### Week 8: Production Readiness
#### Day 50-52: Deployment
- [ ] **Production Deployment**
- Docker containerization
- Kubernetes manifests
- CI/CD pipeline
- **Files**: `docker/`, `.github/workflows/`
#### Day 53-54: Performance Profiling
- [ ] **Profiling Tools**
- Performance monitoring
- Memory usage tracking
- Bottleneck identification
- **Files**: New profiling modules
#### Day 55-56: Final Polish
- [ ] **Production Hardening**
- Security audit
- Load testing
- Documentation review
- **Files**: All files
## Implementation Guidelines
### Daily Workflow
1. **Morning Standup**: Review progress, identify blockers
2. **Development**: Focus on assigned tasks
3. **Testing**: Write tests alongside code
4. **Code Review**: Peer review all changes
5. **Documentation**: Update docs with changes
### Quality Gates
- All code must pass linting and formatting
- New features require unit tests
- Integration tests for critical paths
- Security review for sensitive changes
### Risk Mitigation
- Feature flags for new functionality
- Gradual rollout with monitoring
- Rollback procedures for each change
- Regular backup and recovery testing
## Success Criteria
### Phase 1 Success
- [ ] All security vulnerabilities fixed
- [ ] Import resolution issues resolved
- [ ] Basic test framework in place
- [ ] Configuration management implemented
### Phase 2 Success
- [ ] Performance improvements measured
- [ ] Test coverage >80%
- [ ] Paper trading mode functional
- [ ] Async operations implemented
### Phase 3 Success
- [ ] Monitoring dashboard operational
- [ ] Alerting system functional
- [ ] Documentation complete
- [ ] Developer experience improved
### Phase 4 Success
- [ ] Production deployment ready
- [ ] Advanced features working
- [ ] Performance benchmarks met
- [ ] Security audit passed
## Resource Requirements
### Development Team
- **Senior Python Developer**: Lead architecture and security
- **Backend Developer**: Performance and database optimization
- **DevOps Engineer**: Deployment and monitoring
- **QA Engineer**: Testing framework and automation
### Tools & Services
- **Development**: PyCharm/VSCode, Git, Docker
- **Testing**: Pytest, Mock, Coverage tools
- **Monitoring**: Prometheus, Grafana, AlertManager
- **CI/CD**: GitHub Actions, Docker Hub
- **Documentation**: Sphinx/MkDocs, ReadTheDocs
### Infrastructure
- **Development**: Local development environment
- **Testing**: Staging environment with test data
- **Production**: Cloud deployment with monitoring
- **Backup**: Automated backup and recovery system
## Timeline Summary
| Phase | Duration | Key Deliverables |
|-------|----------|------------------|
| Phase 1 | 2 weeks | Security fixes, basic testing, configuration |
| Phase 2 | 2 weeks | Performance optimization, comprehensive testing |
| Phase 3 | 2 weeks | Monitoring, documentation, developer tools |
| Phase 4 | 2 weeks | Advanced features, production deployment |
| **Total** | **8 weeks** | **Production-ready trading system** |
This roadmap provides a structured approach to transforming the trading bot into a robust, scalable, and maintainable system suitable for production use.

View File

@ -0,0 +1 @@
"# Comprehensive Project Review and Improvement Proposals"

View File

@ -1,6 +1,6 @@
{
"sma_cross_eth_5m": {
"strategy_name": "sma_cross_2",
"strategy_name": "sma_cross_1",
"script": "strategies.ma_cross_strategy.MaCrossStrategy",
"optimization_params": {
"fast": {

208
_data/coin_id_map.json Normal file
View File

@ -0,0 +1,208 @@
{
"0G": "zero-gravity",
"2Z": "doublezero",
"AAVE": "aave",
"ACE": "endurance",
"ADA": "ada-the-dog",
"AI": "sleepless-ai",
"AI16Z": "ai16z",
"AIXBT": "aixbt",
"ALGO": "dear-algorithm",
"ALT": "altlayer",
"ANIME": "anime-token",
"APE": "ape-3",
"APEX": "apex-token-2",
"APT": "aptos",
"AR": "arweave",
"ARB": "osmosis-allarb",
"ARK": "ark-3",
"ASTER": "astar",
"ATOM": "lost-bitcoin-layer",
"AVAX": "binance-peg-avalanche",
"AVNT": "avantis",
"BABY": "baby-2",
"BADGER": "badger-dao",
"BANANA": "nforbanana",
"BCH": "bitcoin-cash",
"BERA": "berachain-bera",
"BIGTIME": "big-time",
"BIO": "bio-protocol",
"BLAST": "blast",
"BLUR": "blur",
"BLZ": "bluzelle",
"BNB": "binancecoin",
"BNT": "bancor",
"BOME": "book-of-meme",
"BRETT": "brett",
"BSV": "bitcoin-cash-sv",
"BTC": "bitcoin",
"CAKE": "pancakeswap-token",
"CANTO": "canto",
"CATI": "catizen",
"CELO": "celo",
"CFX": "cosmic-force-token-v2",
"CHILLGUY": "just-a-chill-guy",
"COMP": "compound-governance-token",
"CRV": "curve-dao-token",
"CYBER": "cyberconnect",
"DOGE": "doge-on-pulsechain",
"DOOD": "doodles",
"DOT": "xcdot",
"DYDX": "dydx-chain",
"DYM": "dymension",
"EIGEN": "eigenlayer",
"ENA": "ethena",
"ENS": "ethereum-name-service",
"ETC": "ethereum-classic",
"ETH": "ethereum",
"ETHFI": "ether-fi",
"FARTCOIN": "fartcoin-2",
"FET": "fetch-ai",
"FIL": "filecoin",
"FRIEND": "friend-tech",
"FTM": "fantom",
"FTT": "ftx-token",
"GALA": "gala",
"GAS": "gas",
"GMT": "stepn",
"GMX": "gmx",
"GOAT": "goat",
"GRASS": "grass-3",
"GRIFFAIN": "griffain",
"HBAR": "hedera-hashgraph",
"HEMI": "hemi",
"HMSTR": "hamster-kombat",
"HYPE": "hyperliquid",
"HYPER": "hyper-4",
"ILV": "illuvium",
"IMX": "immutable-x",
"INIT": "initia",
"INJ": "injective-protocol",
"IO": "io",
"IOTA": "iota-2",
"IP": "story-2",
"JELLY": "jelly-time",
"JTO": "jito-governance-token",
"JUP": "jupiter-exchange-solana",
"KAITO": "kaito",
"KAS": "wrapped-kaspa",
"LAUNCHCOIN": "ben-pasternak",
"LAYER": "unilayer",
"LDO": "linea-bridged-ldo-linea",
"LINEA": "linea",
"LINK": "osmosis-alllink",
"LISTA": "lista",
"LOOM": "loom",
"LTC": "litecoin",
"MANTA": "manta-network",
"MATIC": "matic-network",
"MAV": "maverick-protocol",
"MAVIA": "heroes-of-mavia",
"ME": "magic-eden",
"MEGA": "megaeth",
"MELANIA": "melania-meme",
"MEME": "mpx6900",
"MERL": "merlin-chain",
"MET": "metya",
"MEW": "cat-in-a-dogs-world",
"MINA": "mina-protocol",
"MKR": "maker",
"MNT": "mynth",
"MON": "mon-protocol",
"MOODENG": "moo-deng-2",
"MORPHO": "morpho",
"MOVE": "movement",
"MYRO": "myro",
"NEAR": "near",
"NEO": "neo",
"NIL": "nillion",
"NOT": "nothing-3",
"NTRN": "neutron-3",
"NXPC": "nexpace",
"OGN": "origin-protocol",
"OM": "mantra-dao",
"OMNI": "omni-2",
"ONDO": "ondo-finance",
"OP": "optimism",
"ORBS": "orbs",
"ORDI": "ordinals",
"OX": "ox-fun",
"PANDORA": "pandora",
"PAXG": "pax-gold",
"PENDLE": "pendle",
"PENGU": "pudgy-penguins",
"PEOPLE": "constitutiondao-wormhole",
"PIXEL": "pixel-3",
"PNUT": "pnut",
"POL": "proof-of-liquidity",
"POLYX": "polymesh",
"POPCAT": "popcat",
"PROMPT": "wayfinder",
"PROVE": "succinct",
"PUMP": "pump-fun",
"PURR": "purr-2",
"PYTH": "pyth-network",
"RDNT": "radiant-capital",
"RENDER": "render-token",
"REQ": "request-network",
"RESOLV": "resolv",
"REZ": "renzo",
"RLB": "rollbit-coin",
"RSR": "reserve-rights-token",
"RUNE": "thorchain",
"S": "token-s",
"SAGA": "saga-2",
"SAND": "the-sandbox-wormhole",
"SCR": "scroll",
"SEI": "sei-network",
"SHIA": "shiba-saga",
"SKY": "sky",
"SNX": "havven",
"SOL": "solana",
"SOPH": "sophon",
"SPX": "spx6900",
"STBL": "stbl",
"STG": "stargate-finance",
"STRAX": "stratis",
"STRK": "starknet",
"STX": "stox",
"SUI": "sui",
"SUPER": "superfarm",
"SUSHI": "sushi",
"SYRUP": "syrup",
"TAO": "the-anthropic-order",
"TIA": "tia",
"TNSR": "tensorium",
"TON": "tontoken",
"TRB": "tellor",
"TRUMP": "trumpeffect69420",
"TRX": "tron-bsc",
"TST": "test-3",
"TURBO": "turbo",
"UMA": "uma",
"UNI": "uni",
"UNIBOT": "unibot",
"USTC": "wrapped-ust",
"USUAL": "usual",
"VINE": "vine",
"VIRTUAL": "virtual-protocol",
"VVV": "venice-token",
"W": "w",
"WCT": "connect-token-wct",
"WIF": "wif-secondchance",
"WLD": "worldcoin-wld",
"WLFI": "world-liberty-financial",
"XAI": "xai-blockchain",
"XLM": "stellar",
"XPL": "pulse-2",
"XRP": "ripple",
"YGG": "yield-guild-games",
"YZY": "yzy",
"ZEC": "zcash",
"ZEN": "zenith-3",
"ZEREBRO": "zerebro",
"ZETA": "zeta",
"ZK": "zksync",
"ZORA": "zora",
"ZRO": "layerzero"
}

View File

@ -101,6 +101,7 @@
"MAV": 0,
"MAVIA": 1,
"ME": 1,
"MEGA": 0,
"MELANIA": 1,
"MEME": 0,
"MERL": 0,

View File

@ -1,7 +0,0 @@
{
"sma_cross_2": {
"coin": "BTC",
"side": "short",
"size": 0.0001
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
{
"copy_trader_eth_ETH": {
"strategy": "copy_trader_eth",
"coin": "ETH",
"side": "long",
"open_time_utc": "2025-11-02T20:35:02.988272+00:00",
"open_price": 3854.9,
"amount": 0.0055,
"leverage": 3
}
}

View File

@ -1,12 +1,11 @@
{
"sma_cross_eth_5m": {
"enabled": true,
"script": "strategy_runner.py",
"sma_cross_1": {
"enabled": false,
"class": "strategies.ma_cross_strategy.MaCrossStrategy",
"agent": "scalper_agent",
"parameters": {
"coin": "ETH",
"timeframe": "1m",
"timeframe": "15m",
"short_ma": 7,
"long_ma": 44,
"size": 0.0055,
@ -14,19 +13,39 @@
"leverage_short": 5
}
},
"sma_125d_btc": {
"enabled": true,
"script": "strategy_runner.py",
"sma_44d_btc": {
"enabled": false,
"class": "strategies.single_sma_strategy.SingleSmaStrategy",
"agent": "swing_agent",
"parameters": {
"agent": "swing",
"coin": "BTC",
"timeframe": "1d",
"sma_period": 44,
"size": 0.0001,
"leverage_long": 2,
"leverage_long": 3,
"leverage_short": 1
}
},
"copy_trader_eth": {
"enabled": true,
"is_event_driven": true,
"class": "strategies.copy_trader_strategy.CopyTraderStrategy",
"parameters": {
"agent": "scalper",
"target_address": "0x32885a6adac4375858E6edC092EfDDb0Ef46484C",
"coins_to_copy": {
"ETH": {
"size": 0.0055,
"leverage_long": 3,
"leverage_short": 3
},
"BTC": {
"size": 0.0002,
"leverage_long": 1,
"leverage_short": 1
}
}
}
}
}

View File

@ -0,0 +1,7 @@
{
"ETH": {
"side": "long",
"size": 0.018,
"entry": 3864.2
}
}

View File

@ -0,0 +1,7 @@
{
"strategy_name": "copy_trader_eth",
"current_signal": "WAIT",
"last_signal_change_utc": null,
"signal_price": null,
"last_checked_utc": "2025-11-02T09:55:08.460168+00:00"
}

View File

@ -1,7 +0,0 @@
{
"strategy_name": "ma_cross_btc",
"current_signal": "HOLD",
"last_signal_change_utc": "2025-10-12T17:00:00+00:00",
"signal_price": 114286.0,
"last_checked_utc": "2025-10-15T11:48:55.092260+00:00"
}

View File

@ -1,7 +0,0 @@
{
"strategy_name": "sma_125d_btc",
"current_signal": "SELL",
"last_signal_change_utc": "2025-10-14T00:00:00+00:00",
"signal_price": 113026.0,
"last_checked_utc": "2025-10-16T10:42:03.203292+00:00"
}

View File

@ -1,7 +0,0 @@
{
"strategy_name": "sma_125d_eth",
"current_signal": "BUY",
"last_signal_change_utc": "2025-08-26T00:00:00+00:00",
"signal_price": 4600.63,
"last_checked_utc": "2025-10-15T17:35:17.663159+00:00"
}

View File

@ -1,7 +0,0 @@
{
"strategy_name": "sma_44d_btc",
"current_signal": "SELL",
"last_signal_change_utc": "2025-10-14T00:00:00+00:00",
"signal_price": 113026.0,
"last_checked_utc": "2025-10-16T10:42:03.202977+00:00"
}

View File

@ -1,7 +0,0 @@
{
"strategy_name": "sma_5m_eth",
"current_signal": "SELL",
"last_signal_change_utc": "2025-10-15T17:30:00+00:00",
"signal_price": 3937.5,
"last_checked_utc": "2025-10-15T17:35:05.035566+00:00"
}

View File

@ -1,7 +0,0 @@
{
"strategy_name": "sma_cross",
"current_signal": "SELL",
"last_signal_change_utc": "2025-10-15T11:45:00+00:00",
"signal_price": 111957.0,
"last_checked_utc": "2025-10-15T12:10:05.048434+00:00"
}

View File

@ -1,7 +0,0 @@
{
"strategy_name": "sma_cross_1",
"current_signal": "FLAT",
"last_signal_change_utc": "2025-10-18T20:22:00+00:00",
"signal_price": 3893.9,
"last_checked_utc": "2025-10-18T20:30:05.021192+00:00"
}

View File

@ -1,7 +1,7 @@
{
"strategy_name": "sma_cross_2",
"current_signal": "SELL",
"last_signal_change_utc": "2025-10-20T00:00:00+00:00",
"signal_price": 110811.0,
"last_checked_utc": "2025-10-20T18:45:51.578502+00:00"
"last_signal_change_utc": "2025-10-27T00:00:00+00:00",
"signal_price": 114111.0,
"last_checked_utc": "2025-11-09T21:06:17.671443+00:00"
}

View File

@ -1,7 +0,0 @@
{
"strategy_name": "sma_cross_eth_5m",
"current_signal": "SELL",
"last_signal_change_utc": "2025-10-15T11:45:00+00:00",
"signal_price": 4106.1,
"last_checked_utc": "2025-10-15T12:05:05.022308+00:00"
}

290
_data/wallets_info.json Normal file
View File

@ -0,0 +1,290 @@
{
"Whale 1 (BTC Maxi)": {
"address": "0xb83de012dba672c76a7dbbbf3e459cb59d7d6e36",
"core_state": {
"raw_state": {
"marginSummary": {
"accountValue": "30018881.1193690002",
"totalNtlPos": "182930683.6996490061",
"totalRawUsd": "212949564.8190180063",
"totalMarginUsed": "22969943.9848450013"
},
"crossMarginSummary": {
"accountValue": "30018881.1193690002",
"totalNtlPos": "182930683.6996490061",
"totalRawUsd": "212949564.8190180063",
"totalMarginUsed": "22969943.9848450013"
},
"crossMaintenanceMarginUsed": "5420634.4984849999",
"withdrawable": "7043396.1885489998",
"assetPositions": [
{
"type": "oneWay",
"position": {
"coin": "BTC",
"szi": "-546.94441",
"leverage": {
"type": "cross",
"value": 10
},
"entryPx": "115183.2",
"positionValue": "62795781.6009199992",
"unrealizedPnl": "203045.067519",
"returnOnEquity": "0.0322299761",
"liquidationPx": "159230.7089577085",
"marginUsed": "6279578.1600919999",
"maxLeverage": 40,
"cumFunding": {
"allTime": "-6923407.0911370004",
"sinceOpen": "-6923407.0970780002",
"sinceChange": "-1574.188052"
}
}
},
{
"type": "oneWay",
"position": {
"coin": "ETH",
"szi": "-13938.989",
"leverage": {
"type": "cross",
"value": 10
},
"entryPx": "4106.64",
"positionValue": "58064252.5784000009",
"unrealizedPnl": "-821803.895073",
"returnOnEquity": "-0.1435654683",
"liquidationPx": "5895.7059682083",
"marginUsed": "5806425.2578400001",
"maxLeverage": 25,
"cumFunding": {
"allTime": "-6610045.8844170002",
"sinceOpen": "-6610045.8844170002",
"sinceChange": "-730.403023"
}
}
},
{
"type": "oneWay",
"position": {
"coin": "SOL",
"szi": "-75080.68",
"leverage": {
"type": "cross",
"value": 10
},
"entryPx": "201.3063",
"positionValue": "14975592.4328000005",
"unrealizedPnl": "138627.573942",
"returnOnEquity": "0.0917199656",
"liquidationPx": "519.0933515657",
"marginUsed": "1497559.2432800001",
"maxLeverage": 20,
"cumFunding": {
"allTime": "-792893.154387",
"sinceOpen": "-922.301401",
"sinceChange": "-187.682929"
}
}
},
{
"type": "oneWay",
"position": {
"coin": "DOGE",
"szi": "-109217.0",
"leverage": {
"type": "cross",
"value": 10
},
"entryPx": "0.279959",
"positionValue": "22081.49306",
"unrealizedPnl": "8494.879599",
"returnOnEquity": "2.7782496288",
"liquidationPx": "213.2654356057",
"marginUsed": "2208.149306",
"maxLeverage": 10,
"cumFunding": {
"allTime": "-1875.469799",
"sinceOpen": "-1875.469799",
"sinceChange": "45.79339"
}
}
},
{
"type": "oneWay",
"position": {
"coin": "INJ",
"szi": "-18747.2",
"leverage": {
"type": "cross",
"value": 3
},
"entryPx": "13.01496",
"positionValue": "162200.7744",
"unrealizedPnl": "81793.4435",
"returnOnEquity": "1.005680924",
"liquidationPx": "1208.3529290194",
"marginUsed": "54066.9248",
"maxLeverage": 10,
"cumFunding": {
"allTime": "-539.133533",
"sinceOpen": "-539.133533",
"sinceChange": "-7.367325"
}
}
},
{
"type": "oneWay",
"position": {
"coin": "SUI",
"szi": "-376577.6",
"leverage": {
"type": "cross",
"value": 3
},
"entryPx": "3.85881",
"positionValue": "989495.3017599999",
"unrealizedPnl": "463648.956001",
"returnOnEquity": "0.9571980625",
"liquidationPx": "64.3045458208",
"marginUsed": "329831.767253",
"maxLeverage": 10,
"cumFunding": {
"allTime": "-45793.455728",
"sinceOpen": "-45793.450891",
"sinceChange": "-1233.875821"
}
}
},
{
"type": "oneWay",
"position": {
"coin": "XRP",
"szi": "-39691.0",
"leverage": {
"type": "cross",
"value": 20
},
"entryPx": "2.468585",
"positionValue": "105486.7707",
"unrealizedPnl": "-7506.1484",
"returnOnEquity": "-1.5321699789",
"liquidationPx": "607.2856858464",
"marginUsed": "5274.338535",
"maxLeverage": 20,
"cumFunding": {
"allTime": "-2645.400002",
"sinceOpen": "-116.036833",
"sinceChange": "-116.036833"
}
}
},
{
"type": "oneWay",
"position": {
"coin": "HYPE",
"szi": "-750315.16",
"leverage": {
"type": "cross",
"value": 5
},
"entryPx": "43.3419",
"positionValue": "34957933.6195600033",
"unrealizedPnl": "-2437823.0249080001",
"returnOnEquity": "-0.3748177636",
"liquidationPx": "76.3945326684",
"marginUsed": "6991586.7239119997",
"maxLeverage": 5,
"cumFunding": {
"allTime": "-1881584.4214250001",
"sinceOpen": "-1881584.4214250001",
"sinceChange": "-45247.838743"
}
}
},
{
"type": "oneWay",
"position": {
"coin": "FARTCOIN",
"szi": "-4122236.7999999998",
"leverage": {
"type": "cross",
"value": 10
},
"entryPx": "0.80127",
"positionValue": "1681584.057824",
"unrealizedPnl": "1621478.3279619999",
"returnOnEquity": "4.9090151459",
"liquidationPx": "6.034656163",
"marginUsed": "168158.405782",
"maxLeverage": 10,
"cumFunding": {
"allTime": "-72941.395024",
"sinceOpen": "-51271.5204",
"sinceChange": "-6504.295598"
}
}
},
{
"type": "oneWay",
"position": {
"coin": "PUMP",
"szi": "-1921732999.0",
"leverage": {
"type": "cross",
"value": 5
},
"entryPx": "0.005551",
"positionValue": "9176275.0702250004",
"unrealizedPnl": "1491738.24016",
"returnOnEquity": "0.6991640321",
"liquidationPx": "0.0166674064",
"marginUsed": "1835255.0140450001",
"maxLeverage": 10,
"cumFunding": {
"allTime": "-196004.534539",
"sinceOpen": "-196004.534539",
"sinceChange": "-9892.654861"
}
}
}
],
"time": 1761595358385
},
"account_value": 30018881.119369,
"margin_used": 22969943.984845,
"margin_utilization": 0.765183215640378,
"available_margin": 7048937.134523999,
"total_position_value": 0.0,
"portfolio_leverage": 0.0
},
"open_orders": {
"raw_orders": [
{
"coin": "WLFI",
"side": "B",
"limitPx": "0.10447",
"sz": "2624.0",
"oid": 194029229960,
"timestamp": 1760131688558,
"origSz": "12760.0",
"cloid": "0x00000000000000000000001261000016"
},
{
"coin": "@166",
"side": "A",
"limitPx": "1.01",
"sz": "103038.77",
"oid": 174787748753,
"timestamp": 1758819420037,
"origSz": "3000000.0"
}
]
},
"account_metrics": {
"cumVlm": "2823125892.6900000572",
"nRequestsUsed": 1766294,
"nRequestsCap": 2823135892
}
}
}

View File

@ -0,0 +1,7 @@
[
{
"name": "Whale 1 (BTC Maxi)",
"address": "0xb83de012dba672c76a7dbbbf3e459cb59d7d6e36",
"tags": ["btc", "high_leverage"]
}
]

View File

@ -0,0 +1,2 @@
# This file can be empty.
# It tells Python that 'position_logic' is a directory containing modules.

View File

@ -0,0 +1,31 @@
from abc import ABC, abstractmethod
import logging
class BasePositionLogic(ABC):
"""
Abstract base class for all strategy-specific position logic.
Defines the interface for how the PositionManager interacts with logic modules.
"""
def __init__(self, strategy_name: str, send_order_callback, log_trade_callback):
self.strategy_name = strategy_name
self.send_order = send_order_callback
self.log_trade = log_trade_callback
logging.info(f"Initialized position logic for '{strategy_name}'")
@abstractmethod
def handle_signal(self, signal_data: dict, current_strategy_positions: dict) -> dict:
"""
The core logic method. This is called by the PositionManager when a
new signal arrives for this strategy.
Args:
signal_data: The full signal dictionary from the strategy.
current_strategy_positions: A dict of this strategy's current positions,
keyed by coin (e.g., {"BTC": {"side": "long", ...}}).
Returns:
A dictionary representing the new state for the *specific coin* in the
signal (e.g., {"side": "long", "size": 0.1}).
Return None to indicate the position for this coin should be closed/removed.
"""
pass

View File

@ -0,0 +1,83 @@
import logging
from position_logic.base_logic import BasePositionLogic
class DefaultFlipLogic(BasePositionLogic):
"""
The standard "flip-on-signal" logic used by most simple strategies
(SMA, MA Cross, and even the per-coin Copy Trader signals).
- BUY signal: Closes any short, opens a long.
- SELL signal: Closes any long, opens a short.
- FLAT signal: Closes any open position.
"""
def handle_signal(self, signal_data: dict, current_strategy_positions: dict) -> dict:
"""
Processes a BUY, SELL, or FLAT signal and issues the necessary orders
to flip or open a position.
"""
name = self.strategy_name
params = signal_data['config']['parameters']
coin = signal_data['coin']
desired_signal = signal_data['signal']
signal_price = signal_data.get('signal_price', 0)
size = params.get('size')
leverage_long = int(params.get('leverage_long', 2))
leverage_short = int(params.get('leverage_short', 2))
agent_name = signal_data['config'].get("agent", "default").lower()
# --- This logic now correctly targets a specific coin ---
current_position = current_strategy_positions.get(coin)
new_position_state = None # Return None to close position
if desired_signal == "BUY" or desired_signal == "INIT_BUY":
new_position_state = {"coin": coin, "side": "long", "size": size}
if not current_position:
logging.warning(f"[{name}]-[{coin}] ACTION: Setting leverage to {leverage_long}x and opening LONG.")
self.send_order(agent_name, "update_leverage", coin, is_buy=True, size=leverage_long)
self.send_order(agent_name, "market_open", coin, is_buy=True, size=size)
self.log_trade(strategy=name, coin=coin, action="OPEN_LONG", price=signal_price, size=size, signal=desired_signal)
elif current_position['side'] == 'short':
logging.warning(f"[{name}]-[{coin}] ACTION: Closing SHORT and opening LONG with {leverage_long}x leverage.")
self.send_order(agent_name, "update_leverage", coin, is_buy=True, size=leverage_long)
self.send_order(agent_name, "market_open", coin, is_buy=True, size=current_position['size'], reduce_only=True)
self.log_trade(strategy=name, coin=coin, action="CLOSE_SHORT", price=signal_price, size=current_position['size'], signal=desired_signal)
self.send_order(agent_name, "market_open", coin, is_buy=True, size=size)
self.log_trade(strategy=name, coin=coin, action="OPEN_LONG", price=signal_price, size=size, signal=desired_signal)
else: # Already long, do nothing
logging.info(f"[{name}]-[{coin}] INFO: Already LONG, no action taken.")
new_position_state = current_position # State is unchanged
elif desired_signal == "SELL" or desired_signal == "INIT_SELL":
new_position_state = {"coin": coin, "side": "short", "size": size}
if not current_position:
logging.warning(f"[{name}]-[{coin}] ACTION: Setting leverage to {leverage_short}x and opening SHORT.")
self.send_order(agent_name, "update_leverage", coin, is_buy=False, size=leverage_short)
self.send_order(agent_name, "market_open", coin, is_buy=False, size=size)
self.log_trade(strategy=name, coin=coin, action="OPEN_SHORT", price=signal_price, size=size, signal=desired_signal)
elif current_position['side'] == 'long':
logging.warning(f"[{name}]-[{coin}] ACTION: Closing LONG and opening SHORT with {leverage_short}x leverage.")
self.send_order(agent_name, "update_leverage", coin, is_buy=False, size=leverage_short)
self.send_order(agent_name, "market_open", coin, is_buy=False, size=current_position['size'], reduce_only=True)
self.log_trade(strategy=name, coin=coin, action="CLOSE_LONG", price=signal_price, size=current_position['size'], signal=desired_signal)
self.send_order(agent_name, "market_open", coin, is_buy=False, size=size)
self.log_trade(strategy=name, coin=coin, action="OPEN_SHORT", price=signal_price, size=size, signal=desired_signal)
else: # Already short, do nothing
logging.info(f"[{name}]-[{coin}] INFO: Already SHORT, no action taken.")
new_position_state = current_position # State is unchanged
elif desired_signal == "FLAT":
if current_position:
logging.warning(f"[{name}]-[{coin}] ACTION: Close {current_position['side']} position.")
is_buy = current_position['side'] == 'short' # To close a short, we buy
self.send_order(agent_name, "market_open", coin, is_buy=is_buy, size=current_position['size'], reduce_only=True)
self.log_trade(strategy=name, coin=coin, action=f"CLOSE_{current_position['side'].upper()}", price=signal_price, size=current_position['size'], signal=desired_signal)
# new_position_state is already None, which will remove it
return new_position_state

79
review.md Normal file
View File

@ -0,0 +1,79 @@
# Project Review and Recommendations
This review provides an analysis of the current state of the automated trading bot project, proposes specific code improvements, and identifies files that appear to be unused or are one-off utilities that could be reorganized.
The project is a well-structured, multi-process Python application for crypto trading. It has a clear separation of concerns between data fetching, strategy execution, and trade management. The use of `multiprocessing` and a centralized `main_app.py` orchestrator is a solid architectural choice.
The following sections detail recommendations for improving configuration management, code structure, and robustness, along with a list of files recommended for cleanup.
---
## Proposed Code Changes
### 1. Centralize Configuration
- **Issue:** Key configuration variables like `WATCHED_COINS` and `required_timeframes` are hardcoded in `main_app.py`. This makes them difficult to change without modifying the source code.
- **Proposal:**
- Create a central configuration file, e.g., `_data/config.json`.
- Move `WATCHED_COINS` and `required_timeframes` into this new file.
- Load this configuration in `main_app.py` at startup.
- **Benefit:** Decouples configuration from code, making the application more flexible and easier to manage.
### 2. Refactor `main_app.py` for Clarity
- **Issue:** `main_app.py` is long and handles multiple responsibilities: process orchestration, dashboard rendering, and data reading.
- **Proposal:**
- **Abstract Process Management:** The functions for running subprocesses (e.g., `run_live_candle_fetcher`, `run_resampler_job`) contain repetitive logic for logging, shutdown handling, and process looping. This could be abstracted into a generic `ProcessRunner` class.
- **Create a Dashboard Class:** The complex dashboard rendering logic could be moved into a separate `Dashboard` class to improve separation of concerns and make the main application loop cleaner.
- **Benefit:** Improves code readability, reduces duplication, and makes the application easier to maintain and extend.
### 3. Improve Project Structure
- **Issue:** The root directory is cluttered with numerous Python scripts, making it difficult to distinguish between core application files, utility scripts, and old/example files.
- **Proposal:**
- Create a `scripts/` directory and move all one-off utility and maintenance scripts into it.
- Consider creating a `src/` or `app/` directory to house the core application source code (`main_app.py`, `trade_executor.py`, etc.), separating it clearly from configuration, data, and documentation.
- **Benefit:** A cleaner, more organized project structure that is easier for new developers to understand.
### 4. Enhance Robustness and Error Handling
- **Issue:** The agent loading in `trade_executor.py` relies on discovering environment variables by a naming convention (`_AGENT_PK`). This is clever but can be brittle if environment variables are named incorrectly.
- **Proposal:**
- Explicitly define the agent names and their corresponding environment variable keys in the proposed `_data/config.json` file. The `trade_executor` would then load only the agents specified in the configuration.
- **Benefit:** Makes agent configuration more explicit and less prone to errors from stray environment variables.
---
## Identified Unused/Utility Files
The following files were identified as likely being unused by the core application, being obsolete, or serving as one-off utilities. It is recommended to **move them to a `scripts/` directory** or **delete them** if they are obsolete.
### Obsolete / Old Versions:
- `data_fetcher_old.py`
- `market_old.py`
- `base_strategy.py` (The one in the root directory; the one in `strategies/` is used).
### One-Off Utility Scripts (Recommend moving to `scripts/`):
- `!migrate_to_sqlite.py`
- `import_csv.py`
- `del_market_cap_tables.py`
- `fix_timestamps.py`
- `list_coins.py`
- `create_agent.py`
### Examples / Unused Code:
- `basic_ws.py` (Appears to be an example file).
- `backtester.py`
- `strategy_sma_cross.py` (A strategy file in the root, not in the `strategies` folder).
- `strategy_template.py`
### Standalone / Potentially Unused Core Files:
The following files seem to have their logic already integrated into the main multi-process application. They might be remnants of a previous architecture and may not be needed as standalone scripts.
- `address_monitor.py`
- `position_monitor.py`
- `trade_log.py`
- `wallet_data.py`
- `whale_tracker.py`
### Data / Log Files (Recommend archiving or deleting):
- `hyperliquid_wallet_data_*.json` (These appear to be backups or logs).