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"" 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"{out_token})>"