Automated Action 5bb78bd9be Implement Solana arbitrage analytics backend
- Create project structure with FastAPI
- Add database models for blocks, transactions, arbitrages, pools, and DEXes
- Implement Solana RPC client for fetching blockchain data
- Create arbitrage detection algorithm
- Implement comprehensive API endpoints for analytics
- Set up database migrations with Alembic
- Add detailed project documentation

generated with BackendIM... (backend.im)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-05-12 14:13:06 +00:00

64 lines
3.0 KiB
Python

from datetime import datetime
from sqlalchemy import (
Column, Integer, String, DateTime, Float,
BigInteger, ForeignKey, JSON, Boolean, Text
)
from sqlalchemy.orm import relationship
from app.db.base_class import Base
class Arbitrage(Base):
"""Arbitrage transaction model."""
id = Column(Integer, primary_key=True, index=True)
transaction_id = Column(Integer, ForeignKey("transaction.id"), nullable=False)
initiator_address = Column(String, index=True, nullable=False)
start_token_address = Column(String, index=True, nullable=False)
start_token_symbol = Column(String, nullable=True)
start_amount = Column(Float, nullable=False)
end_amount = Column(Float, nullable=False)
profit_amount = Column(Float, nullable=False) # end_amount - start_amount
profit_percentage = Column(Float, nullable=False) # (end_amount - start_amount) / start_amount * 100
success = Column(Boolean, nullable=False, default=False)
failure_reason = Column(Text, nullable=True)
gas_cost = Column(Float, nullable=True) # Estimated gas cost in SOL
net_profit = Column(Float, nullable=True) # profit_amount - gas_cost
legs_count = Column(Integer, nullable=False, default=0)
route_description = Column(Text, nullable=True) # Human-readable route
included_dexes = Column(JSON, nullable=True) # List of DEX names involved
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
# Relationships
transaction = relationship("Transaction", back_populates="arbitrages")
legs = relationship("ArbitrageLeg", back_populates="arbitrage", cascade="all, delete-orphan")
def __repr__(self):
token = self.start_token_symbol or self.start_token_address[:8]
return f"<Arbitrage(token={token}, profit={self.profit_percentage:.2f}%)>"
class ArbitrageLeg(Base):
"""Individual hop/leg in an arbitrage path."""
id = Column(Integer, primary_key=True, index=True)
arbitrage_id = Column(Integer, ForeignKey("arbitrage.id"), nullable=False)
leg_index = Column(Integer, nullable=False) # Order in the arbitrage path
pool_id = Column(Integer, ForeignKey("pool.id"), nullable=False)
token_in_address = Column(String, index=True, nullable=False)
token_in_symbol = Column(String, nullable=True)
token_in_amount = Column(Float, nullable=False)
token_out_address = Column(String, index=True, nullable=False)
token_out_symbol = Column(String, nullable=True)
token_out_amount = Column(Float, nullable=False)
price_impact = Column(Float, nullable=True) # Price impact percentage
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
# Relationships
arbitrage = relationship("Arbitrage", back_populates="legs")
pool = relationship("Pool", back_populates="arbitrage_legs")
def __repr__(self):
in_token = self.token_in_symbol or self.token_in_address[:8]
out_token = self.token_out_symbol or self.token_out_address[:8]
return f"<ArbitrageLeg(index={self.leg_index}, swap={in_token}->{out_token})>"