@intentsolutionsio/crypto-derivatives-tracker 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/.claude-plugin/plugin.json +22 -0
  2. package/LICENSE +21 -0
  3. package/README.md +173 -0
  4. package/agents/derivatives-agent.md +408 -0
  5. package/package.json +43 -0
  6. package/skills/skill-adapter/assets/README.md +6 -0
  7. package/skills/skill-adapter/assets/config-template.json +32 -0
  8. package/skills/skill-adapter/assets/skill-schema.json +28 -0
  9. package/skills/skill-adapter/assets/test-data.json +27 -0
  10. package/skills/skill-adapter/references/README.md +4 -0
  11. package/skills/skill-adapter/references/best-practices.md +69 -0
  12. package/skills/skill-adapter/references/examples.md +73 -0
  13. package/skills/skill-adapter/scripts/README.md +8 -0
  14. package/skills/skill-adapter/scripts/helper-template.sh +42 -0
  15. package/skills/skill-adapter/scripts/validation.sh +32 -0
  16. package/skills/tracking-crypto-derivatives/ARD.md +376 -0
  17. package/skills/tracking-crypto-derivatives/PRD.md +258 -0
  18. package/skills/tracking-crypto-derivatives/SKILL.md +127 -0
  19. package/skills/tracking-crypto-derivatives/config/settings.yaml +152 -0
  20. package/skills/tracking-crypto-derivatives/references/errors.md +224 -0
  21. package/skills/tracking-crypto-derivatives/references/examples.md +460 -0
  22. package/skills/tracking-crypto-derivatives/references/implementation.md +113 -0
  23. package/skills/tracking-crypto-derivatives/scripts/basis_calculator.py +377 -0
  24. package/skills/tracking-crypto-derivatives/scripts/derivatives_tracker.py +579 -0
  25. package/skills/tracking-crypto-derivatives/scripts/formatters.py +459 -0
  26. package/skills/tracking-crypto-derivatives/scripts/funding_tracker.py +308 -0
  27. package/skills/tracking-crypto-derivatives/scripts/liquidation_monitor.py +356 -0
  28. package/skills/tracking-crypto-derivatives/scripts/oi_analyzer.py +338 -0
  29. package/skills/tracking-crypto-derivatives/scripts/options_analyzer.py +373 -0
@@ -0,0 +1,113 @@
1
+ # Tracking Crypto Derivatives - Implementation Reference
2
+
3
+ ## Detailed Output Formats
4
+
5
+ ### Funding Rate Report
6
+ ```
7
+ BTC PERPETUAL FUNDING RATES
8
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
9
+ Exchange Current 24h Avg 7d Avg Next Payment
10
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
11
+ Binance +0.0150% +0.0120% +0.0080% 2h 15m
12
+ Bybit +0.0180% +0.0140% +0.0100% 2h 15m
13
+ OKX +0.0130% +0.0110% +0.0090% 2h 15m
14
+ Deribit +0.0200% +0.0150% +0.0120% 2h 15m
15
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
16
+ Weighted Avg: +0.0158% | Annualized: +17.29%
17
+ Sentiment: Moderately Bullish
18
+ ```
19
+
20
+ ### Open Interest Report
21
+ ```
22
+ BTC OPEN INTEREST ANALYSIS
23
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
24
+ Exchange OI (USD) 24h Chg 7d Chg Share
25
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
26
+ Binance $8.2B +2.5% +8.1% 44.3%
27
+ Bybit $4.5B +1.8% +5.2% 24.3%
28
+ OKX $3.1B +3.2% +12.5% 16.8%
29
+ BitMEX $1.5B -0.5% -2.1% 8.1%
30
+ Deribit $1.2B +0.8% +3.4% 6.5%
31
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
32
+ Total OI: $18.5B (+2.3% 24h)
33
+ Long/Short Ratio: 1.15 (53.5% long)
34
+ ```
35
+
36
+ ### Liquidation Heatmap
37
+ ```
38
+ BTC LIQUIDATION LEVELS
39
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
40
+ Current Price: $67,500
41
+
42
+ LONG LIQUIDATIONS (below):
43
+ $65,000 ████████████ $125M (HIGH DENSITY)
44
+ $62,500 ███████ $85M
45
+ $60,000 ████████████████████ $210M (CRITICAL)
46
+
47
+ SHORT LIQUIDATIONS (above):
48
+ $70,000 █████████ $95M
49
+ $72,500 █████████████ $145M (HIGH DENSITY)
50
+ $75,000 █████████████████ $180M
51
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
52
+ 24h Liquidations: Longs $45.2M | Shorts $32.8M
53
+ ```
54
+
55
+ ## Options Analysis Deep Dive
56
+
57
+ ### Options Commands
58
+ ```bash
59
+ # Get options overview
60
+ python derivatives_tracker.py options BTC
61
+
62
+ # Show put/call ratio
63
+ python derivatives_tracker.py options BTC --pcr
64
+
65
+ # Find max pain for expiry
66
+ python derivatives_tracker.py options BTC --expiry 2025-01-31
67
+
68
+ # Track large options trades
69
+ python derivatives_tracker.py options BTC --flow
70
+ ```
71
+
72
+ ### Options Insights
73
+ - **High IV rank** (>80): Options expensive, consider selling
74
+ - **Low IV rank** (<20): Options cheap, consider buying
75
+ - **Max pain**: Price where most options expire worthless
76
+
77
+ ## Basis Trading Guide
78
+
79
+ ### Basis Commands
80
+ ```bash
81
+ # Get spot-perp basis
82
+ python derivatives_tracker.py basis BTC
83
+
84
+ # Get quarterly futures basis
85
+ python derivatives_tracker.py basis BTC --quarterly
86
+
87
+ # Show all basis opportunities
88
+ python derivatives_tracker.py basis --all
89
+ ```
90
+
91
+ ### Basis Trading Interpretation
92
+ - **Positive basis**: Futures > Spot (contango, normal)
93
+ - **Negative basis**: Futures < Spot (backwardation)
94
+ - **Cash-and-carry**: Buy spot + sell futures when basis high
95
+
96
+ ## Key Concepts
97
+
98
+ - **Funding Rate**: Payment between longs/shorts every 8h
99
+ - **Open Interest**: Total outstanding contracts
100
+ - **Basis**: Difference between futures and spot price
101
+ - **Max Pain**: Strike where most options expire worthless
102
+ - **IV Rank**: Current IV percentile vs historical
103
+
104
+ ## Risk Warning
105
+
106
+ Derivatives are leveraged instruments with high risk of loss.
107
+ - Funding costs accumulate over time
108
+ - Liquidations can happen rapidly
109
+ - Options can expire worthless
110
+ - This tool provides analysis only, not financial advice
111
+
112
+ ---
113
+ *[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
@@ -0,0 +1,377 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Basis and spread calculator.
4
+
5
+ Calculates futures basis and spreads with:
6
+ - Spot-futures basis tracking
7
+ - Annualized basis yield
8
+ - Term structure analysis
9
+ - Contango/backwardation detection
10
+ """
11
+
12
+ from dataclasses import dataclass
13
+ from decimal import Decimal
14
+ from typing import Dict, List, Optional
15
+ from datetime import datetime, date
16
+
17
+ from exchange_client import ExchangeClient, BasisData, Exchange
18
+
19
+
20
+ @dataclass
21
+ class BasisAnalysis:
22
+ """Comprehensive basis analysis."""
23
+
24
+ symbol: str
25
+ spot_price: Decimal
26
+ basis_data: List[BasisData]
27
+ avg_basis_pct: float
28
+ avg_annualized: float
29
+ market_structure: str # "contango", "backwardation", "mixed"
30
+ structure_strength: str # "strong", "moderate", "weak"
31
+ best_carry_expiry: Optional[str]
32
+ best_carry_yield: float
33
+ timestamp: datetime
34
+
35
+
36
+ @dataclass
37
+ class CarryOpportunity:
38
+ """Cash-and-carry arbitrage opportunity."""
39
+
40
+ symbol: str
41
+ exchange: str
42
+ expiry: str
43
+ spot_price: Decimal
44
+ futures_price: Decimal
45
+ basis_pct: float
46
+ days_to_expiry: int
47
+ annualized_yield: float
48
+ direction: str # "long_basis" or "short_basis"
49
+ strategy: str # Trade description
50
+ risk_notes: str
51
+
52
+
53
+ class BasisCalculator:
54
+ """
55
+ Calculates and analyzes futures basis.
56
+
57
+ Features:
58
+ - Multi-expiry analysis
59
+ - Term structure visualization
60
+ - Carry trade identification
61
+ - Contango/backwardation detection
62
+ """
63
+
64
+ # Structure interpretation
65
+ STRONG_BASIS = 5.0 # >5% annualized is strong
66
+ MODERATE_BASIS = 2.0 # >2% is moderate
67
+
68
+ def __init__(
69
+ self,
70
+ client: Optional[ExchangeClient] = None,
71
+ ):
72
+ """
73
+ Initialize basis calculator.
74
+
75
+ Args:
76
+ client: Exchange client for data fetching
77
+ """
78
+ self.client = client or ExchangeClient(use_mock=True)
79
+
80
+ def analyze(
81
+ self,
82
+ symbol: str,
83
+ spot_price: Optional[Decimal] = None,
84
+ exchanges: Optional[List[Exchange]] = None,
85
+ ) -> BasisAnalysis:
86
+ """
87
+ Analyze basis for a symbol.
88
+
89
+ Args:
90
+ symbol: Trading symbol (e.g., "BTC")
91
+ spot_price: Current spot price
92
+ exchanges: Exchanges to include
93
+
94
+ Returns:
95
+ BasisAnalysis with all metrics
96
+ """
97
+ # Set default spot price if not provided
98
+ if spot_price is None:
99
+ if symbol == "BTC":
100
+ spot_price = Decimal("67500")
101
+ elif symbol == "ETH":
102
+ spot_price = Decimal("2500")
103
+ else:
104
+ spot_price = Decimal("100")
105
+
106
+ # Fetch basis data
107
+ basis_list = self.client.get_all_basis(symbol, spot_price, exchanges)
108
+
109
+ if not basis_list:
110
+ raise ValueError(f"No basis data available for {symbol}")
111
+
112
+ # Calculate averages
113
+ avg_basis = sum(b.basis_pct for b in basis_list) / len(basis_list)
114
+ avg_annual = sum(b.annualized_pct for b in basis_list) / len(basis_list)
115
+
116
+ # Determine market structure
117
+ structure, strength = self._analyze_structure(basis_list)
118
+
119
+ # Find best carry opportunity
120
+ best_carry = max(basis_list, key=lambda b: b.annualized_pct)
121
+
122
+ return BasisAnalysis(
123
+ symbol=symbol,
124
+ spot_price=spot_price,
125
+ basis_data=basis_list,
126
+ avg_basis_pct=round(avg_basis, 3),
127
+ avg_annualized=round(avg_annual, 2),
128
+ market_structure=structure,
129
+ structure_strength=strength,
130
+ best_carry_expiry=best_carry.expiry,
131
+ best_carry_yield=best_carry.annualized_pct,
132
+ timestamp=datetime.now(),
133
+ )
134
+
135
+ def _analyze_structure(
136
+ self,
137
+ basis_list: List[BasisData],
138
+ ) -> tuple:
139
+ """
140
+ Analyze term structure from basis data.
141
+
142
+ Returns:
143
+ (structure, strength) tuple
144
+ """
145
+ positive = sum(1 for b in basis_list if b.basis_pct > 0)
146
+ negative = sum(1 for b in basis_list if b.basis_pct < 0)
147
+ total = len(basis_list)
148
+
149
+ # Determine structure
150
+ if positive == total:
151
+ structure = "contango"
152
+ elif negative == total:
153
+ structure = "backwardation"
154
+ elif positive > negative:
155
+ structure = "contango" # Mostly contango
156
+ elif negative > positive:
157
+ structure = "backwardation"
158
+ else:
159
+ structure = "mixed"
160
+
161
+ # Determine strength from magnitude
162
+ avg_abs = sum(abs(b.annualized_pct) for b in basis_list) / total
163
+ if avg_abs >= self.STRONG_BASIS:
164
+ strength = "strong"
165
+ elif avg_abs >= self.MODERATE_BASIS:
166
+ strength = "moderate"
167
+ else:
168
+ strength = "weak"
169
+
170
+ return structure, strength
171
+
172
+ def find_carry_opportunities(
173
+ self,
174
+ symbols: List[str],
175
+ min_yield: float = 5.0,
176
+ ) -> List[CarryOpportunity]:
177
+ """
178
+ Find cash-and-carry arbitrage opportunities.
179
+
180
+ Strategy:
181
+ - Contango: Buy spot, sell futures, collect basis
182
+ - Backwardation: Sell spot (if possible), buy futures
183
+
184
+ Args:
185
+ symbols: Symbols to scan
186
+ min_yield: Minimum annualized yield (%)
187
+
188
+ Returns:
189
+ List of carry opportunities
190
+ """
191
+ opportunities = []
192
+
193
+ for symbol in symbols:
194
+ try:
195
+ analysis = self.analyze(symbol)
196
+
197
+ for basis in analysis.basis_data:
198
+ if abs(basis.annualized_pct) >= min_yield:
199
+ if basis.basis_pct > 0:
200
+ # Contango - long basis trade
201
+ direction = "long_basis"
202
+ strategy = (
203
+ f"Buy {symbol} spot at ${float(analysis.spot_price):,.0f}, "
204
+ f"sell {basis.expiry} futures at ${float(basis.futures_price):,.0f}"
205
+ )
206
+ risk_notes = "Funding costs may reduce yield; early liquidation risk"
207
+ else:
208
+ # Backwardation - short basis trade
209
+ direction = "short_basis"
210
+ strategy = (
211
+ f"Short {symbol} spot (borrow), "
212
+ f"buy {basis.expiry} futures at ${float(basis.futures_price):,.0f}"
213
+ )
214
+ risk_notes = "Borrowing costs apply; squeeze risk in tight markets"
215
+
216
+ opportunities.append(CarryOpportunity(
217
+ symbol=symbol,
218
+ exchange=basis.exchange,
219
+ expiry=basis.expiry,
220
+ spot_price=analysis.spot_price,
221
+ futures_price=basis.futures_price,
222
+ basis_pct=basis.basis_pct,
223
+ days_to_expiry=basis.days_to_expiry,
224
+ annualized_yield=basis.annualized_pct,
225
+ direction=direction,
226
+ strategy=strategy,
227
+ risk_notes=risk_notes,
228
+ ))
229
+ except Exception:
230
+ continue
231
+
232
+ # Sort by yield descending
233
+ opportunities.sort(key=lambda x: abs(x.annualized_yield), reverse=True)
234
+ return opportunities
235
+
236
+ def get_term_structure(
237
+ self,
238
+ symbol: str,
239
+ spot_price: Optional[Decimal] = None,
240
+ ) -> List[Dict]:
241
+ """
242
+ Get term structure data for visualization.
243
+
244
+ Args:
245
+ symbol: Trading symbol
246
+ spot_price: Current spot price
247
+
248
+ Returns:
249
+ List of expiry data points
250
+ """
251
+ analysis = self.analyze(symbol, spot_price)
252
+
253
+ # Sort by days to expiry
254
+ sorted_basis = sorted(
255
+ analysis.basis_data,
256
+ key=lambda b: b.days_to_expiry
257
+ )
258
+
259
+ return [
260
+ {
261
+ "expiry": b.expiry,
262
+ "days": b.days_to_expiry,
263
+ "futures_price": float(b.futures_price),
264
+ "basis_pct": b.basis_pct,
265
+ "annualized_pct": b.annualized_pct,
266
+ "exchange": b.exchange,
267
+ }
268
+ for b in sorted_basis
269
+ ]
270
+
271
+ def calculate_implied_rate(
272
+ self,
273
+ spot: Decimal,
274
+ futures: Decimal,
275
+ days: int,
276
+ ) -> Dict:
277
+ """
278
+ Calculate implied interest rate from basis.
279
+
280
+ Args:
281
+ spot: Spot price
282
+ futures: Futures price
283
+ days: Days to expiry
284
+
285
+ Returns:
286
+ Dict with rate calculations
287
+ """
288
+ if days <= 0:
289
+ return {"error": "Days must be positive"}
290
+
291
+ basis = float(futures - spot)
292
+ basis_pct = basis / float(spot) * 100
293
+ annualized = basis_pct * 365 / days
294
+
295
+ return {
296
+ "spot": float(spot),
297
+ "futures": float(futures),
298
+ "days_to_expiry": days,
299
+ "basis_usd": round(basis, 2),
300
+ "basis_pct": round(basis_pct, 3),
301
+ "annualized_rate": round(annualized, 2),
302
+ "structure": "contango" if basis > 0 else "backwardation",
303
+ }
304
+
305
+
306
+ def demo():
307
+ """Demonstrate basis calculator."""
308
+ calc = BasisCalculator()
309
+
310
+ print("=" * 70)
311
+ print("BASIS CALCULATOR")
312
+ print("=" * 70)
313
+
314
+ # Analyze BTC basis
315
+ analysis = calc.analyze("BTC", Decimal("67500"))
316
+
317
+ print(f"\n📈 {analysis.symbol} BASIS ANALYSIS")
318
+ print(f" Spot Price: ${analysis.spot_price:,}")
319
+ print("-" * 60)
320
+
321
+ print(f"\n{'Expiry':<12} {'Futures':>12} {'Basis':>10} {'Annual':>10} {'Days':>6}")
322
+ print("-" * 60)
323
+
324
+ for basis in sorted(analysis.basis_data, key=lambda b: b.days_to_expiry):
325
+ print(
326
+ f"{basis.expiry:<12} "
327
+ f"${float(basis.futures_price):>10,.0f} "
328
+ f"{basis.basis_pct:>+9.2f}% "
329
+ f"{basis.annualized_pct:>+9.1f}% "
330
+ f"{basis.days_to_expiry:>6}"
331
+ )
332
+
333
+ print("-" * 60)
334
+ print(f"\nMarket Structure: {analysis.structure_strength.title()} {analysis.market_structure.title()}")
335
+ print(f"Average Basis: {analysis.avg_basis_pct:+.2f}%")
336
+ print(f"Average Annualized: {analysis.avg_annualized:+.1f}%")
337
+ print(f"Best Carry: {analysis.best_carry_expiry} ({analysis.best_carry_yield:+.1f}% annualized)")
338
+
339
+ # Term structure
340
+ print("\n" + "-" * 60)
341
+ print("TERM STRUCTURE")
342
+ print("-" * 60)
343
+
344
+ structure = calc.get_term_structure("BTC", Decimal("67500"))
345
+ for point in structure:
346
+ bar = "+" * min(int(abs(point["annualized_pct"]) / 2), 20)
347
+ direction = "▲" if point["annualized_pct"] > 0 else "▼"
348
+ print(f"{point['expiry']:<12} {direction} {bar} {point['annualized_pct']:+.1f}%")
349
+
350
+ # Carry opportunities
351
+ print("\n" + "=" * 70)
352
+ print("CARRY TRADE SCANNER")
353
+ print("=" * 70)
354
+
355
+ opportunities = calc.find_carry_opportunities(["BTC", "ETH"], min_yield=5.0)
356
+ if opportunities:
357
+ print(f"\n{'Symbol':<6} {'Expiry':<12} {'Basis':>8} {'Annual':>10} {'Direction':<12}")
358
+ print("-" * 60)
359
+ for opp in opportunities[:5]:
360
+ print(
361
+ f"{opp.symbol:<6} "
362
+ f"{opp.expiry:<12} "
363
+ f"{opp.basis_pct:>+7.2f}% "
364
+ f"{opp.annualized_yield:>+9.1f}% "
365
+ f"{opp.direction:<12}"
366
+ )
367
+
368
+ print("\nTop Opportunity:")
369
+ top = opportunities[0]
370
+ print(f" Strategy: {top.strategy}")
371
+ print(f" Risk: {top.risk_notes}")
372
+ else:
373
+ print("\nNo carry opportunities found above threshold")
374
+
375
+
376
+ if __name__ == "__main__":
377
+ demo()