Back to skills
SkillHub ClubResearch & OpsFull StackData / AI

trading-research

Binance cryptocurrency trading research, technical analysis, and position management. Triggers on requests for crypto prices, market data, trading analysis, DCA planning, position sizing, whale activity, or any trading research questions about Bitcoin, altcoins, or crypto markets.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,084
Hot score
99
Updated
March 20, 2026
Overall rating
C5.7
Composite score
5.7
Best-practice grade
C64.8

Install command

npx @skill-hub/cli install openclaw-skills-trading-research

Repository

openclaw/skills

Skill path: skills/fpsjago/trading-research

Binance cryptocurrency trading research, technical analysis, and position management. Triggers on requests for crypto prices, market data, trading analysis, DCA planning, position sizing, whale activity, or any trading research questions about Bitcoin, altcoins, or crypto markets.

Open repository

Best for

Primary workflow: Research & Ops.

Technical facets: Full Stack, Data / AI.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install trading-research into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding trading-research to shared team environments
  • Use trading-research for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: trading-research
description: Binance cryptocurrency trading research, technical analysis, and position management. Triggers on requests for crypto prices, market data, trading analysis, DCA planning, position sizing, whale activity, or any trading research questions about Bitcoin, altcoins, or crypto markets.
---

# Trading Research Skill

Comprehensive cryptocurrency trading research and analysis focused on Binance markets. Designed for conservative-moderate risk traders using DCA (Dollar Cost Averaging) strategies with technical analysis support.

## When to Use This Skill

Activate when user requests:
- Current crypto prices or market data
- Technical analysis (RSI, MACD, Bollinger Bands, etc.)
- DCA strategy planning or schedule calculation
- Position sizing with risk management
- Market scanning for opportunities
- Whale tracking or large order monitoring
- Trading strategy advice or risk assessment

## Core Philosophy

- **Conservative first**: Preserve capital, minimize risk
- **DCA-focused**: Time in market > timing the market
- **Risk management**: Never risk more than 1-2% per trade
- **Data-driven**: Use technical indicators for confirmation, not prediction
- **Transparent**: Show calculations, explain reasoning

## Available Tools

### 1. Market Data (`binance_market.py`)

Fetch real-time Binance market data.

**Use when**: User asks for price, volume, orderbook, recent trades, or funding rates.

**Common commands**:
```bash
# Current price and 24h stats (default)
python3 scripts/binance_market.py --symbol BTCUSDT

# Orderbook depth
python3 scripts/binance_market.py --symbol BTCUSDT --orderbook --depth 20

# Candlestick data
python3 scripts/binance_market.py --symbol BTCUSDT --klines 1h --limit 100

# Recent trades
python3 scripts/binance_market.py --symbol BTCUSDT --trades --limit 100

# Funding rate (futures)
python3 scripts/binance_market.py --symbol BTCUSDT --funding

# All data at once
python3 scripts/binance_market.py --symbol BTCUSDT --all

# JSON output (for piping)
python3 scripts/binance_market.py --symbol BTCUSDT --json > btc_data.json
```

**Intervals**: 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w

### 2. Technical Analysis (`technical_analysis.py`)

Calculate and interpret technical indicators.

**Use when**: User asks for TA, indicators, buy/sell signals, or market analysis.

**Common commands**:
```bash
# Full analysis (default: 1h timeframe, 200 candles)
python3 scripts/technical_analysis.py --symbol BTCUSDT

# Different timeframe
python3 scripts/technical_analysis.py --symbol BTCUSDT --interval 4h

# Custom RSI period
python3 scripts/technical_analysis.py --symbol BTCUSDT --rsi-period 21

# From saved klines JSON
python3 scripts/technical_analysis.py --input btc_klines.json

# JSON output
python3 scripts/technical_analysis.py --symbol BTCUSDT --json
```

**What it analyzes**:
- Trend direction (SMA 20/50, EMA 12/26)
- RSI (14) - overbought/oversold
- MACD - momentum and crossovers
- Bollinger Bands - volatility and position
- Support/resistance levels
- Volume analysis
- Trading signals and recommendations

### 3. DCA Calculator (`dca_calculator.py`)

Plan Dollar Cost Averaging strategies.

**Use when**: User wants to set up DCA, calculate investment schedules, or compare strategies.

**Common commands**:
```bash
# Basic DCA plan
python3 scripts/dca_calculator.py --total 5000 --frequency weekly --duration 180

# With current price for projections
python3 scripts/dca_calculator.py --total 10000 --frequency monthly --duration 365 --current-price 100000

# Show scenario analysis
python3 scripts/dca_calculator.py --total 5000 --frequency weekly --duration 180 --current-price 100000 --scenarios

# Custom start date
python3 scripts/dca_calculator.py --total 5000 --frequency weekly --duration 180 --start-date 2026-03-01

# JSON output
python3 scripts/dca_calculator.py --total 5000 --frequency weekly --duration 180 --json
```

**Frequencies**: daily, weekly, biweekly, monthly

**Output includes**:
- Purchase schedule with dates and amounts
- Number of purchases and amount per purchase
- Scenario analysis (flat, bull, bear markets)
- Comparison to lump sum approach

### 4. Position Sizer (`position_sizer.py`)

Calculate safe position sizes using risk management rules.

**Use when**: User wants to enter a trade and needs to know position size, stop loss, or take profit levels.

**Common commands**:
```bash
# Basic position sizing (2% risk recommended)
python3 scripts/position_sizer.py --balance 10000 --risk 2 --entry 100000 --stop-loss 95000

# Conservative 1% risk
python3 scripts/position_sizer.py --balance 10000 --risk 1 --entry 100000 --stop-loss 97000

# Custom take-profit ratios
python3 scripts/position_sizer.py --balance 10000 --risk 2 --entry 100000 --stop-loss 95000 --take-profit 2 3 5

# Ladder strategy (scaling in)
python3 scripts/position_sizer.py --balance 10000 --risk 2 --entry 100000 --stop-loss 95000 --ladder 3

# JSON output
python3 scripts/position_sizer.py --balance 10000 --risk 2 --entry 100000 --stop-loss 95000 --json
```

**Output includes**:
- Position size in units and dollar value
- Risk amount in dollars
- Stop loss percentage
- Take profit levels at multiple R:R ratios
- Position as percentage of account
- Warnings if position too large

**Rules**:
- Conservative: Risk 1% per trade
- Moderate: Risk 2% per trade
- Never exceed 3% risk per trade
- Position should be <50% of account

### 5. Market Scanner (`market_scanner.py`)

Scan all Binance USDT pairs for opportunities.

**Use when**: User wants to find top movers, volume spikes, or new opportunities.

**Common commands**:
```bash
# Full market scan (default)
python3 scripts/market_scanner.py

# Top gainers only
python3 scripts/market_scanner.py --gainers --limit 20

# High volume pairs
python3 scripts/market_scanner.py --volume

# Most volatile pairs
python3 scripts/market_scanner.py --volatile

# Breakout candidates (near 24h high with volume)
python3 scripts/market_scanner.py --breakout

# Filter by minimum volume
python3 scripts/market_scanner.py --min-volume 500000

# JSON output
python3 scripts/market_scanner.py --json
```

**Categories scanned**:
- Top gainers (24h price change)
- Top losers (24h price change)
- Highest volume pairs
- Most volatile pairs (high-low spread)
- Potential breakouts (near 24h high + volume)

### 6. Whale Tracker (`whale_tracker.py`)

Monitor large trades and orderbook imbalances.

**Use when**: User asks about whale activity, large orders, or orderbook pressure.

**Common commands**:
```bash
# Full whale analysis (default)
python3 scripts/whale_tracker.py --symbol BTCUSDT

# Large trades only
python3 scripts/whale_tracker.py --symbol BTCUSDT --trades

# Orderbook imbalances only
python3 scripts/whale_tracker.py --symbol BTCUSDT --orderbook

# Custom orderbook depth
python3 scripts/whale_tracker.py --symbol BTCUSDT --orderbook --depth 50

# Adjust threshold (default 90th percentile)
python3 scripts/whale_tracker.py --symbol BTCUSDT --threshold 95

# JSON output
python3 scripts/whale_tracker.py --symbol BTCUSDT --json
```

**Output includes**:
- Large trades (top 10% by value)
- Buy vs sell pressure from large trades
- Orderbook bid/ask imbalance
- Orderbook walls (large orders)
- Market sentiment (bullish/bearish/neutral)

## Quick Start Workflows

### "What's BTC doing?"
```bash
# Get overview
python3 scripts/binance_market.py --symbol BTCUSDT --ticker

# Technical analysis
python3 scripts/technical_analysis.py --symbol BTCUSDT --interval 1h
```

### "Should I buy now?"
```bash
# Check technicals first
python3 scripts/technical_analysis.py --symbol BTCUSDT

# Check whale activity
python3 scripts/whale_tracker.py --symbol BTCUSDT

# If signals look good, calculate position size
python3 scripts/position_sizer.py --balance 10000 --risk 2 --entry <CURRENT_PRICE> --stop-loss <SUPPORT_LEVEL>
```

### "Set up a DCA plan"
```bash
# Plan the strategy
python3 scripts/dca_calculator.py --total 5000 --frequency weekly --duration 180 --current-price <CURRENT_PRICE> --scenarios

# Show them the schedule and explain
```

### "Find me opportunities"
```bash
# Scan market
python3 scripts/market_scanner.py

# For interesting pairs, do deeper analysis
python3 scripts/technical_analysis.py --symbol <PAIR>
python3 scripts/whale_tracker.py --symbol <PAIR>
```

### "What's the market sentiment?"
```bash
# Check whale activity
python3 scripts/whale_tracker.py --symbol BTCUSDT

# Check volume and volatility
python3 scripts/market_scanner.py --volume --volatile
```

## Reference Materials

Located in `references/` directory:

### `binance-api.md`
- API endpoints and parameters
- Rate limits
- Authentication for signed requests
- Order types and time-in-force
- Error codes
- Python examples

**Use when**: Need API details, building custom queries, or troubleshooting

### `indicators.md`
- Technical indicator formulas
- Interpretation guidelines
- Common settings per timeframe
- Combining indicators
- Reliability assessment
- Common mistakes

**Use when**: Explaining indicators, interpreting signals, or educating user

### `strategies.md`
- DCA variations (fixed, value-based, RSI-based, ladder)
- Risk management (1-2% rule, stop loss strategies)
- Trend following strategies
- Entry/exit strategies
- Position sizing examples
- Performance tracking

**Use when**: Planning trades, explaining strategies, or risk management questions

## Trading Guidance

### For Conservative Traders

**DCA Approach**:
- Start with weekly or monthly purchases
- Fixed amount: $50-200 per purchase
- Duration: 6-12 months minimum
- Don't try to time the market
- Accumulate and hold long-term

**Risk Management**:
- No leverage
- 50%+ of account in cash/stablecoins
- Risk 1% per trade maximum
- Only trade with 3+ confirmations
- Stop losses always active

### For Moderate Risk Traders

**Enhanced DCA**:
- Adjust amounts based on RSI (buy more when oversold)
- Use technical analysis for better entries
- 60-70% DCA, 30-40% active trading
- Risk 2% per trade on active positions

**Position Trading**:
- Wait for confluence of indicators
- Use position_sizer.py for every trade
- Risk:Reward ratio minimum 2:1
- Trail stops as profit grows

### Red Flags (Don't Trade)

- RSI >70 and rising (overbought)
- Low volume breakout (likely false)
- Against major trend (don't short bull market)
- Multiple indicators conflicting
- No clear support level for stop loss
- Risk:Reward ratio <1.5:1
- During extreme fear or greed

## Response Format

When user asks for analysis:

1. **Current State**: Price, trend, key levels
2. **Technical View**: Indicator readings and what they mean
3. **Sentiment**: Whale activity, volume, market pressure
4. **Recommendation**: Buy/wait/sell with reasoning
5. **Risk Management**: Position size, stop loss, take profit if applicable
6. **Caveats**: What could go wrong, alternative scenarios

Always include:
- Specific numbers (don't just say "oversold", say "RSI at 28")
- Risk warnings for trades
- Clear next steps
- Timeframe context (day trade vs swing trade vs long-term)

## Important Notes

### API Access
- All scripts use Binance public API (no authentication needed for data)
- Respect rate limits (built into scripts)
- If API blocked by geo-restrictions, scripts will error gracefully

### Limitations
- **No trading execution**: These tools are for research only
- **No real-time WebSocket**: Data is snapshot-based (REST API)
- **No futures-specific features**: Primarily spot market focused (except funding rates)
- **No backtesting engine**: Manual strategy evaluation

### Authentication Required For
- Placing orders
- Checking account balance
- Viewing open orders
- Accessing trade history

**Note**: Guide users to Binance API documentation (see `references/binance-api.md`) for authenticated trading setup.

## Error Handling

If script fails:
1. Check internet connection
2. Verify symbol format (uppercase, e.g., BTCUSDT not btc-usdt)
3. Check if Binance API accessible in user's location
4. Verify script path and Python availability
5. Check for typos in parameters

Common errors:
- **HTTP 451**: API blocked in location (suggest VPN)
- **Invalid symbol**: Check symbol exists on Binance
- **Rate limit**: Wait 60 seconds and retry
- **Connection timeout**: Network issue or API down

## Best Practices

1. **Always show your work**: Display the command you ran
2. **Interpret results**: Don't just dump data, explain what it means
3. **Context matters**: Different advice for day trade vs DCA accumulation
4. **Risk first**: Mention risk management before entry signals
5. **Be honest**: If indicators conflict, say so
6. **Update knowledge**: If market conditions changed, acknowledge it
7. **No predictions**: Frame as "if X then Y", not "X will happen"
8. **Show alternatives**: Bull and bear case scenarios

## Skill Maintenance

### Testing
Run each script monthly to ensure API compatibility:
```bash
python3 scripts/binance_market.py --symbol BTCUSDT --help
python3 scripts/technical_analysis.py --help
python3 scripts/dca_calculator.py --help
python3 scripts/position_sizer.py --help
python3 scripts/market_scanner.py --help
python3 scripts/whale_tracker.py --help
```

### Updates Needed If
- Binance changes API endpoints
- New technical indicators requested
- Additional risk management tools needed
- User feedback suggests improvements

---

**Remember**: This skill helps users make informed decisions. It does not make decisions for them. Always emphasize personal responsibility and risk disclosure.


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### scripts/binance_market.py

```python
#!/usr/bin/env python3
"""
Binance Market Data Fetcher
Fetch price, orderbook, 24h stats, funding rates, and klines from Binance public API
"""

import json
import argparse
import sys
from urllib import request, error
from urllib.parse import urlencode

BASE_URL = "https://data-api.binance.vision"
FAPI_URL = "https://fapi.binance.com"

def fetch_json(url):
    """Fetch JSON data from URL with error handling"""
    try:
        with request.urlopen(url, timeout=10) as response:
            return json.loads(response.read().decode())
    except error.HTTPError as e:
        print(f"HTTP Error {e.code}: {e.reason}", file=sys.stderr)
        sys.exit(1)
    except error.URLError as e:
        print(f"Connection Error: {e.reason}", file=sys.stderr)
        sys.exit(1)
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)

def get_price(symbol):
    """Get current price for a symbol"""
    url = f"{BASE_URL}/api/v3/ticker/price?symbol={symbol}"
    data = fetch_json(url)
    return data

def get_ticker_24h(symbol):
    """Get 24h ticker statistics"""
    url = f"{BASE_URL}/api/v3/ticker/24hr?symbol={symbol}"
    data = fetch_json(url)
    return data

def get_orderbook(symbol, limit=20):
    """Get orderbook depth"""
    url = f"{BASE_URL}/api/v3/depth?symbol={symbol}&limit={limit}"
    data = fetch_json(url)
    return data

def get_recent_trades(symbol, limit=100):
    """Get recent trades"""
    url = f"{BASE_URL}/api/v3/trades?symbol={symbol}&limit={limit}"
    data = fetch_json(url)
    return data

def get_klines(symbol, interval, limit=100):
    """Get candlestick data (klines)
    
    Intervals: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M
    """
    url = f"{BASE_URL}/api/v3/klines?symbol={symbol}&interval={interval}&limit={limit}"
    data = fetch_json(url)
    
    # Format klines for readability
    formatted = []
    for k in data:
        formatted.append({
            'open_time': k[0],
            'open': float(k[1]),
            'high': float(k[2]),
            'low': float(k[3]),
            'close': float(k[4]),
            'volume': float(k[5]),
            'close_time': k[6],
            'quote_volume': float(k[7]),
            'trades': k[8],
            'taker_buy_base': float(k[9]),
            'taker_buy_quote': float(k[10])
        })
    return formatted

def get_funding_rate(symbol):
    """Get current funding rate (futures only)"""
    try:
        url = f"{FAPI_URL}/fapi/v1/premiumIndex?symbol={symbol}"
        data = fetch_json(url)
        return data
    except:
        return {"error": "Funding rate only available for futures symbols"}

def format_price_output(data):
    """Format price data for display"""
    print(f"Symbol: {data['symbol']}")
    print(f"Price: ${float(data['price']):,.2f}")

def format_ticker_output(data):
    """Format 24h ticker data for display"""
    price_change = float(data['priceChange'])
    price_change_pct = float(data['priceChangePercent'])
    
    print(f"Symbol: {data['symbol']}")
    print(f"Current Price: ${float(data['lastPrice']):,.2f}")
    print(f"24h Change: ${price_change:,.2f} ({price_change_pct:+.2f}%)")
    print(f"24h High: ${float(data['highPrice']):,.2f}")
    print(f"24h Low: ${float(data['lowPrice']):,.2f}")
    print(f"24h Volume: {float(data['volume']):,.2f} {data['symbol'][:-4]}")
    print(f"24h Quote Volume: ${float(data['quoteVolume']):,.2f}")
    print(f"Trades: {data['count']:,}")

def format_orderbook_output(data, depth=10):
    """Format orderbook data for display"""
    print(f"\nOrderbook (Top {depth} levels):")
    print(f"\n{'Price':<15} {'Bids':<15} {'Asks':<15}")
    print("-" * 45)
    
    bids = data['bids'][:depth]
    asks = data['asks'][:depth]
    max_len = max(len(bids), len(asks))
    
    for i in range(max_len):
        bid_price = f"${float(bids[i][0]):,.2f}" if i < len(bids) else ""
        bid_qty = f"{float(bids[i][1]):,.4f}" if i < len(bids) else ""
        ask_price = f"${float(asks[i][0]):,.2f}" if i < len(asks) else ""
        ask_qty = f"{float(asks[i][1]):,.4f}" if i < len(asks) else ""
        
        print(f"{bid_price:<15} {bid_qty:<15} {ask_qty:<15}")

def format_trades_output(data, limit=10):
    """Format recent trades for display"""
    print(f"\nRecent Trades (Last {limit}):")
    print(f"{'Price':<15} {'Quantity':<15} {'Time':<20} {'Buyer Maker'}")
    print("-" * 70)
    
    for trade in data[-limit:]:
        price = f"${float(trade['price']):,.2f}"
        qty = f"{float(trade['qty']):,.4f}"
        from datetime import datetime
        time_str = datetime.fromtimestamp(trade['time']/1000).strftime('%Y-%m-%d %H:%M:%S')
        buyer_maker = "Sell" if trade['isBuyerMaker'] else "Buy"
        
        print(f"{price:<15} {qty:<15} {time_str:<20} {buyer_maker}")

def format_klines_output(data, limit=10):
    """Format klines for display"""
    print(f"\nCandlestick Data (Last {limit}):")
    print(f"{'Open Time':<20} {'Open':<12} {'High':<12} {'Low':<12} {'Close':<12} {'Volume':<15}")
    print("-" * 95)
    
    from datetime import datetime
    for k in data[-limit:]:
        time_str = datetime.fromtimestamp(k['open_time']/1000).strftime('%Y-%m-%d %H:%M')
        print(f"{time_str:<20} ${k['open']:<11,.2f} ${k['high']:<11,.2f} ${k['low']:<11,.2f} ${k['close']:<11,.2f} {k['volume']:<14,.2f}")

def format_funding_output(data):
    """Format funding rate for display"""
    if 'error' in data:
        print(f"Error: {data['error']}")
        return
    
    print(f"Symbol: {data['symbol']}")
    print(f"Mark Price: ${float(data['markPrice']):,.2f}")
    print(f"Index Price: ${float(data['indexPrice']):,.2f}")
    print(f"Funding Rate: {float(data['lastFundingRate']) * 100:.4f}%")
    print(f"Next Funding Time: {data['nextFundingTime']}")

def main():
    parser = argparse.ArgumentParser(description='Fetch Binance market data')
    parser.add_argument('--symbol', '-s', default='BTCUSDT', help='Trading pair symbol (default: BTCUSDT)')
    parser.add_argument('--price', '-p', action='store_true', help='Get current price')
    parser.add_argument('--ticker', '-t', action='store_true', help='Get 24h ticker stats')
    parser.add_argument('--orderbook', '-o', action='store_true', help='Get orderbook depth')
    parser.add_argument('--trades', '-r', action='store_true', help='Get recent trades')
    parser.add_argument('--klines', '-k', metavar='INTERVAL', help='Get klines (1m,5m,15m,1h,4h,1d,1w)')
    parser.add_argument('--funding', '-f', action='store_true', help='Get funding rate (futures)')
    parser.add_argument('--limit', '-l', type=int, default=100, help='Limit for klines/trades (default: 100)')
    parser.add_argument('--depth', '-d', type=int, default=10, help='Orderbook depth to display (default: 10)')
    parser.add_argument('--json', '-j', action='store_true', help='Output raw JSON')
    parser.add_argument('--all', '-a', action='store_true', help='Fetch all data types')
    
    args = parser.parse_args()
    
    # If no specific flag, show price and ticker
    if not any([args.price, args.ticker, args.orderbook, args.trades, args.klines, args.funding, args.all]):
        args.price = True
        args.ticker = True
    
    symbol = args.symbol.upper()
    
    try:
        if args.all or args.price:
            data = get_price(symbol)
            if args.json:
                print(json.dumps(data, indent=2))
            else:
                format_price_output(data)
                print()
        
        if args.all or args.ticker:
            data = get_ticker_24h(symbol)
            if args.json:
                print(json.dumps(data, indent=2))
            else:
                format_ticker_output(data)
                print()
        
        if args.all or args.orderbook:
            data = get_orderbook(symbol, limit=20)
            if args.json:
                print(json.dumps(data, indent=2))
            else:
                format_orderbook_output(data, args.depth)
                print()
        
        if args.all or args.trades:
            data = get_recent_trades(symbol, limit=args.limit)
            if args.json:
                print(json.dumps(data, indent=2))
            else:
                format_trades_output(data, min(10, len(data)))
                print()
        
        if args.klines:
            data = get_klines(symbol, args.klines, limit=args.limit)
            if args.json:
                print(json.dumps(data, indent=2))
            else:
                format_klines_output(data, min(10, len(data)))
                print()
        
        if args.all or args.funding:
            data = get_funding_rate(symbol)
            if args.json:
                print(json.dumps(data, indent=2))
            else:
                format_funding_output(data)
                print()
                
    except KeyboardInterrupt:
        print("\nInterrupted", file=sys.stderr)
        sys.exit(1)

if __name__ == '__main__':
    main()

```

### scripts/technical_analysis.py

```python
#!/usr/bin/env python3
"""
Technical Analysis Calculator
Calculate RSI, MACD, Bollinger Bands, EMA, SMA, volume analysis from kline data
Can accept JSON input from binance_market.py or fetch directly
"""

import json
import argparse
import sys
from urllib import request, error
from statistics import mean, stdev

BASE_URL = "https://data-api.binance.vision"

def fetch_klines(symbol, interval, limit):
    """Fetch klines from Binance"""
    url = f"{BASE_URL}/api/v3/klines?symbol={symbol}&interval={interval}&limit={limit}"
    try:
        with request.urlopen(url, timeout=10) as response:
            data = json.loads(response.read().decode())
            return [
                {
                    'open_time': k[0],
                    'open': float(k[1]),
                    'high': float(k[2]),
                    'low': float(k[3]),
                    'close': float(k[4]),
                    'volume': float(k[5]),
                    'close_time': k[6],
                    'quote_volume': float(k[7])
                }
                for k in data
            ]
    except error.HTTPError as e:
        print(f"HTTP Error {e.code}: {e.reason}", file=sys.stderr)
        sys.exit(1)
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)

def calculate_sma(prices, period):
    """Calculate Simple Moving Average"""
    if len(prices) < period:
        return None
    return mean(prices[-period:])

def calculate_ema(prices, period):
    """Calculate Exponential Moving Average"""
    if len(prices) < period:
        return None
    
    multiplier = 2 / (period + 1)
    ema = mean(prices[:period])  # Start with SMA
    
    for price in prices[period:]:
        ema = (price - ema) * multiplier + ema
    
    return ema

def calculate_rsi(prices, period=14):
    """Calculate Relative Strength Index"""
    if len(prices) < period + 1:
        return None
    
    gains = []
    losses = []
    
    for i in range(1, len(prices)):
        change = prices[i] - prices[i-1]
        if change > 0:
            gains.append(change)
            losses.append(0)
        else:
            gains.append(0)
            losses.append(abs(change))
    
    avg_gain = mean(gains[-period:])
    avg_loss = mean(losses[-period:])
    
    if avg_loss == 0:
        return 100
    
    rs = avg_gain / avg_loss
    rsi = 100 - (100 / (1 + rs))
    
    return rsi

def calculate_macd(prices, fast=12, slow=26, signal=9):
    """Calculate MACD (Moving Average Convergence Divergence)"""
    if len(prices) < slow:
        return None, None, None
    
    ema_fast = calculate_ema(prices, fast)
    ema_slow = calculate_ema(prices, slow)
    
    if ema_fast is None or ema_slow is None:
        return None, None, None
    
    macd_line = ema_fast - ema_slow
    
    # Calculate signal line (EMA of MACD)
    # Simplified: using last value as approximation
    signal_line = macd_line  # In production, would track MACD history
    histogram = macd_line - signal_line
    
    return macd_line, signal_line, histogram

def calculate_bollinger_bands(prices, period=20, std_dev=2):
    """Calculate Bollinger Bands"""
    if len(prices) < period:
        return None, None, None
    
    sma = calculate_sma(prices, period)
    std = stdev(prices[-period:])
    
    upper_band = sma + (std * std_dev)
    lower_band = sma - (std * std_dev)
    
    return upper_band, sma, lower_band

def find_support_resistance(klines, lookback=20):
    """Find support and resistance levels using pivot points"""
    if len(klines) < lookback:
        return [], []
    
    highs = [k['high'] for k in klines[-lookback:]]
    lows = [k['low'] for k in klines[-lookback:]]
    
    # Simple approach: use recent highs/lows
    resistance_levels = []
    support_levels = []
    
    # Find local maxima/minima
    for i in range(1, len(highs) - 1):
        if highs[i] > highs[i-1] and highs[i] > highs[i+1]:
            resistance_levels.append(highs[i])
        if lows[i] < lows[i-1] and lows[i] < lows[i+1]:
            support_levels.append(lows[i])
    
    # Add overall high/low
    resistance_levels.append(max(highs))
    support_levels.append(min(lows))
    
    return sorted(set(resistance_levels), reverse=True)[:3], sorted(set(support_levels))[:3]

def analyze_volume(klines, period=20):
    """Analyze volume patterns"""
    if len(klines) < period:
        return None
    
    volumes = [k['volume'] for k in klines[-period:]]
    avg_volume = mean(volumes)
    current_volume = klines[-1]['volume']
    
    volume_ratio = current_volume / avg_volume if avg_volume > 0 else 0
    
    return {
        'current': current_volume,
        'average': avg_volume,
        'ratio': volume_ratio,
        'status': 'High' if volume_ratio > 1.5 else 'Normal' if volume_ratio > 0.5 else 'Low'
    }

def get_trend_signal(prices):
    """Simple trend detection"""
    if len(prices) < 20:
        return "Insufficient data"
    
    sma_20 = calculate_sma(prices, 20)
    sma_50 = calculate_sma(prices, 50) if len(prices) >= 50 else None
    current_price = prices[-1]
    
    if sma_50:
        if current_price > sma_20 > sma_50:
            return "Strong Uptrend"
        elif current_price < sma_20 < sma_50:
            return "Strong Downtrend"
        elif current_price > sma_20:
            return "Uptrend"
        else:
            return "Downtrend"
    else:
        if current_price > sma_20:
            return "Uptrend"
        else:
            return "Downtrend"

def analyze(klines, rsi_period=14, bb_period=20, show_all=False):
    """Perform comprehensive technical analysis"""
    closes = [k['close'] for k in klines]
    current_price = closes[-1]
    
    # Calculate indicators
    sma_20 = calculate_sma(closes, 20)
    sma_50 = calculate_sma(closes, 50)
    ema_12 = calculate_ema(closes, 12)
    ema_26 = calculate_ema(closes, 26)
    
    rsi = calculate_rsi(closes, rsi_period)
    macd_line, signal_line, histogram = calculate_macd(closes)
    bb_upper, bb_middle, bb_lower = calculate_bollinger_bands(closes, bb_period)
    
    resistance, support = find_support_resistance(klines)
    volume_analysis = analyze_volume(klines)
    trend = get_trend_signal(closes)
    
    # Format output
    print(f"{'='*60}")
    print(f"Technical Analysis")
    print(f"{'='*60}")
    print(f"\nCurrent Price: ${current_price:,.2f}")
    print(f"Trend: {trend}")
    
    print(f"\n{'Moving Averages:':<30}")
    if sma_20:
        print(f"  SMA(20): ${sma_20:,.2f}")
    if sma_50:
        print(f"  SMA(50): ${sma_50:,.2f}")
    if ema_12:
        print(f"  EMA(12): ${ema_12:,.2f}")
    if ema_26:
        print(f"  EMA(26): ${ema_26:,.2f}")
    
    print(f"\n{'Momentum Indicators:':<30}")
    if rsi is not None:
        rsi_status = "Overbought" if rsi > 70 else "Oversold" if rsi < 30 else "Neutral"
        print(f"  RSI({rsi_period}): {rsi:.2f} ({rsi_status})")
    
    if macd_line is not None:
        macd_status = "Bullish" if macd_line > signal_line else "Bearish"
        print(f"  MACD: {macd_line:.2f} ({macd_status})")
        print(f"  Signal: {signal_line:.2f}")
        print(f"  Histogram: {histogram:.2f}")
    
    print(f"\n{'Bollinger Bands:':<30}")
    if bb_upper:
        bb_position = ((current_price - bb_lower) / (bb_upper - bb_lower)) * 100
        print(f"  Upper: ${bb_upper:,.2f}")
        print(f"  Middle: ${bb_middle:,.2f}")
        print(f"  Lower: ${bb_lower:,.2f}")
        print(f"  Position: {bb_position:.1f}% (0%=Lower, 100%=Upper)")
    
    print(f"\n{'Support/Resistance Levels:':<30}")
    if resistance:
        print(f"  Resistance: {', '.join([f'${r:,.2f}' for r in resistance])}")
    if support:
        print(f"  Support: {', '.join([f'${s:,.2f}' for s in support])}")
    
    print(f"\n{'Volume Analysis:':<30}")
    if volume_analysis:
        print(f"  Current: {volume_analysis['current']:,.2f}")
        print(f"  Average(20): {volume_analysis['average']:,.2f}")
        print(f"  Ratio: {volume_analysis['ratio']:.2f}x ({volume_analysis['status']})")
    
    # Trading signals
    print(f"\n{'='*60}")
    print(f"Trading Signals")
    print(f"{'='*60}")
    
    signals = []
    
    if rsi is not None:
        if rsi < 30:
            signals.append("⚠ RSI oversold - potential buy opportunity")
        elif rsi > 70:
            signals.append("⚠ RSI overbought - consider taking profits")
    
    if bb_upper and bb_lower:
        if current_price >= bb_upper:
            signals.append("⚠ Price at upper Bollinger Band - overbought")
        elif current_price <= bb_lower:
            signals.append("⚠ Price at lower Bollinger Band - oversold")
    
    if volume_analysis and volume_analysis['ratio'] > 2:
        signals.append("šŸ“Š Unusually high volume - significant interest")
    
    if macd_line and signal_line:
        if macd_line > 0 and signal_line > 0:
            signals.append("āœ“ MACD bullish crossover")
        elif macd_line < 0 and signal_line < 0:
            signals.append("āœ— MACD bearish crossover")
    
    if signals:
        for signal in signals:
            print(f"  {signal}")
    else:
        print("  No strong signals detected")
    
    print(f"\n{'='*60}\n")
    
    # Return data for JSON output
    return {
        'price': current_price,
        'trend': trend,
        'sma_20': sma_20,
        'sma_50': sma_50,
        'ema_12': ema_12,
        'ema_26': ema_26,
        'rsi': rsi,
        'macd': {'line': macd_line, 'signal': signal_line, 'histogram': histogram},
        'bollinger_bands': {'upper': bb_upper, 'middle': bb_middle, 'lower': bb_lower},
        'support': support,
        'resistance': resistance,
        'volume': volume_analysis,
        'signals': signals
    }

def main():
    parser = argparse.ArgumentParser(description='Technical Analysis Calculator')
    parser.add_argument('--symbol', '-s', default='BTCUSDT', help='Trading pair symbol (default: BTCUSDT)')
    parser.add_argument('--interval', '-i', default='1h', help='Timeframe (1m,5m,15m,1h,4h,1d,1w) (default: 1h)')
    parser.add_argument('--limit', '-l', type=int, default=200, help='Number of candles to analyze (default: 200)')
    parser.add_argument('--rsi-period', type=int, default=14, help='RSI period (default: 14)')
    parser.add_argument('--bb-period', type=int, default=20, help='Bollinger Bands period (default: 20)')
    parser.add_argument('--input', '-f', help='Read klines from JSON file instead of API')
    parser.add_argument('--json', '-j', action='store_true', help='Output as JSON')
    
    args = parser.parse_args()
    
    try:
        if args.input:
            with open(args.input, 'r') as f:
                klines = json.load(f)
        else:
            klines = fetch_klines(args.symbol.upper(), args.interval, args.limit)
        
        if not klines:
            print("No data received", file=sys.stderr)
            sys.exit(1)
        
        result = analyze(klines, args.rsi_period, args.bb_period)
        
        if args.json:
            print(json.dumps(result, indent=2))
            
    except KeyboardInterrupt:
        print("\nInterrupted", file=sys.stderr)
        sys.exit(1)
    except FileNotFoundError:
        print(f"Error: File '{args.input}' not found", file=sys.stderr)
        sys.exit(1)
    except json.JSONDecodeError:
        print(f"Error: Invalid JSON in '{args.input}'", file=sys.stderr)
        sys.exit(1)

if __name__ == '__main__':
    main()

```

### scripts/dca_calculator.py

```python
#!/usr/bin/env python3
"""
DCA (Dollar Cost Averaging) Calculator
Plan DCA schedule, amount distribution, and cost averaging projections
"""

import json
import argparse
import sys
from datetime import datetime, timedelta

def calculate_dca_schedule(total_amount, frequency, duration_days, start_date=None):
    """Calculate DCA purchase schedule
    
    Args:
        total_amount: Total amount to invest
        frequency: 'daily', 'weekly', 'biweekly', 'monthly'
        duration_days: Total duration in days
        start_date: Start date (datetime object or None for today)
    """
    if start_date is None:
        start_date = datetime.now()
    
    # Determine interval days
    intervals = {
        'daily': 1,
        'weekly': 7,
        'biweekly': 14,
        'monthly': 30
    }
    
    interval_days = intervals.get(frequency.lower())
    if not interval_days:
        raise ValueError(f"Invalid frequency: {frequency}. Use: daily, weekly, biweekly, monthly")
    
    # Calculate number of purchases
    num_purchases = duration_days // interval_days
    if num_purchases == 0:
        num_purchases = 1
    
    amount_per_purchase = total_amount / num_purchases
    
    # Generate schedule
    schedule = []
    current_date = start_date
    
    for i in range(num_purchases):
        schedule.append({
            'purchase_number': i + 1,
            'date': current_date.strftime('%Y-%m-%d'),
            'amount': amount_per_purchase,
            'cumulative': amount_per_purchase * (i + 1)
        })
        current_date += timedelta(days=interval_days)
    
    return schedule, num_purchases, amount_per_purchase

def simulate_dca_returns(schedule, price_history):
    """Simulate DCA strategy with historical prices
    
    Args:
        schedule: List of purchase dates and amounts
        price_history: Dict of {date: price}
    """
    total_invested = 0
    total_units = 0
    purchases = []
    
    for entry in schedule:
        date = entry['date']
        amount = entry['amount']
        
        # Find price for this date (or closest available)
        price = price_history.get(date)
        if price is None:
            # Try to find closest date
            available_dates = sorted(price_history.keys())
            for d in available_dates:
                if d >= date:
                    price = price_history[d]
                    break
        
        if price is None:
            continue
        
        units = amount / price
        total_invested += amount
        total_units += units
        
        purchases.append({
            'date': date,
            'price': price,
            'amount': amount,
            'units': units,
            'total_units': total_units,
            'avg_price': total_invested / total_units
        })
    
    return purchases, total_invested, total_units

def calculate_lump_sum_comparison(total_amount, start_price, end_price):
    """Compare DCA to lump sum investment"""
    lump_sum_units = total_amount / start_price
    lump_sum_value = lump_sum_units * end_price
    lump_sum_return = ((lump_sum_value - total_amount) / total_amount) * 100
    
    return {
        'units': lump_sum_units,
        'final_value': lump_sum_value,
        'return_pct': lump_sum_return
    }

def format_schedule_output(schedule, num_purchases, amount_per_purchase, total_amount):
    """Format DCA schedule for display"""
    print(f"\n{'='*70}")
    print(f"DCA Investment Schedule")
    print(f"{'='*70}")
    print(f"Total Investment: ${total_amount:,.2f}")
    print(f"Number of Purchases: {num_purchases}")
    print(f"Amount per Purchase: ${amount_per_purchase:,.2f}")
    print(f"First Purchase: {schedule[0]['date']}")
    print(f"Last Purchase: {schedule[-1]['date']}")
    
    print(f"\n{'#':<5} {'Date':<12} {'Amount':<15} {'Cumulative':<15}")
    print("-" * 70)
    
    for entry in schedule[:10]:  # Show first 10
        print(f"{entry['purchase_number']:<5} {entry['date']:<12} ${entry['amount']:<14,.2f} ${entry['cumulative']:<14,.2f}")
    
    if len(schedule) > 10:
        print(f"... ({len(schedule) - 10} more purchases)")
        last = schedule[-1]
        print(f"{last['purchase_number']:<5} {last['date']:<12} ${last['amount']:<14,.2f} ${last['cumulative']:<14,.2f}")
    
    print()

def format_simulation_output(purchases, total_invested, total_units, current_price=None):
    """Format DCA simulation results"""
    if not purchases:
        print("No simulation data available")
        return
    
    avg_price = total_invested / total_units if total_units > 0 else 0
    
    print(f"\n{'='*70}")
    print(f"DCA Simulation Results")
    print(f"{'='*70}")
    print(f"Total Invested: ${total_invested:,.2f}")
    print(f"Total Units Acquired: {total_units:.6f}")
    print(f"Average Purchase Price: ${avg_price:,.2f}")
    
    if current_price:
        current_value = total_units * current_price
        profit_loss = current_value - total_invested
        roi = (profit_loss / total_invested) * 100 if total_invested > 0 else 0
        
        print(f"Current Price: ${current_price:,.2f}")
        print(f"Current Value: ${current_value:,.2f}")
        print(f"Profit/Loss: ${profit_loss:,.2f} ({roi:+.2f}%)")
    
    print(f"\n{'Purchase History:'}")
    print(f"{'Date':<12} {'Price':<12} {'Amount':<12} {'Units':<12} {'Avg Price':<12}")
    print("-" * 70)
    
    for p in purchases[:10]:
        print(f"{p['date']:<12} ${p['price']:<11,.2f} ${p['amount']:<11,.2f} {p['units']:<11.6f} ${p['avg_price']:<11,.2f}")
    
    if len(purchases) > 10:
        print(f"... ({len(purchases) - 10} more purchases)")
        last = purchases[-1]
        print(f"{last['date']:<12} ${last['price']:<11,.2f} ${last['amount']:<11,.2f} {last['units']:<11.6f} ${last['avg_price']:<11,.2f}")
    
    print()

def simple_projection(amount_per_purchase, num_purchases, current_price, price_scenarios):
    """Project DCA outcomes under different price scenarios"""
    print(f"\n{'='*70}")
    print(f"DCA Price Scenario Analysis")
    print(f"{'='*70}")
    print(f"Amount per Purchase: ${amount_per_purchase:,.2f}")
    print(f"Number of Purchases: {num_purchases}")
    print(f"Current Price: ${current_price:,.2f}")
    
    print(f"\n{'Scenario':<20} {'Avg Price':<15} {'Units':<15} {'Final Value':<15} {'ROI':<10}")
    print("-" * 70)
    
    total_invested = amount_per_purchase * num_purchases
    
    for scenario_name, avg_price in price_scenarios.items():
        total_units = total_invested / avg_price
        final_value = total_units * current_price
        roi = ((final_value - total_invested) / total_invested) * 100
        
        print(f"{scenario_name:<20} ${avg_price:<14,.2f} {total_units:<14.6f} ${final_value:<14,.2f} {roi:>9.2f}%")
    
    print()

def main():
    parser = argparse.ArgumentParser(description='DCA (Dollar Cost Averaging) Calculator')
    parser.add_argument('--total', '-t', type=float, required=True, help='Total amount to invest')
    parser.add_argument('--frequency', '-f', default='weekly', 
                       choices=['daily', 'weekly', 'biweekly', 'monthly'],
                       help='Purchase frequency (default: weekly)')
    parser.add_argument('--duration', '-d', type=int, required=True, 
                       help='Investment duration in days')
    parser.add_argument('--start-date', '-s', help='Start date (YYYY-MM-DD, default: today)')
    parser.add_argument('--current-price', '-p', type=float, 
                       help='Current asset price for projections')
    parser.add_argument('--scenarios', '-c', action='store_true',
                       help='Show price scenario analysis')
    parser.add_argument('--json', '-j', action='store_true', help='Output as JSON')
    
    args = parser.parse_args()
    
    try:
        # Parse start date
        start_date = None
        if args.start_date:
            start_date = datetime.strptime(args.start_date, '%Y-%m-%d')
        
        # Calculate schedule
        schedule, num_purchases, amount_per_purchase = calculate_dca_schedule(
            args.total, args.frequency, args.duration, start_date
        )
        
        if args.json:
            output = {
                'total_amount': args.total,
                'frequency': args.frequency,
                'duration_days': args.duration,
                'num_purchases': num_purchases,
                'amount_per_purchase': amount_per_purchase,
                'schedule': schedule
            }
            print(json.dumps(output, indent=2))
        else:
            format_schedule_output(schedule, num_purchases, amount_per_purchase, args.total)
            
            # Show scenarios if current price provided
            if args.current_price and args.scenarios:
                scenarios = {
                    'Flat market': args.current_price,
                    'Bull market (+30%)': args.current_price * 0.85,  # Lower avg price in bull
                    'Bear market (-30%)': args.current_price * 1.15,  # Higher avg price in bear
                    'Volatile (±20%)': args.current_price,
                }
                simple_projection(amount_per_purchase, num_purchases, args.current_price, scenarios)
            
            # Summary
            print(f"{'='*70}")
            print(f"Summary")
            print(f"{'='*70}")
            print(f"This DCA strategy spreads ${args.total:,.2f} over {num_purchases} purchases")
            print(f"Each {args.frequency} purchase: ${amount_per_purchase:,.2f}")
            print(f"Duration: {args.duration} days (~{args.duration/30:.1f} months)")
            
            if args.current_price:
                # Show what immediate purchase would get
                immediate_units = args.total / args.current_price
                print(f"\nImmediate purchase at ${args.current_price:,.2f}: {immediate_units:.6f} units")
                print(f"DCA benefit: Reduces timing risk and emotional decision-making")
            
            print(f"\n{'='*70}\n")
            
    except ValueError as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)
    except KeyboardInterrupt:
        print("\nInterrupted", file=sys.stderr)
        sys.exit(1)

if __name__ == '__main__':
    main()

```

### scripts/position_sizer.py

```python
#!/usr/bin/env python3
"""
Position Sizer
Calculate position size based on account balance, risk percentage, entry price, and stop loss
"""

import json
import argparse
import sys

def calculate_position_size(account_balance, risk_percent, entry_price, stop_loss_price):
    """Calculate position size using risk management rules
    
    Args:
        account_balance: Total account balance
        risk_percent: Percentage of account to risk (e.g., 1 = 1%)
        entry_price: Planned entry price
        stop_loss_price: Stop loss price
    
    Returns:
        Dictionary with position sizing details
    """
    if entry_price <= 0 or stop_loss_price <= 0:
        raise ValueError("Entry and stop loss prices must be positive")
    
    if account_balance <= 0:
        raise ValueError("Account balance must be positive")
    
    if risk_percent <= 0 or risk_percent > 100:
        raise ValueError("Risk percent must be between 0 and 100")
    
    # Calculate risk amount in dollars
    risk_amount = account_balance * (risk_percent / 100)
    
    # Calculate price difference (risk per unit)
    price_difference = abs(entry_price - stop_loss_price)
    
    if price_difference == 0:
        raise ValueError("Entry price and stop loss cannot be the same")
    
    # Calculate position size in units
    position_size_units = risk_amount / price_difference
    
    # Calculate position value in dollars
    position_value = position_size_units * entry_price
    
    # Calculate position as percentage of account
    position_percent = (position_value / account_balance) * 100
    
    # Calculate stop loss percentage
    stop_loss_percent = (price_difference / entry_price) * 100
    
    return {
        'account_balance': account_balance,
        'risk_percent': risk_percent,
        'risk_amount': risk_amount,
        'entry_price': entry_price,
        'stop_loss_price': stop_loss_price,
        'stop_loss_percent': stop_loss_percent,
        'position_size_units': position_size_units,
        'position_value': position_value,
        'position_percent': position_percent
    }

def calculate_take_profit_levels(entry_price, stop_loss_price, risk_reward_ratios=[1, 2, 3]):
    """Calculate take profit levels based on risk-reward ratios
    
    Args:
        entry_price: Entry price
        stop_loss_price: Stop loss price
        risk_reward_ratios: List of R:R ratios to calculate
    """
    risk = abs(entry_price - stop_loss_price)
    is_long = entry_price > stop_loss_price
    
    take_profit_levels = []
    
    for ratio in risk_reward_ratios:
        if is_long:
            tp_price = entry_price + (risk * ratio)
        else:
            tp_price = entry_price - (risk * ratio)
        
        profit_percent = ((tp_price - entry_price) / entry_price) * 100
        
        take_profit_levels.append({
            'ratio': ratio,
            'price': tp_price,
            'profit_percent': profit_percent
        })
    
    return take_profit_levels, is_long

def calculate_ladder_strategy(position_size, num_levels=3):
    """Calculate a ladder/scaling strategy for entries or exits
    
    Args:
        position_size: Total position size
        num_levels: Number of levels to split into
    """
    size_per_level = position_size / num_levels
    
    levels = []
    for i in range(num_levels):
        levels.append({
            'level': i + 1,
            'size': size_per_level,
            'cumulative': size_per_level * (i + 1),
            'percent': (size_per_level / position_size) * 100
        })
    
    return levels

def format_position_output(result, take_profit_levels, is_long):
    """Format position sizing output"""
    print(f"\n{'='*70}")
    print(f"Position Sizing Analysis")
    print(f"{'='*70}")
    
    print(f"\nAccount & Risk:")
    print(f"  Account Balance: ${result['account_balance']:,.2f}")
    print(f"  Risk Percentage: {result['risk_percent']:.2f}%")
    print(f"  Risk Amount: ${result['risk_amount']:,.2f}")
    
    print(f"\nPosition Details:")
    direction = "LONG" if is_long else "SHORT"
    print(f"  Direction: {direction}")
    print(f"  Entry Price: ${result['entry_price']:,.2f}")
    print(f"  Stop Loss: ${result['stop_loss_price']:,.2f} ({result['stop_loss_percent']:.2f}%)")
    
    print(f"\nPosition Size:")
    print(f"  Units to Buy: {result['position_size_units']:.6f}")
    print(f"  Position Value: ${result['position_value']:,.2f}")
    print(f"  Position % of Account: {result['position_percent']:.2f}%")
    
    print(f"\nTake Profit Levels:")
    print(f"  {'R:R':<6} {'Price':<15} {'Profit %':<12} {'Profit $':<15}")
    print(f"  {'-'*50}")
    
    for tp in take_profit_levels:
        profit_amount = (tp['price'] - result['entry_price']) * result['position_size_units']
        print(f"  {tp['ratio']:>3}:1  ${tp['price']:<14,.2f} {tp['profit_percent']:>10.2f}%  ${profit_amount:>13,.2f}")
    
    print(f"\n{'='*70}")
    print(f"Risk Management Summary")
    print(f"{'='*70}")
    print(f"Maximum Loss if Stop Hit: ${result['risk_amount']:,.2f} ({result['risk_percent']:.2f}%)")
    print(f"Recommended: Risk 1-2% per trade for conservative approach")
    
    if result['position_percent'] > 50:
        print(f"\n⚠ WARNING: Position is {result['position_percent']:.1f}% of account - consider reducing")
    elif result['position_percent'] > 25:
        print(f"\n⚠ CAUTION: Position is {result['position_percent']:.1f}% of account - monitor closely")
    else:
        print(f"\nāœ“ Position size is {result['position_percent']:.1f}% of account - reasonable allocation")
    
    print(f"\n{'='*70}\n")

def format_ladder_output(levels, price, label="Entry Ladder"):
    """Format ladder strategy output"""
    print(f"\n{label}:")
    print(f"  {'Level':<8} {'Size (Units)':<15} {'Cumulative':<15} {'Percent':<10}")
    print(f"  {'-'*50}")
    
    for level in levels:
        print(f"  {level['level']:<8} {level['size']:<15.6f} {level['cumulative']:<15.6f} {level['percent']:<10.1f}%")

def main():
    parser = argparse.ArgumentParser(description='Position Size Calculator')
    parser.add_argument('--balance', '-b', type=float, required=True, help='Account balance')
    parser.add_argument('--risk', '-r', type=float, default=1.0, help='Risk percentage (default: 1.0)')
    parser.add_argument('--entry', '-e', type=float, required=True, help='Entry price')
    parser.add_argument('--stop-loss', '-s', type=float, required=True, help='Stop loss price')
    parser.add_argument('--take-profit', '-t', nargs='+', type=float, default=[1, 2, 3],
                       help='Risk:reward ratios for take profit (default: 1 2 3)')
    parser.add_argument('--ladder', '-l', type=int, help='Number of levels for ladder strategy')
    parser.add_argument('--json', '-j', action='store_true', help='Output as JSON')
    
    args = parser.parse_args()
    
    try:
        # Calculate position size
        result = calculate_position_size(
            args.balance,
            args.risk,
            args.entry,
            args.stop_loss
        )
        
        # Calculate take profit levels
        take_profit_levels, is_long = calculate_take_profit_levels(
            args.entry,
            args.stop_loss,
            args.take_profit
        )
        
        if args.json:
            output = {
                'position': result,
                'take_profit_levels': take_profit_levels,
                'direction': 'LONG' if is_long else 'SHORT'
            }
            
            if args.ladder:
                output['ladder'] = calculate_ladder_strategy(result['position_size_units'], args.ladder)
            
            print(json.dumps(output, indent=2))
        else:
            format_position_output(result, take_profit_levels, is_long)
            
            if args.ladder:
                levels = calculate_ladder_strategy(result['position_size_units'], args.ladder)
                format_ladder_output(levels, args.entry)
                print(f"\nNote: Scale into position across {args.ladder} levels to reduce timing risk\n")
            
    except ValueError as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)
    except KeyboardInterrupt:
        print("\nInterrupted", file=sys.stderr)
        sys.exit(1)

if __name__ == '__main__':
    main()

```

### scripts/market_scanner.py

```python
#!/usr/bin/env python3
"""
Market Scanner
Scan Binance for top gainers/losers, volume spikes, and unusual activity
"""

import json
import argparse
import sys
from urllib import request, error
from datetime import datetime

BASE_URL = "https://data-api.binance.vision"

def fetch_json(url):
    """Fetch JSON data from URL with error handling"""
    try:
        with request.urlopen(url, timeout=10) as response:
            return json.loads(response.read().decode())
    except error.HTTPError as e:
        print(f"HTTP Error {e.code}: {e.reason}", file=sys.stderr)
        sys.exit(1)
    except error.URLError as e:
        print(f"Connection Error: {e.reason}", file=sys.stderr)
        sys.exit(1)
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)

def get_all_tickers():
    """Get 24h ticker data for all symbols"""
    url = f"{BASE_URL}/api/v3/ticker/24hr"
    return fetch_json(url)

def get_exchange_info():
    """Get exchange information including trading pairs"""
    url = f"{BASE_URL}/api/v3/exchangeInfo"
    return fetch_json(url)

def filter_usdt_pairs(tickers):
    """Filter for USDT trading pairs only"""
    return [t for t in tickers if t['symbol'].endswith('USDT') and t['symbol'] != 'USDT']

def filter_active_pairs(tickers, min_volume=100000):
    """Filter for pairs with significant volume"""
    return [t for t in tickers if float(t['quoteVolume']) >= min_volume]

def find_top_gainers(tickers, limit=10):
    """Find top gaining pairs by 24h percentage change"""
    sorted_tickers = sorted(tickers, key=lambda x: float(x['priceChangePercent']), reverse=True)
    return sorted_tickers[:limit]

def find_top_losers(tickers, limit=10):
    """Find top losing pairs by 24h percentage change"""
    sorted_tickers = sorted(tickers, key=lambda x: float(x['priceChangePercent']))
    return sorted_tickers[:limit]

def find_volume_spikes(tickers, limit=10):
    """Find pairs with highest 24h volume"""
    sorted_tickers = sorted(tickers, key=lambda x: float(x['quoteVolume']), reverse=True)
    return sorted_tickers[:limit]

def find_volatile_pairs(tickers, limit=10):
    """Find most volatile pairs (highest high-low spread)"""
    volatility_tickers = []
    
    for t in tickers:
        high = float(t['highPrice'])
        low = float(t['lowPrice'])
        if low > 0:
            volatility = ((high - low) / low) * 100
            t['volatility'] = volatility
            volatility_tickers.append(t)
    
    sorted_tickers = sorted(volatility_tickers, key=lambda x: x['volatility'], reverse=True)
    return sorted_tickers[:limit]

def find_breakout_candidates(tickers, limit=10):
    """Find potential breakout candidates (near 24h high with high volume)"""
    breakout_candidates = []
    
    for t in tickers:
        current = float(t['lastPrice'])
        high = float(t['highPrice'])
        volume = float(t['quoteVolume'])
        
        if high > 0:
            distance_from_high = ((high - current) / high) * 100
            
            # Near 24h high (within 2%) with significant volume
            if distance_from_high < 2 and volume > 500000:
                t['distance_from_high'] = distance_from_high
                breakout_candidates.append(t)
    
    sorted_candidates = sorted(breakout_candidates, key=lambda x: x['distance_from_high'])
    return sorted_candidates[:limit]

def format_ticker_table(tickers, title, show_volume=True):
    """Format ticker data as a table"""
    print(f"\n{'='*90}")
    print(f"{title}")
    print(f"{'='*90}")
    
    if show_volume:
        print(f"{'#':<4} {'Symbol':<12} {'Price':<15} {'24h Change':<15} {'Volume (USDT)':<20}")
    else:
        print(f"{'#':<4} {'Symbol':<12} {'Price':<15} {'24h Change':<15} {'High':<15} {'Low':<15}")
    
    print("-" * 90)
    
    for i, t in enumerate(tickers, 1):
        symbol = t['symbol']
        price = float(t['lastPrice'])
        change_pct = float(t['priceChangePercent'])
        
        # Color coding for terminal (green/red)
        change_str = f"{change_pct:+.2f}%"
        
        if show_volume:
            volume = float(t['quoteVolume'])
            print(f"{i:<4} {symbol:<12} ${price:<14,.4f} {change_str:<15} ${volume:<19,.0f}")
        else:
            high = float(t['highPrice'])
            low = float(t['lowPrice'])
            print(f"{i:<4} {symbol:<12} ${price:<14,.4f} {change_str:<15} ${high:<14,.4f} ${low:<14,.4f}")
    
    print()

def format_volatile_table(tickers, title):
    """Format volatile pairs table"""
    print(f"\n{'='*90}")
    print(f"{title}")
    print(f"{'='*90}")
    print(f"{'#':<4} {'Symbol':<12} {'Price':<15} {'24h Change':<15} {'Volatility':<15}")
    print("-" * 90)
    
    for i, t in enumerate(tickers, 1):
        symbol = t['symbol']
        price = float(t['lastPrice'])
        change_pct = float(t['priceChangePercent'])
        volatility = t.get('volatility', 0)
        
        print(f"{i:<4} {symbol:<12} ${price:<14,.4f} {change_pct:>+13.2f}%  {volatility:>13.2f}%")
    
    print()

def format_breakout_table(tickers, title):
    """Format breakout candidates table"""
    print(f"\n{'='*90}")
    print(f"{title}")
    print(f"{'='*90}")
    print(f"{'#':<4} {'Symbol':<12} {'Price':<15} {'24h High':<15} {'Distance':<15} {'Volume':<20}")
    print("-" * 90)
    
    for i, t in enumerate(tickers, 1):
        symbol = t['symbol']
        price = float(t['lastPrice'])
        high = float(t['highPrice'])
        distance = t.get('distance_from_high', 0)
        volume = float(t['quoteVolume'])
        
        print(f"{i:<4} {symbol:<12} ${price:<14,.4f} ${high:<14,.4f} {distance:>13.2f}%  ${volume:<19,.0f}")
    
    print()

def scan_market(min_volume=100000, limit=10):
    """Perform comprehensive market scan"""
    print(f"Scanning Binance market... (minimum volume: ${min_volume:,.0f})")
    
    # Fetch all tickers
    all_tickers = get_all_tickers()
    
    # Filter for USDT pairs with significant volume
    usdt_tickers = filter_usdt_pairs(all_tickers)
    active_tickers = filter_active_pairs(usdt_tickers, min_volume)
    
    print(f"Found {len(active_tickers)} active USDT pairs\n")
    
    # Perform different scans
    top_gainers = find_top_gainers(active_tickers, limit)
    top_losers = find_top_losers(active_tickers, limit)
    top_volume = find_volume_spikes(active_tickers, limit)
    volatile_pairs = find_volatile_pairs(active_tickers, limit)
    breakout_candidates = find_breakout_candidates(active_tickers, limit)
    
    return {
        'top_gainers': top_gainers,
        'top_losers': top_losers,
        'top_volume': top_volume,
        'volatile_pairs': volatile_pairs,
        'breakout_candidates': breakout_candidates,
        'total_pairs': len(active_tickers),
        'timestamp': datetime.now().isoformat()
    }

def main():
    parser = argparse.ArgumentParser(description='Binance Market Scanner')
    parser.add_argument('--min-volume', '-v', type=float, default=100000,
                       help='Minimum 24h volume in USDT (default: 100000)')
    parser.add_argument('--limit', '-l', type=int, default=10,
                       help='Number of results per category (default: 10)')
    parser.add_argument('--gainers', '-g', action='store_true', help='Show only top gainers')
    parser.add_argument('--losers', '-L', action='store_true', help='Show only top losers')
    parser.add_argument('--volume', '-V', action='store_true', help='Show only top volume')
    parser.add_argument('--volatile', '-o', action='store_true', help='Show only volatile pairs')
    parser.add_argument('--breakout', '-b', action='store_true', help='Show only breakout candidates')
    parser.add_argument('--json', '-j', action='store_true', help='Output as JSON')
    
    args = parser.parse_args()
    
    try:
        results = scan_market(args.min_volume, args.limit)
        
        if args.json:
            print(json.dumps(results, indent=2))
        else:
            # Show all categories if no specific flag
            show_all = not any([args.gainers, args.losers, args.volume, args.volatile, args.breakout])
            
            if show_all or args.gainers:
                format_ticker_table(results['top_gainers'], f"šŸš€ Top {args.limit} Gainers (24h)")
            
            if show_all or args.losers:
                format_ticker_table(results['top_losers'], f"šŸ“‰ Top {args.limit} Losers (24h)")
            
            if show_all or args.volume:
                format_ticker_table(results['top_volume'], f"šŸ’° Highest Volume (24h)")
            
            if show_all or args.volatile:
                format_volatile_table(results['volatile_pairs'], f"šŸ“Š Most Volatile Pairs (24h)")
            
            if show_all or args.breakout:
                format_breakout_table(results['breakout_candidates'], f"šŸŽÆ Potential Breakouts (Near 24h High)")
            
            print(f"{'='*90}")
            print(f"Market Scan Summary")
            print(f"{'='*90}")
            print(f"Total Active Pairs: {results['total_pairs']}")
            print(f"Timestamp: {results['timestamp']}")
            print(f"{'='*90}\n")
            
    except KeyboardInterrupt:
        print("\nInterrupted", file=sys.stderr)
        sys.exit(1)

if __name__ == '__main__':
    main()

```

### scripts/whale_tracker.py

```python
#!/usr/bin/env python3
"""
Whale Tracker
Monitor large trades and orderbook imbalances on Binance
"""

import json
import argparse
import sys
from urllib import request, error
from datetime import datetime
from statistics import mean

BASE_URL = "https://data-api.binance.vision"

def fetch_json(url):
    """Fetch JSON data from URL with error handling"""
    try:
        with request.urlopen(url, timeout=10) as response:
            return json.loads(response.read().decode())
    except error.HTTPError as e:
        print(f"HTTP Error {e.code}: {e.reason}", file=sys.stderr)
        sys.exit(1)
    except error.URLError as e:
        print(f"Connection Error: {e.reason}", file=sys.stderr)
        sys.exit(1)
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)

def get_recent_trades(symbol, limit=1000):
    """Get recent trades"""
    url = f"{BASE_URL}/api/v3/trades?symbol={symbol}&limit={limit}"
    return fetch_json(url)

def get_orderbook(symbol, limit=1000):
    """Get orderbook depth"""
    url = f"{BASE_URL}/api/v3/depth?symbol={symbol}&limit={limit}"
    return fetch_json(url)

def get_ticker(symbol):
    """Get 24h ticker for reference"""
    url = f"{BASE_URL}/api/v3/ticker/24hr?symbol={symbol}"
    return fetch_json(url)

def analyze_large_trades(trades, threshold_percentile=90):
    """Identify large trades (whale activity)
    
    Args:
        trades: List of recent trades
        threshold_percentile: Percentile for defining "large" trades
    """
    if not trades:
        return []
    
    # Calculate trade sizes
    trade_sizes = [float(t['qty']) * float(t['price']) for t in trades]
    
    # Find threshold (top percentile)
    sorted_sizes = sorted(trade_sizes)
    threshold_idx = int(len(sorted_sizes) * (threshold_percentile / 100))
    threshold = sorted_sizes[threshold_idx] if threshold_idx < len(sorted_sizes) else sorted_sizes[-1]
    
    # Filter large trades
    large_trades = []
    for i, trade in enumerate(trades):
        size = trade_sizes[i]
        if size >= threshold:
            large_trades.append({
                'time': trade['time'],
                'price': float(trade['price']),
                'qty': float(trade['qty']),
                'value': size,
                'is_buyer_maker': trade['isBuyerMaker'],
                'side': 'SELL' if trade['isBuyerMaker'] else 'BUY'
            })
    
    return large_trades, threshold

def analyze_orderbook_imbalance(orderbook, depth=20):
    """Analyze orderbook for bid/ask imbalances and walls
    
    Args:
        orderbook: Orderbook data
        depth: Number of levels to analyze
    """
    bids = orderbook['bids'][:depth]
    asks = orderbook['asks'][:depth]
    
    # Calculate total bid/ask volume
    total_bid_volume = sum(float(b[1]) for b in bids)
    total_ask_volume = sum(float(a[1]) for a in asks)
    
    # Calculate bid/ask value
    total_bid_value = sum(float(b[0]) * float(b[1]) for b in bids)
    total_ask_value = sum(float(a[0]) * float(a[1]) for a in asks)
    
    # Calculate imbalance ratio
    if total_ask_volume > 0:
        volume_ratio = total_bid_volume / total_ask_volume
    else:
        volume_ratio = float('inf')
    
    if total_ask_value > 0:
        value_ratio = total_bid_value / total_ask_value
    else:
        value_ratio = float('inf')
    
    # Find walls (unusually large orders)
    bid_sizes = [float(b[1]) for b in bids]
    ask_sizes = [float(a[1]) for a in asks]
    
    avg_bid_size = mean(bid_sizes) if bid_sizes else 0
    avg_ask_size = mean(ask_sizes) if ask_sizes else 0
    
    # Wall threshold: 3x average
    bid_wall_threshold = avg_bid_size * 3
    ask_wall_threshold = avg_ask_size * 3
    
    bid_walls = [
        {'price': float(b[0]), 'size': float(b[1])}
        for b in bids if float(b[1]) >= bid_wall_threshold
    ]
    
    ask_walls = [
        {'price': float(a[0]), 'size': float(a[1])}
        for a in asks if float(a[1]) >= ask_wall_threshold
    ]
    
    return {
        'total_bid_volume': total_bid_volume,
        'total_ask_volume': total_ask_volume,
        'total_bid_value': total_bid_value,
        'total_ask_value': total_ask_value,
        'volume_ratio': volume_ratio,
        'value_ratio': value_ratio,
        'bid_walls': bid_walls,
        'ask_walls': ask_walls,
        'imbalance': 'BULLISH' if volume_ratio > 1.5 else 'BEARISH' if volume_ratio < 0.67 else 'NEUTRAL'
    }

def format_large_trades_output(large_trades, threshold):
    """Format large trades output"""
    print(f"\n{'='*90}")
    print(f"šŸ‹ Large Trades (Whale Activity)")
    print(f"{'='*90}")
    print(f"Threshold: ${threshold:,.2f} (top 10% of recent trades)")
    print(f"Total Large Trades: {len(large_trades)}")
    
    if not large_trades:
        print("No large trades detected in recent activity")
        return
    
    # Aggregate by side
    buy_count = sum(1 for t in large_trades if t['side'] == 'BUY')
    sell_count = sum(1 for t in large_trades if t['side'] == 'SELL')
    buy_volume = sum(t['value'] for t in large_trades if t['side'] == 'BUY')
    sell_volume = sum(t['value'] for t in large_trades if t['side'] == 'SELL')
    
    print(f"\nSummary:")
    print(f"  Buy Orders: {buy_count} (${buy_volume:,.2f})")
    print(f"  Sell Orders: {sell_count} (${sell_volume:,.2f})")
    
    if buy_volume > sell_volume * 1.2:
        print(f"  ⚠ Whale buying pressure detected!")
    elif sell_volume > buy_volume * 1.2:
        print(f"  ⚠ Whale selling pressure detected!")
    
    print(f"\nRecent Large Trades (last 20):")
    print(f"{'Time':<20} {'Side':<6} {'Price':<15} {'Quantity':<15} {'Value':<15}")
    print("-" * 90)
    
    # Show most recent large trades
    sorted_trades = sorted(large_trades, key=lambda x: x['time'], reverse=True)
    for trade in sorted_trades[:20]:
        time_str = datetime.fromtimestamp(trade['time']/1000).strftime('%Y-%m-%d %H:%M:%S')
        side_str = trade['side']
        print(f"{time_str:<20} {side_str:<6} ${trade['price']:<14,.2f} {trade['qty']:<14,.4f} ${trade['value']:<14,.2f}")
    
    print()

def format_orderbook_output(analysis, current_price):
    """Format orderbook analysis output"""
    print(f"\n{'='*90}")
    print(f"šŸ“Š Orderbook Analysis")
    print(f"{'='*90}")
    print(f"Current Price: ${current_price:,.2f}")
    
    print(f"\nOrderbook Imbalance (top 20 levels):")
    print(f"  Total Bid Volume: {analysis['total_bid_volume']:,.4f}")
    print(f"  Total Ask Volume: {analysis['total_ask_volume']:,.4f}")
    print(f"  Volume Ratio (Bid/Ask): {analysis['volume_ratio']:.2f}")
    print(f"  Value Ratio (Bid/Ask): {analysis['value_ratio']:.2f}")
    print(f"  Market Sentiment: {analysis['imbalance']}")
    
    if analysis['imbalance'] == 'BULLISH':
        print(f"  āœ“ More buy pressure - potential upward movement")
    elif analysis['imbalance'] == 'BEARISH':
        print(f"  āœ— More sell pressure - potential downward movement")
    
    print(f"\n🧱 Orderbook Walls:")
    
    if analysis['bid_walls']:
        print(f"\n  Support Walls (Large Bids):")
        print(f"  {'Price':<15} {'Size':<15} {'Distance from Current':<20}")
        print(f"  {'-'*50}")
        for wall in analysis['bid_walls'][:5]:
            distance = ((current_price - wall['price']) / current_price) * 100
            print(f"  ${wall['price']:<14,.2f} {wall['size']:<14,.4f} {distance:>18.2f}%")
    else:
        print(f"  No significant bid walls detected")
    
    if analysis['ask_walls']:
        print(f"\n  Resistance Walls (Large Asks):")
        print(f"  {'Price':<15} {'Size':<15} {'Distance from Current':<20}")
        print(f"  {'-'*50}")
        for wall in analysis['ask_walls'][:5]:
            distance = ((wall['price'] - current_price) / current_price) * 100
            print(f"  ${wall['price']:<14,.2f} {wall['size']:<14,.4f} {distance:>18.2f}%")
    else:
        print(f"  No significant ask walls detected")
    
    print()

def main():
    parser = argparse.ArgumentParser(description='Whale Tracker - Monitor large trades and orderbook imbalances')
    parser.add_argument('--symbol', '-s', default='BTCUSDT', help='Trading pair symbol (default: BTCUSDT)')
    parser.add_argument('--trades', '-t', action='store_true', help='Analyze large trades')
    parser.add_argument('--orderbook', '-o', action='store_true', help='Analyze orderbook imbalances')
    parser.add_argument('--depth', '-d', type=int, default=20, help='Orderbook depth to analyze (default: 20)')
    parser.add_argument('--threshold', type=int, default=90, help='Percentile threshold for large trades (default: 90)')
    parser.add_argument('--json', '-j', action='store_true', help='Output as JSON')
    
    args = parser.parse_args()
    
    symbol = args.symbol.upper()
    
    # If no specific analysis requested, do both
    if not args.trades and not args.orderbook:
        args.trades = True
        args.orderbook = True
    
    try:
        result = {'symbol': symbol, 'timestamp': datetime.now().isoformat()}
        
        # Get current price for reference
        ticker = get_ticker(symbol)
        current_price = float(ticker['lastPrice'])
        
        if args.trades:
            trades = get_recent_trades(symbol, limit=1000)
            large_trades, threshold = analyze_large_trades(trades, args.threshold)
            
            result['large_trades'] = {
                'trades': large_trades,
                'threshold': threshold,
                'count': len(large_trades)
            }
            
            if not args.json:
                format_large_trades_output(large_trades, threshold)
        
        if args.orderbook:
            orderbook = get_orderbook(symbol, limit=args.depth)
            analysis = analyze_orderbook_imbalance(orderbook, args.depth)
            
            result['orderbook'] = analysis
            
            if not args.json:
                format_orderbook_output(analysis, current_price)
        
        if args.json:
            print(json.dumps(result, indent=2))
        else:
            print(f"{'='*90}")
            print(f"Whale Tracking Summary for {symbol}")
            print(f"{'='*90}")
            print(f"Timestamp: {result['timestamp']}")
            print(f"Current Price: ${current_price:,.2f}")
            
            if args.trades:
                buy_trades = [t for t in result['large_trades']['trades'] if t['side'] == 'BUY']
                sell_trades = [t for t in result['large_trades']['trades'] if t['side'] == 'SELL']
                print(f"Large Trades: {len(buy_trades)} buys, {len(sell_trades)} sells")
            
            if args.orderbook:
                print(f"Orderbook Sentiment: {result['orderbook']['imbalance']}")
                print(f"Bid/Ask Ratio: {result['orderbook']['volume_ratio']:.2f}")
            
            print(f"{'='*90}\n")
            
    except KeyboardInterrupt:
        print("\nInterrupted", file=sys.stderr)
        sys.exit(1)

if __name__ == '__main__':
    main()

```

### references/binance-api.md

```markdown
# Binance API Quick Reference

## Base URLs

- **Spot REST API**: `https://api.binance.com`
- **Futures REST API**: `https://fapi.binance.com`
- **WebSocket Streams**: `wss://stream.binance.com:9443`

## Rate Limits

- **Request Weight**: 1200 per minute per IP
- **Orders**: 10 orders per second per account
- **RAW_REQUESTS**: 5000 per 5 minutes per IP

Each endpoint has a weight. Stay under limits to avoid bans.

## Public Endpoints (No Authentication)

### Market Data

#### Get Current Price
```
GET /api/v3/ticker/price?symbol=BTCUSDT
```
Weight: 1 (single symbol), 2 (all symbols)

#### Get 24h Ticker Statistics
```
GET /api/v3/ticker/24hr?symbol=BTCUSDT
```
Weight: 1 (single symbol), 40 (all symbols)

Returns: price change, high, low, volume, number of trades

#### Get Orderbook Depth
```
GET /api/v3/depth?symbol=BTCUSDT&limit=100
```
Weight: Adjusted based on limit (5-50)
Limits: 5, 10, 20, 50, 100, 500, 1000, 5000

#### Get Recent Trades
```
GET /api/v3/trades?symbol=BTCUSDT&limit=500
```
Weight: 1
Max limit: 1000

#### Get Kline/Candlestick Data
```
GET /api/v3/klines?symbol=BTCUSDT&interval=1h&limit=100
```
Weight: 1

**Intervals**: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M

**Response Format**:
```json
[
  [
    1499040000000,      // Open time
    "0.01634000",       // Open
    "0.80000000",       // High
    "0.01575800",       // Low
    "0.01577100",       // Close
    "148976.11427815",  // Volume
    1499644799999,      // Close time
    "2434.19055334",    // Quote asset volume
    308,                // Number of trades
    "1756.87402397",    // Taker buy base asset volume
    "28.46694368",      // Taker buy quote asset volume
    "17928899.62484339" // Ignore
  ]
]
```

#### Get Exchange Info
```
GET /api/v3/exchangeInfo
```
Weight: 10

Returns all trading pairs, trading rules, filters, etc.

#### Get Average Price
```
GET /api/v3/avgPrice?symbol=BTCUSDT
```
Weight: 1

### Futures-Specific Endpoints

#### Get Funding Rate
```
GET /fapi/v1/premiumIndex?symbol=BTCUSDT
```
Weight: 1

#### Get Open Interest
```
GET /fapi/v1/openInterest?symbol=BTCUSDT
```
Weight: 1

## Signed Endpoints (Authentication Required)

### Authentication

Signed endpoints require:
1. **API Key** in header: `X-MBX-APIKEY`
2. **Signature** in query string: `signature=<HMAC SHA256>`
3. **Timestamp** in query string: `timestamp=<milliseconds>`

### Creating a Signature

```python
import hmac
import hashlib
import time

secret_key = "YOUR_SECRET_KEY"
query_string = "symbol=BTCUSDT&side=BUY&type=LIMIT&quantity=1&price=50000&timestamp=1234567890"

signature = hmac.new(
    secret_key.encode(),
    query_string.encode(),
    hashlib.sha256
).hexdigest()
```

### Account Endpoints

#### Get Account Information
```
GET /api/v3/account?timestamp=<timestamp>&signature=<signature>
```
Weight: 10

Returns balances, permissions, trading status

#### Get Order
```
GET /api/v3/order?symbol=BTCUSDT&orderId=123&timestamp=<timestamp>&signature=<signature>
```
Weight: 2

#### Query All Orders
```
GET /api/v3/allOrders?symbol=BTCUSDT&timestamp=<timestamp>&signature=<signature>
```
Weight: 10

### Trading Endpoints

#### Place New Order
```
POST /api/v3/order
```
Weight: 1

**Required Parameters**:
- `symbol` (e.g., BTCUSDT)
- `side` (BUY or SELL)
- `type` (LIMIT, MARKET, STOP_LOSS_LIMIT, etc.)
- `quantity`
- `timestamp`
- `signature`

**Additional for LIMIT orders**:
- `timeInForce` (GTC, IOC, FOK)
- `price`

**Example**:
```
symbol=BTCUSDT&side=BUY&type=LIMIT&timeInForce=GTC&quantity=0.01&price=50000&timestamp=1234567890&signature=xxx
```

#### Cancel Order
```
DELETE /api/v3/order
```
Weight: 1

**Required Parameters**:
- `symbol`
- `orderId` or `origClientOrderId`
- `timestamp`
- `signature`

#### Cancel All Open Orders
```
DELETE /api/v3/openOrders?symbol=BTCUSDT&timestamp=<timestamp>&signature=<signature>
```
Weight: 1

## Order Types

- **LIMIT**: Buy/sell at specific price or better
- **MARKET**: Execute immediately at current market price
- **STOP_LOSS**: Market order triggered when stop price reached
- **STOP_LOSS_LIMIT**: Limit order triggered when stop price reached
- **TAKE_PROFIT**: Market order triggered when take profit reached
- **TAKE_PROFIT_LIMIT**: Limit order triggered when take profit reached
- **LIMIT_MAKER**: Limit order that will be rejected if would execute immediately (post-only)

## Time in Force

- **GTC** (Good Till Canceled): Order stays active until filled or canceled
- **IOC** (Immediate or Cancel): Fill what you can immediately, cancel rest
- **FOK** (Fill or Kill): Either fill entire order immediately or cancel

## Error Codes

- **-1000**: Unknown error
- **-1001**: Disconnected
- **-1003**: Too many requests (rate limit exceeded)
- **-1021**: Timestamp outside recv window
- **-1100**: Illegal characters in parameter
- **-2010**: Insufficient balance
- **-2011**: Order would trigger immediately (LIMIT_MAKER)

## Best Practices

1. **Use testnet first**: `https://testnet.binance.vision` for spot
2. **Implement rate limiting**: Track your request weight
3. **Handle errors gracefully**: Retry with exponential backoff
4. **Sync time**: Ensure system clock is accurate (within 1 second)
5. **Use WebSockets for real-time data**: More efficient than polling REST
6. **Keep API keys secure**: Never commit to git, use environment variables
7. **Use IP whitelisting**: Restrict API key to specific IPs
8. **Set trading restrictions**: Limit withdrawal permissions if not needed

## WebSocket Streams

### Individual Symbol Ticker
```
wss://stream.binance.com:9443/ws/btcusdt@ticker
```

### All Market Tickers
```
wss://stream.binance.com:9443/ws/!ticker@arr
```

### Kline/Candlestick Streams
```
wss://stream.binance.com:9443/ws/btcusdt@kline_1h
```

### Orderbook Depth
```
wss://stream.binance.com:9443/ws/btcusdt@depth
```

### Aggregate Trade Streams
```
wss://stream.binance.com:9443/ws/btcusdt@aggTrade
```

## Python Example (Using requests)

```python
import requests
import hmac
import hashlib
import time

API_KEY = "your_api_key"
SECRET_KEY = "your_secret_key"
BASE_URL = "https://api.binance.com"

# Public endpoint (no auth)
def get_price(symbol):
    url = f"{BASE_URL}/api/v3/ticker/price"
    params = {"symbol": symbol}
    response = requests.get(url, params=params)
    return response.json()

# Signed endpoint (with auth)
def get_account():
    endpoint = "/api/v3/account"
    timestamp = int(time.time() * 1000)
    
    query_string = f"timestamp={timestamp}"
    signature = hmac.new(
        SECRET_KEY.encode(),
        query_string.encode(),
        hashlib.sha256
    ).hexdigest()
    
    headers = {"X-MBX-APIKEY": API_KEY}
    url = f"{BASE_URL}{endpoint}?{query_string}&signature={signature}"
    
    response = requests.get(url, headers=headers)
    return response.json()

# Place order
def place_order(symbol, side, order_type, quantity, price=None):
    endpoint = "/api/v3/order"
    timestamp = int(time.time() * 1000)
    
    params = {
        "symbol": symbol,
        "side": side,
        "type": order_type,
        "quantity": quantity,
        "timestamp": timestamp
    }
    
    if order_type == "LIMIT":
        params["timeInForce"] = "GTC"
        params["price"] = price
    
    query_string = "&".join([f"{k}={v}" for k, v in params.items()])
    signature = hmac.new(
        SECRET_KEY.encode(),
        query_string.encode(),
        hashlib.sha256
    ).hexdigest()
    
    headers = {"X-MBX-APIKEY": API_KEY}
    url = f"{BASE_URL}{endpoint}?{query_string}&signature={signature}"
    
    response = requests.post(url, headers=headers)
    return response.json()
```

## Resources

- **Official Docs**: https://binance-docs.github.io/apidocs/spot/en/
- **API Status**: https://www.binance.com/en/support/announcement
- **Testnet**: https://testnet.binance.vision/
- **Python SDK**: `python-binance` (pip install python-binance)

```



---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "fpsjago",
  "slug": "trading-research",
  "displayName": "Trading Research",
  "latest": {
    "version": "1.0.0",
    "publishedAt": 1770296676331,
    "commit": "https://github.com/clawdbot/skills/commit/51ccafb02b592e906e6b10192208f19d5eb1fdfd"
  },
  "history": []
}

```

### references/indicators.md

```markdown
# Technical Indicators Reference

## Moving Averages

### Simple Moving Average (SMA)

**Formula**: Sum of closing prices over N periods / N

**Common Periods**: 20, 50, 100, 200

**Interpretation**:
- Price above SMA = Uptrend
- Price below SMA = Downtrend
- SMA acts as support in uptrends, resistance in downtrends

**Trading Signals**:
- **Golden Cross**: Short-term MA (50) crosses above long-term MA (200) = Bullish
- **Death Cross**: Short-term MA (50) crosses below long-term MA (200) = Bearish

**Best For**: Identifying trend direction, support/resistance levels

### Exponential Moving Average (EMA)

**Formula**: EMA = Price(t) Ɨ k + EMA(y) Ɨ (1-k)
- k = 2 / (N + 1)
- More weight to recent prices

**Common Periods**: 12, 26, 50, 200

**Interpretation**:
- More responsive to recent price changes than SMA
- Reacts faster to trend changes

**Trading Signals**:
- **EMA Crossover**: Fast EMA (12) crosses above slow EMA (26) = Buy signal
- **EMA Support/Resistance**: Price bouncing off EMA levels

**Best For**: Short-term trading, faster trend identification

---

## Momentum Indicators

### Relative Strength Index (RSI)

**Formula**: RSI = 100 - [100 / (1 + RS)]
- RS = Average Gain / Average Loss over N periods

**Common Settings**: 14 periods

**Range**: 0 to 100

**Interpretation**:
- **Overbought**: RSI > 70 (potential reversal down)
- **Oversold**: RSI < 30 (potential reversal up)
- **Neutral**: RSI 30-70

**Trading Signals**:
- **Divergence**: Price makes new high/low but RSI doesn't = Reversal signal
- **Failure Swing**: RSI fails to exceed previous high/low = Trend weakening
- **Centerline Crossover**: RSI > 50 = Bullish, RSI < 50 = Bearish

**Best For**: Identifying overbought/oversold conditions, divergences

**Conservative Usage**:
- Don't trade RSI signals alone
- Use with trend confirmation
- In strong trends, RSI can stay overbought/oversold for extended periods

### MACD (Moving Average Convergence Divergence)

**Formula**:
- MACD Line = EMA(12) - EMA(26)
- Signal Line = EMA(9) of MACD Line
- Histogram = MACD Line - Signal Line

**Interpretation**:
- **Bullish**: MACD Line > Signal Line
- **Bearish**: MACD Line < Signal Line
- **Momentum**: Histogram shows strength

**Trading Signals**:
- **MACD Crossover**: MACD crosses above signal = Buy, below = Sell
- **Centerline Crossover**: MACD crosses above 0 = Bullish, below = Bearish
- **Divergence**: Price vs MACD disagreement = Potential reversal

**Best For**: Trend following, momentum analysis

**Conservative Usage**:
- Wait for crossover confirmation (not just touch)
- Consider histogram direction (increasing momentum)
- Best in trending markets, less effective in ranging markets

---

## Volatility Indicators

### Bollinger Bands

**Formula**:
- Middle Band = SMA(20)
- Upper Band = SMA(20) + (2 Ɨ Standard Deviation)
- Lower Band = SMA(20) - (2 Ɨ Standard Deviation)

**Common Settings**: 20 periods, 2 standard deviations

**Interpretation**:
- **Band Width**: Wide = High volatility, Narrow = Low volatility
- **Price Position**: Near upper = Overbought, Near lower = Oversold
- **Squeeze**: Narrow bands = Volatility expansion coming

**Trading Signals**:
- **Bounce**: Price bounces off bands (mean reversion)
- **Breakout**: Price moves outside bands = Strong momentum
- **Walking the Bands**: Price stays near upper/lower band = Strong trend
- **Squeeze & Break**: Bands narrow, then price breaks out with volume

**Best For**: Volatility analysis, overbought/oversold in ranging markets

**Conservative Usage**:
- Don't sell at upper band in strong uptrends (can "walk the band")
- Wait for confirmation before acting on band touches
- Use with RSI for better signals

### Average True Range (ATR)

**Formula**: Average of True Range over N periods
- True Range = max(High-Low, |High-Close_prev|, |Low-Close_prev|)

**Common Settings**: 14 periods

**Interpretation**:
- **High ATR**: Increased volatility
- **Low ATR**: Decreased volatility
- Not directional (doesn't predict up/down)

**Trading Signals**:
- **Position Sizing**: Use ATR for stop loss placement
- **Breakout Confirmation**: Breakouts with rising ATR = Stronger
- **Volatility Expansion**: Rising ATR = Potential trend start

**Best For**: Risk management, stop loss placement

---

## Volume Indicators

### Volume Analysis

**Types**:
- **Volume Spike**: > 2x average volume = Significant interest
- **Volume Divergence**: Price rising but volume falling = Weak trend
- **Climax Volume**: Extreme volume = Potential reversal

**Interpretation**:
- **High Volume + Price Up**: Strong buying (bullish)
- **High Volume + Price Down**: Strong selling (bearish)
- **Low Volume**: Lack of conviction

**Trading Signals**:
- **Breakout Confirmation**: Breakout with high volume = Legitimate
- **Trend Confirmation**: Uptrend with increasing volume = Healthy
- **Reversal Warning**: Volume spike at extreme = Potential top/bottom

### On-Balance Volume (OBV)

**Formula**:
- If Close > Close_prev: OBV = OBV_prev + Volume
- If Close < Close_prev: OBV = OBV_prev - Volume
- If Close = Close_prev: OBV = OBV_prev

**Interpretation**:
- Rising OBV = Accumulation (buying pressure)
- Falling OBV = Distribution (selling pressure)

**Trading Signals**:
- **Divergence**: Price up but OBV down = Bearish
- **Confirmation**: Price and OBV moving together = Strong trend

---

## Support & Resistance

### Pivot Points

**Formula** (Standard):
- Pivot = (High + Low + Close) / 3
- R1 = 2 Ɨ Pivot - Low
- S1 = 2 Ɨ Pivot - High
- R2 = Pivot + (High - Low)
- S2 = Pivot - (High - Low)

**Interpretation**:
- Price above Pivot = Bullish sentiment
- Price below Pivot = Bearish sentiment

**Trading Signals**:
- Use R1, R2, R3 as resistance targets
- Use S1, S2, S3 as support targets
- Breakout above/below pivot = Trend signal

### Fibonacci Retracement

**Levels**: 23.6%, 38.2%, 50%, 61.8%, 78.6%

**Usage**:
- Draw from swing low to swing high (uptrend)
- Draw from swing high to swing low (downtrend)

**Interpretation**:
- **Common Retracement**: 38.2% - 61.8%
- **Strong Support**: 61.8% level
- **Trend Continuation**: Bounce from retracement level

**Trading Signals**:
- **Buy Opportunity**: Uptrend retraces to 50-61.8% with support
- **Sell Opportunity**: Downtrend retraces to 50-61.8% with resistance

---

## Combining Indicators

### Trend + Momentum
- **EMA(20) + RSI**: Trend direction + Entry timing
- **SMA(50/200) + MACD**: Major trend + Momentum confirmation

### Volatility + Support/Resistance
- **Bollinger Bands + Fibonacci**: Volatility + Key levels
- **ATR + Support/Resistance**: Stop loss placement

### Volume Confirmation
- **Any indicator + Volume**: Confirm signals with volume

---

## Common Settings for Different Timeframes

### Day Trading (Minutes to Hours)
- **EMA**: 9, 20, 50
- **RSI**: 7 or 14
- **MACD**: 12, 26, 9
- **Bollinger Bands**: 20 periods, 2 SD
- **Volume**: Compare to 20-period average

### Swing Trading (Days to Weeks)
- **EMA**: 20, 50, 200
- **RSI**: 14
- **MACD**: 12, 26, 9
- **Bollinger Bands**: 20 periods, 2 SD
- **Volume**: Compare to 50-period average

### Position Trading (Weeks to Months)
- **SMA**: 50, 100, 200
- **RSI**: 14 or 21
- **MACD**: 12, 26, 9
- **Bollinger Bands**: 20 periods, 2 SD
- **Volume**: Compare to 100-period average

---

## Indicator Reliability

**Most Reliable**:
- Moving Averages (trend identification)
- Volume (confirmation)
- Support/Resistance levels

**Moderate Reliability**:
- RSI (overbought/oversold)
- MACD (trend changes)
- Bollinger Bands (volatility)

**Less Reliable Alone**:
- Stochastic Oscillator
- Williams %R
- Single-indicator systems

---

## Common Mistakes

1. **Using too many indicators**: Leads to analysis paralysis
2. **Ignoring price action**: Indicators lag price
3. **Trading against the trend**: Indicator signals in wrong direction
4. **No confirmation**: Acting on single indicator signal
5. **Wrong timeframe**: Using day-trading indicators for swing trading
6. **Ignoring volume**: Volume confirms price moves
7. **Over-optimizing**: Finding perfect settings for past data

---

## Conservative Trading Approach

**Minimum Confirmations** (pick 3):
1. Trend alignment (price above/below key MA)
2. Momentum confirmation (RSI/MACD agrees)
3. Volume confirmation (above average on signal)
4. Support/Resistance (near key level)
5. Multiple timeframe agreement

**Don't Trade**:
- Against major trend
- Without stop loss
- Based on single indicator
- During low volume periods
- When multiple indicators conflict

**Wait For**:
- Clear trend establishment
- Multiple confirmations
- Volume increase
- Risk:reward ratio > 2:1

```

### references/strategies.md

```markdown
# Trading Strategies Reference

## Dollar Cost Averaging (DCA)

### Basic DCA Strategy

**Definition**: Investing a fixed dollar amount at regular intervals regardless of price.

**How It Works**:
- Invest $100 every week for 52 weeks = $5,200 total
- Buy more units when price is low
- Buy fewer units when price is high
- Average cost per unit decreases over time

**Advantages**:
- Eliminates timing risk
- Reduces emotional decision-making
- Simple to execute
- Works well in volatile markets
- Accumulates more during dips

**Disadvantages**:
- May underperform lump sum in bull markets
- Requires discipline during fear
- Transaction fees add up (use low-fee exchanges)
- Not optimal if you have strong market timing

**Best For**:
- Conservative investors
- Long-term accumulation
- Volatile assets like Bitcoin
- Investors who fear market timing

### DCA Variants

#### 1. Fixed Amount DCA
```
Every Monday: Buy $100 of BTC regardless of price
Duration: 12 months
Total: $5,200
```

**Pros**: Simple, consistent
**Cons**: Doesn't adapt to market conditions

#### 2. Value-Based DCA (Buy the Dip)
```
When BTC < $95,000: Buy $150 (normal + $50 extra)
When BTC > $105,000: Buy $50 (reduce exposure)
When BTC $95k-$105k: Buy $100 (normal)
```

**Pros**: Adapts to market, buys more on dips
**Cons**: More complex, requires monitoring

#### 3. RSI-Based DCA
```
RSI < 30 (oversold): Buy $200 (double down)
RSI 30-70 (neutral): Buy $100 (normal)
RSI > 70 (overbought): Buy $50 (reduce) or skip
```

**Pros**: Uses technical signals, buys more when oversold
**Cons**: Can miss rallies, requires TA knowledge

#### 4. Ladder DCA
```
Week 1-4: $50/week (accumulation start)
Week 5-8: $75/week (increase exposure)
Week 9-12: $100/week (full position)
Week 13+: $100/week (maintain)
```

**Pros**: Gradual exposure, risk management
**Cons**: Slower accumulation initially

#### 5. Reverse DCA (Taking Profits)
```
Every month: Sell $100 worth of BTC
Or: When price up 10%, sell 5% of holdings
```

**Pros**: Lock in profits systematically
**Cons**: May exit too early in bull market

---

## Risk Management Strategies

### The 1-2% Rule

**Definition**: Risk no more than 1-2% of your account per trade.

**How to Calculate**:
```
Account Balance: $10,000
Risk per Trade: 2% = $200 maximum loss
Entry: $100,000
Stop Loss: $95,000 (5% down)
Position Size: $200 / ($100,000 - $95,000) = $4,000 position

If stop hit, you lose $200 (2% of account)
```

**Benefits**:
- Survive losing streaks (50 consecutive 2% losses = still have capital)
- Reduces emotional stress
- Allows for recovery

**Implementation**:
- Use position_sizer.py to calculate
- Always set stop loss before entry
- Stick to the rule even during FOMO

### Stop Loss Strategies

#### 1. Fixed Percentage Stop
```
Entry: $100,000
Stop Loss: 5% = $95,000
```

**Pros**: Simple, consistent
**Cons**: Doesn't adapt to volatility

#### 2. ATR-Based Stop
```
Entry: $100,000
ATR (14): $2,500
Stop Loss: Entry - (2 Ɨ ATR) = $100,000 - $5,000 = $95,000
```

**Pros**: Adapts to volatility
**Cons**: Requires ATR calculation

#### 3. Support-Based Stop
```
Entry: $100,000
Previous support: $96,000
Stop Loss: $95,500 (below support)
```

**Pros**: Based on price structure
**Cons**: May be too wide or too tight

#### 4. Trailing Stop
```
Entry: $100,000
Initial Stop: $95,000 (5%)
Price moves to $110,000
Trailing Stop: $104,500 (5% from current)
```

**Pros**: Locks in profits as price rises
**Cons**: Can get stopped out in volatile moves

### Take Profit Strategies

#### 1. Fixed Risk-Reward
```
Entry: $100,000
Stop Loss: $95,000 (Risk: $5,000)
Take Profit: $110,000 (Reward: $10,000)
Risk:Reward = 1:2
```

**Rule**: Only take trades with R:R ≄ 2:1 (conservative) or ≄ 3:1 (very conservative)

#### 2. Ladder Out (Scaling Out)
```
Entry: $100,000 (Position: 1 BTC)
TP1: $105,000 - Sell 33% (0.33 BTC)
TP2: $110,000 - Sell 33% (0.33 BTC)
TP3: $115,000 - Sell 34% (0.34 BTC)
```

**Pros**: Captures gains, reduces risk
**Cons**: Smaller profit if price goes straight up

#### 3. Trend-Following Exit
```
Exit when:
- Price closes below 20 EMA
- RSI drops below 40 after being overbought
- MACD bearish crossover
```

**Pros**: Rides trends longer
**Cons**: Gives back some profits

---

## Trend Following Strategies

### Moving Average Crossover

#### Golden Cross Strategy (Conservative)
```
Buy: When 50 SMA crosses above 200 SMA
Hold: While 50 SMA > 200 SMA
Sell: When 50 SMA crosses below 200 SMA
```

**Characteristics**:
- Long-term (months to years)
- Few signals (1-2 per year)
- Late entries but reliable

#### EMA Ribbon Strategy
```
Use: EMA 9, 21, 55
Buy: When 9 > 21 > 55 (all aligned)
Sell: When 9 < 21 < 55 (reverse)
```

**Characteristics**:
- Medium-term (weeks to months)
- More signals than Golden Cross
- Earlier entries

### Breakout Strategy

#### Resistance Breakout
```
Identify: Strong resistance at $100,000
Wait: For 3+ tests of resistance
Entry: Break above $100,100 with volume
Stop: Below recent low (e.g., $97,000)
Target: Previous range height added to breakout
```

**Example**:
```
Range: $95,000 - $100,000 (height: $5,000)
Breakout: $100,100
Target: $100,000 + $5,000 = $105,000
```

**Rules**:
- Volume must confirm (>1.5x average)
- Wait for retest of breakout level (optional but safer)
- Use tight stop initially

---

## DCA + Risk Management Combined

### Conservative DCA Portfolio Strategy

**Account**: $10,000
**Goal**: Accumulate BTC over 6 months
**Risk Tolerance**: Conservative

**Plan**:
```
Weekly DCA: $100 (Total: $2,600 over 6 months)
Reserve: $7,400 for opportunities

DCA Rules:
- Buy $100 of BTC every Monday at 9 AM
- If RSI < 30: Buy $150 instead
- If price drops >15% in week: Buy $200 extra
- Never skip a week (discipline)

Risk Management:
- Don't use leverage
- Keep 50% of account in stablecoins
- Only increase DCA amount if profit > 20%
```

### Moderate DCA + Swing Trading

**Account**: $20,000
**Goal**: Accumulate + active trading

**Plan**:
```
Core DCA: $500/month ($6,000/year)
Trading Capital: $14,000

DCA:
- Automatic buys, never sell these
- Cold storage after 3 months

Trading:
- Use technical_analysis.py for entries
- Risk 1% per trade ($140 per trade)
- Only trade with indicators aligned
- Take profits at 2:1 R:R minimum

Monthly Review:
- Calculate average cost basis
- Review trading performance
- Adjust if losing money
```

---

## Entry Strategies

### Three Confirmation Strategy (Conservative)

**Required Before Entry**:
1. **Trend**: Price above 50 EMA
2. **Momentum**: RSI 40-60 (not overbought)
3. **Volume**: Current volume > 20-period average
4. **Support**: Price near support level
5. **Pattern**: Bullish candlestick pattern

**Action**: Buy when 4/5 conditions met

### Pullback Entry Strategy

**Setup**:
1. Identify strong uptrend (price > 50 EMA)
2. Wait for pullback to 20 EMA or 50 EMA
3. Check RSI (should be 40-50, not oversold)
4. Wait for bullish candle close above EMA
5. Enter on next candle

**Example**:
```
BTC uptrend from $90k to $105k
Pullback to $101k (touches 20 EMA)
RSI at 45 (neutral)
Bullish engulfing candle closes at $102k
Entry: $102,500
Stop: $99,000 (below EMA)
Target: $108,000 (previous high + extension)
```

---

## Position Sizing Examples

### Scenario 1: Conservative DCA
```
Account: $5,000
Strategy: Pure DCA
Risk: None (not using stop loss, long-term hold)

Weekly: $50 for 20 weeks = $1,000 invested
Remaining: $4,000 cash reserve

Position Size: Grows slowly, no risk of liquidation
```

### Scenario 2: Moderate Trading
```
Account: $10,000
Strategy: Swing trading
Risk: 2% per trade = $200 max loss

Entry: $100,000
Stop: $97,000 (3% move)
Position Size: $200 / $3,000 = 0.0667 BTC = $6,667

If stopped out: Lose $200 (2% of account)
If target hit (+6%): Win $400 (4% of account)
```

### Scenario 3: Aggressive (Not Recommended)
```
Account: $10,000
Strategy: Leverage trading
Risk: 5% per trade = $500 max loss
Leverage: 3x

Position: $10,000 Ɨ 3 = $30,000 exposure
Stop: 1.67% = $500 loss
⚠ High risk of liquidation in volatile moves
```

**Recommendation**: Avoid leverage until very experienced

---

## Common Strategy Mistakes

### 1. No Risk Management
```
āŒ Buy without stop loss
āŒ Risk entire account on one trade
āŒ Use high leverage

āœ… Always set stop loss
āœ… Risk 1-2% per trade
āœ… Avoid leverage (or use <2x)
```

### 2. Emotional DCA
```
āŒ Skip buys during fear
āŒ Double down during FOMO
āŒ Sell DCA accumulation early

āœ… Stick to schedule
āœ… Increase buys when oversold (planned)
āœ… Hold DCA positions long-term
```

### 3. Overtrading
```
āŒ Take every setup
āŒ Trade with conflicting signals
āŒ Revenge trading after loss

āœ… Wait for quality setups
āœ… Need 3+ confirmations
āœ… Take break after 2 consecutive losses
```

### 4. No Plan
```
āŒ Enter without knowing exit
āŒ No stop loss level
āŒ No profit target

āœ… Plan entry, stop, target before trade
āœ… Write down your plan
āœ… Follow the plan
```

---

## Strategy Selection Guide

### Choose Pure DCA If:
- You're new to trading
- You have a long-term view (1+ years)
- You don't want to monitor markets daily
- You believe in Bitcoin long-term
- You want to minimize stress

### Choose DCA + Position Trading If:
- You have trading experience
- You can handle volatility
- You want to optimize entries
- You're willing to learn TA
- You have time for research

### Avoid Active Trading If:
- You're emotional under pressure
- You can't handle losses
- You don't have time to monitor
- You're new to crypto
- You need the money short-term

---

## Recommended Starting Strategy

**Month 1-3: Pure DCA**
- Learn the ropes
- Start with $50-100/week
- Don't deviate from schedule
- Study charts and indicators
- Paper trade strategies

**Month 4-6: Enhanced DCA**
- Add value-based adjustments (buy more on dips)
- Use RSI to guide amounts
- Keep 50% in reserve
- Small position trades (<10% of account)

**Month 7+: DCA + Conservative Trading**
- Maintain core DCA ($X/week)
- Trade with 20-30% of account
- Risk 1% per trade
- Only take high-probability setups
- Review monthly performance

---

## Performance Tracking

### Metrics to Track

1. **DCA Average Cost**: What's your average entry price?
2. **Win Rate**: % of winning trades
3. **Risk:Reward Ratio**: Average gain vs average loss
4. **Max Drawdown**: Largest account decline
5. **Monthly Return**: % gain/loss per month

### Review Questions

- Are you following your rules?
- What's your emotional state during trades?
- Are losses within acceptable range?
- Is the strategy sustainable long-term?
- Would you be happy if this continued for a year?

### When to Adjust

**Reduce risk if**:
- 3+ consecutive losses
- Emotional stress increasing
- Deviating from plan often
- Losing >5% of account in a month

**Increase position size if**:
- Consistently profitable for 3+ months
- Following rules strictly
- Emotional control strong
- Account grown >20%

---

## Final Advice for Conservative Traders

1. **Start small**: Better to be cautious than broke
2. **DCA is king**: Time in market > timing the market
3. **Risk management first**: Preserve capital, profits come second
4. **No leverage**: Sleep well at night
5. **Have a plan**: Know your exit before entry
6. **Journal trades**: Learn from mistakes
7. **Be patient**: Wealth compounds slowly
8. **Stay humble**: Market humbles everyone eventually
9. **Keep learning**: Markets evolve, so should you
10. **Enjoy the process**: If it's not fun, you won't last

**Remember**: The goal is to still be trading next year, not to get rich next week.

```

trading-research | SkillHub