1313"""
1414
1515from dataclasses import dataclass
16- from typing import Optional
1716from blockrun_llm import LLMClient , AsyncLLMClient , PaymentError , APIError
1817
1918
2019@dataclass
2120class ArbitrageOpportunity :
2221 """Represents a detected arbitrage opportunity."""
22+
2323 platform_a : str
2424 platform_b : str
2525 price_a : float # e.g., 0.52 (52% probability)
2626 price_b : float # e.g., 0.47 (47% probability)
27- spread : float # Combined cost below $1.00
27+ spread : float # Combined cost below $1.00
2828 expiry : str
29- market : str # e.g., "BTC > $100,000"
29+ market : str # e.g., "BTC > $100,000"
3030
3131
3232class ArbitrageAnalyzer :
@@ -39,10 +39,10 @@ class ArbitrageAnalyzer:
3939
4040 # Model recommendations by use case
4141 MODELS = {
42- "fast" : "openai/gpt-4o-mini" , # $0.15/M input - quick analysis
42+ "fast" : "openai/gpt-4o-mini" , # $0.15/M input - quick analysis
4343 "balanced" : "anthropic/claude-haiku-4.5" , # $1.00/M input - good reasoning
4444 "deep" : "anthropic/claude-sonnet-4" , # $3.00/M input - thorough analysis
45- "frontier" : "openai/gpt-5.2" , # $1.75/M input - latest capabilities
45+ "frontier" : "openai/gpt-5.2" , # $1.75/M input - latest capabilities
4646 }
4747
4848 def __init__ (self , model_tier : str = "fast" ):
@@ -84,26 +84,20 @@ def analyze_opportunity(self, opp: ArbitrageOpportunity) -> dict:
8484 response = self .client .chat (
8585 self .model ,
8686 prompt ,
87- system = "You are a quantitative trading analyst specializing in prediction market arbitrage. Be concise and actionable."
87+ system = "You are a quantitative trading analyst specializing in prediction market arbitrage. Be concise and actionable." ,
8888 )
8989
9090 return {
9191 "success" : True ,
9292 "analysis" : response ,
9393 "model" : self .model ,
94- "cost_estimate" : "~$0.001-0.01"
94+ "cost_estimate" : "~$0.001-0.01" ,
9595 }
9696
9797 except PaymentError as e :
98- return {
99- "success" : False ,
100- "error" : f"Payment failed - check USDC balance: { e } "
101- }
98+ return {"success" : False , "error" : f"Payment failed - check USDC balance: { e } " }
10299 except APIError as e :
103- return {
104- "success" : False ,
105- "error" : f"API error: { e } "
106- }
100+ return {"success" : False , "error" : f"API error: { e } " }
107101
108102 def get_market_sentiment (self , asset : str = "BTC" ) -> dict :
109103 """
@@ -129,15 +123,10 @@ def get_market_sentiment(self, asset: str = "BTC") -> dict:
129123 response = self .client .chat (
130124 self .model ,
131125 prompt ,
132- system = "You are a crypto market analyst. Provide objective, data-driven analysis."
126+ system = "You are a crypto market analyst. Provide objective, data-driven analysis." ,
133127 )
134128
135- return {
136- "success" : True ,
137- "asset" : asset ,
138- "sentiment" : response ,
139- "model" : self .model
140- }
129+ return {"success" : True , "asset" : asset , "sentiment" : response , "model" : self .model }
141130
142131 except (PaymentError , APIError ) as e :
143132 return {"success" : False , "error" : str (e )}
@@ -152,11 +141,13 @@ def compare_opportunities(self, opportunities: list[ArbitrageOpportunity]) -> di
152141 Returns:
153142 Ranked list with recommendations
154143 """
155- opp_descriptions = "\n " .join ([
156- f"{ i + 1 } . { o .market } : { o .platform_a } @ { o .price_a :.2%} vs { o .platform_b } @ { o .price_b :.2%} , "
157- f"spread: ${ o .spread :.4f} , expires: { o .expiry } "
158- for i , o in enumerate (opportunities )
159- ])
144+ opp_descriptions = "\n " .join (
145+ [
146+ f"{ i + 1 } . { o .market } : { o .platform_a } @ { o .price_a :.2%} vs { o .platform_b } @ { o .price_b :.2%} , "
147+ f"spread: ${ o .spread :.4f} , expires: { o .expiry } "
148+ for i , o in enumerate (opportunities )
149+ ]
150+ )
160151
161152 prompt = f"""Rank these arbitrage opportunities by risk-adjusted return:
162153
@@ -174,14 +165,14 @@ def compare_opportunities(self, opportunities: list[ArbitrageOpportunity]) -> di
174165 response = self .client .chat (
175166 self .model ,
176167 prompt ,
177- system = "You are a quantitative trading analyst. Rank opportunities objectively."
168+ system = "You are a quantitative trading analyst. Rank opportunities objectively." ,
178169 )
179170
180171 return {
181172 "success" : True ,
182173 "ranking" : response ,
183174 "count" : len (opportunities ),
184- "model" : self .model
175+ "model" : self .model ,
185176 }
186177
187178 except (PaymentError , APIError ) as e :
@@ -220,15 +211,18 @@ async def analyze_batch(self, opportunities: list[ArbitrageOpportunity]) -> list
220211 client .chat (
221212 self .model ,
222213 prompt ,
223- system = "Be extremely concise. Yes/No + one sentence max."
214+ system = "Be extremely concise. Yes/No + one sentence max." ,
224215 )
225216 )
226217
227218 results = await asyncio .gather (* tasks , return_exceptions = True )
228219
229220 return [
230- {"opportunity" : opp , "analysis" : r } if isinstance (r , str )
231- else {"opportunity" : opp , "error" : str (r )}
221+ (
222+ {"opportunity" : opp , "analysis" : r }
223+ if isinstance (r , str )
224+ else {"opportunity" : opp , "error" : str (r )}
225+ )
232226 for opp , r in zip (opportunities , results )
233227 ]
234228
@@ -243,7 +237,7 @@ async def analyze_batch(self, opportunities: list[ArbitrageOpportunity]) -> list
243237 price_b = 0.47 ,
244238 spread = 0.99 , # $0.99 combined cost
245239 expiry = "2024-01-15 17:00 UTC" ,
246- market = "BTC > $100,000 by Jan 15"
240+ market = "BTC > $100,000 by Jan 15" ,
247241 )
248242
249243 # Initialize analyzer (uses BASE_CHAIN_WALLET_KEY from env)
0 commit comments