# **SQL for Forex Trading - Ultimate Cheat Sheet**

## **1. Essential Command Structure**
```
[ACTION] [TARGET] [DETAILS] [CONDITIONS] [MODIFIERS]
```
Example:  
```sql
SELECT bid, ask           -- ACTION: what to get
FROM ticks                -- TARGET: where from
WHERE symbol = 'EUR/USD'  -- CONDITIONS: filters
ORDER BY timestamp DESC   -- MODIFIERS: sorting
LIMIT 100;                -- MODIFIERS: quantity
```

## **2. Core Commands**

### **Table Operations**
| Command | Example | Purpose |
|---------|---------|---------|
| `CREATE TABLE` | `CREATE TABLE ticks(timestamp TIMESTAMP, bid FLOAT)` | Create new table |
| `ALTER TABLE` | `ALTER TABLE ticks ADD COLUMN volume FLOAT` | Modify structure |
| `DROP TABLE` | `DROP TABLE ticks` | Delete table |

### **Data Import/Export**
```sql
-- Import CSV
COPY ticks FROM '/data/ticks.csv' (FORMAT CSV);

-- Export results
COPY (SELECT * FROM ticks) TO '/output.csv' (FORMAT CSV);
```

### **Basic Queries**
```sql
-- All columns, limited rows
SELECT * FROM ticks LIMIT 10;

-- Specific columns
SELECT timestamp, bid, ask FROM ticks;

-- Filtered data
SELECT * FROM ticks WHERE bid > 1.1000 AND volume > 1000;
```

## **3. Time-Series Patterns**

### **Candlestick Generation**
```sql
SELECT 
  DATE_TRUNC('1 minute', timestamp) AS minute,
  FIRST(bid) AS open,
  MAX(bid) AS high,
  MIN(bid) AS low,
  LAST(bid) AS close,
  SUM(volume) AS volume
FROM ticks
GROUP BY minute;
```

### **Rolling Calculations**
```sql
-- 30-minute moving average
SELECT 
  timestamp,
  AVG(bid) OVER (ORDER BY timestamp ROWS 29 PRECEDING) AS ma_30
FROM ticks;

-- Rolling spread
SELECT 
  timestamp,
  AVG(ask - bid) OVER (ORDER BY timestamp RANGE '5 minutes') AS avg_spread
FROM ticks;
```

## **4. Key Metrics**

### **Spread Analysis**
```sql
-- Basic spread
SELECT timestamp, ask - bid AS spread FROM ticks;

-- Session averages
SELECT 
  EXTRACT(HOUR FROM timestamp) AS hour,
  AVG(ask - bid) AS avg_spread
FROM ticks
GROUP BY hour;
```

### **Order Book Imbalance**
```sql
SELECT 
  timestamp,
  (bid_size - ask_size) / (bid_size + ask_size) AS imbalance
FROM ticks;
```

## **5. Advanced Patterns**

### **Correlation Analysis**
```sql
WITH hourly AS (
  SELECT 
    DATE_TRUNC('hour', timestamp) AS hour,
    AVG(CASE WHEN symbol='EUR/USD' THEN bid END) AS eurusd,
    AVG(CASE WHEN symbol='USD/JPY' THEN bid END) AS usdjpy
  FROM ticks
  GROUP BY hour
)
SELECT CORR(eurusd, usdjpy) FROM hourly;
```

### **Event Detection**
```sql
-- Large price jumps
SELECT *
FROM ticks
WHERE ABS(bid - LAG(bid) OVER (ORDER BY timestamp)) > 0.0010;
```

## **6. Optimization**

### **Indexing**
```sql
-- Basic index
CREATE INDEX idx_symbol_time ON ticks(symbol, timestamp);

-- For time-series
SELECT create_hypertable('ticks', 'timestamp');  -- TimescaleDB
```

### **Query Performance**
```sql
-- Explain plan
EXPLAIN ANALYZE SELECT * FROM ticks WHERE symbol = 'EUR/USD';

-- Common optimizations:
-- 1. Use WHERE before GROUP BY
-- 2. Limit selected columns (not SELECT *)
-- 3. Use EXISTS instead of IN for large datasets
```

## **7. Quick Reference**

### **Data Types**
| Type | Example | Used For |
|------|---------|----------|
| `TIMESTAMP` | `2024-01-01 12:00:00` | Time data |
| `FLOAT` | `1.12345` | Prices/values |
| `VARCHAR` | `'EUR/USD'` | Text/symbols |
| `BOOLEAN` | `TRUE` | Flags |

### **Aggregate Functions**
| Function | Example | Purpose |
|----------|---------|---------|
| `AVG()` | `AVG(bid)` | Average |
| `MAX()` | `MAX(ask)` | Highest value |
| `MIN()` | `MIN(bid)` | Lowest value |
| `SUM()` | `SUM(volume)` | Total volume |
| `COUNT()` | `COUNT(*)` | Row count |

## **8. Common Errors & Fixes**

| Error | Solution |
|-------|----------|
| Missing comma in column list | Check commas between columns in SELECT/CREATE |
| "GROUP BY" needed | Add `GROUP BY` when using aggregates |
| NULL comparison issues | Use `IS NULL` not `= NULL` |
| Slow queries | Add indexes on filtered/sorted columns |

## **How to Use This Cheat Sheet**
1. **Daily Practice**: Pick 2-3 patterns to implement each day  
2. **Wall Reference**: Print and keep near your workstation  
3. **Troubleshooting**: Use the errors section when queries fail  

Want me to:  
1. Provide a PDF version of this cheat sheet?  
2. Add more forex-specific examples?  
3. Or focus on a particular section in more detail?

---

Here's a streamlined 8-week roadmap focused purely on practical SQL skills for forex bid/ask analysis, structured for immediate application in cron jobs:

### **Week 1-2: Core Foundations for Tick Data**
**Goal:** Process raw ticks into usable formats  
**Key Skills:**
1. **Basic filtering**  
   ```sql
   -- Isolate specific currency pairs/time windows
   SELECT * FROM ticks 
   WHERE symbol = 'EUR/USD' 
     AND timestamp BETWEEN '2024-01-01 00:00' AND '2024-01-01 23:59'
   ```

2. **Candlestick generation**  
   ```sql
   -- 1-minute OHLC candles
   SELECT 
     symbol,
     DATE_TRUNC('minute', timestamp) AS minute,
     FIRST(bid) AS open,
     MAX(bid) AS high,
     MIN(bid) AS low,
     LAST(bid) AS close
   FROM ticks
   GROUP BY symbol, minute
   ```

3. **Spread metrics**  
   ```sql
   -- Average spread by hour
   SELECT 
     symbol,
     EXTRACT(HOUR FROM timestamp) AS hour,
     AVG(ask - bid) AS avg_spread
   FROM ticks
   GROUP BY symbol, hour
   ```

### **Week 3-4: Session Analysis & Basic Signals**
**Goal:** Identify trading opportunities  
**Key Skills:**
1. **Session volatility**  
   ```sql
   -- London vs. NY session comparison
   SELECT 
     CASE 
       WHEN EXTRACT(HOUR FROM timestamp) BETWEEN 7 AND 15 THEN 'London'
       WHEN EXTRACT(HOUR FROM timestamp) BETWEEN 13 AND 21 THEN 'NY'
       ELSE 'Other' 
     END AS session,
     STDDEV((bid+ask)/2) AS volatility
   FROM ticks
   GROUP BY session
   ```

2. **Rolling spreads**  
   ```sql
   -- 30-minute moving spread
   SELECT 
     timestamp,
     AVG(ask - bid) OVER (
       ORDER BY timestamp 
       ROWS BETWEEN 29 PRECEDING AND CURRENT ROW
     ) AS rolling_spread
   FROM ticks
   WHERE symbol = 'GBP/USD'
   ```

3. **Basic alerts**  
   ```sql
   -- Spread widening alert
   SELECT symbol, timestamp, (ask - bid) AS spread
   FROM ticks
   WHERE (ask - bid) > 3 * (
     SELECT AVG(ask - bid) 
     FROM ticks 
     WHERE timestamp > NOW() - INTERVAL '1 day'
   )
   ```

### **Week 5-6: Advanced Pattern Detection**
**Goal:** Build automated signal detectors  
**Key Skills:**
1. **Microprice calculation**  
   ```sql
   -- Weighted mid-price
   SELECT 
     timestamp,
     (bid*ask_size + ask*bid_size)/(bid_size + ask_size) AS microprice
   FROM ticks
   ```

2. **Order flow imbalance**  
   ```sql
   -- Bid/ask size ratio
   SELECT 
     timestamp,
     (bid_size - ask_size)/(bid_size + ask_size) AS imbalance
   FROM ticks
   WHERE ABS((bid_size - ask_size)/(bid_size + ask_size)) > 0.7
   ```

3. **Consecutive moves**  
   ```sql
   -- 5+ consecutive bid increases
   WITH changes AS (
     SELECT *,
       CASE WHEN bid > LAG(bid) OVER (ORDER BY timestamp) THEN 1 ELSE 0 END AS is_up
     FROM ticks
   )
   SELECT timestamp, bid
   FROM changes
   WHERE is_up = 1
   ORDER BY timestamp
   LIMIT 5
   ```

### **Week 7-8: Optimization & Productionization**
**Goal:** Make scripts robust and efficient  
**Key Skills:**
1. **Indexing for time-series**  
   ```sql
   CREATE INDEX idx_symbol_time ON ticks(symbol, timestamp);
   ```

2. **CTEs for complex logic**  
   ```sql
   WITH 
   london_ticks AS (
     SELECT * FROM ticks 
     WHERE EXTRACT(HOUR FROM timestamp) BETWEEN 7 AND 15
   ),
   spreads AS (
     SELECT symbol, AVG(ask - bid) AS avg_spread
     FROM london_ticks
     GROUP BY symbol
   )
   SELECT * FROM spreads WHERE avg_spread > 0.0005;
   ```

3. **Partitioning large tables**  
   ```sql
   CREATE TABLE ticks_partitioned (
     -- schema
   ) PARTITION BY RANGE (timestamp);
   ```

### **Daily Practice Structure**
1. **Morning (5 min):** Run basic monitoring query  
   ```sql
   -- Current spread status
   SELECT symbol, AVG(ask - bid) AS spread 
   FROM ticks 
   WHERE timestamp > NOW() - INTERVAL '15 minutes'
   GROUP BY symbol;
   ```

2. **Evening (15 min):** Build one new analysis query  
   - Monday: Session comparisons  
   - Tuesday: Rolling metrics  
   - Wednesday: Alert conditions  
   - Thursday: Optimization tweaks  
   - Friday: Backtest old queries  

### **Key Mindset Shifts**
1. **Think in ticks, not hours:** Your queries should process milliseconds efficiently  
2. **Pre-compute everything:** Generate candlesticks/aggregates in SQL, not Python  
3. **Log everything:** Every cron job should write results to a logging table  

Want the condensed 1-page cheat sheet version of this roadmap? Or should we focus next on building your first complete cron-ready SQL script?