fijimf / reactfij

Some more experiments
Other
0 stars 0 forks source link

Load process #1

Open fijimf opened 10 years ago

fijimf commented 10 years ago

1) Load all NCAA Schools -- http://data.ncaa.com/jsonp/schools (skipping where name == null) 2) For each school load http://www.ncaa.com/schools/$school$/basketball-men a) Extract

Look for "Div I." b) If Div I extract conference, schedule and roster checks c) If not Div I maintains stub 3) Extract scoreboard info for each date in the season 4) For each game in the schedule a) Expand and verify team info b) Verify game on schedule and build game database, track locations, start times, neutral court, tournament, as well as score. c) Add line score for player. d) Add line score for team 5) Profit

fijimf commented 9 years ago

package com.fijimf.deepfij

import org.joda.time.{DateMidnight, DateTime}

case class Team(id:Long, name:String)

case class Game(id:Long, date:DateTime, homeTeam:Team, awayTeam:Team, result:Option[Result])

case class Result(homeScore:Int, awayScore:Int)

case class Schedule(games:Map[DateMidnight, List[Game]], teams:List[Team])

case class Bettor(id:Long, name:String, offers:List[Offer], bets:List[Bet], balance:Double, availableBalance:Double)

case class Offer(id:Long, game:Game, team:Team, doubleSpread:Int)

case class Bet(game:Game, homeBettor:Bettor, awayBettor:Bettor, doubleSpread:Int)

case class Book(schedule:Schedule, bettors:List[Bettor], bets:List[Bet]) {

def addBettor(p:Bettor):Book = ???

def addTeam(t:Team):Book = ???

def addGame(g:Game):Book = ???

def offerBet(o:Offer): Book = ???

def processResult(gameId:Long, result:Result)= ???

def sweepOffers(timestamp:DateTime) = ???

}

fijimf commented 9 years ago

package com.fijimf.deepfij

import org.joda.time.DateTime

import scala.collection.Iterable

sealed trait HomeAway {
  def opp: HomeAway
}

case object Home extends HomeAway {
  override def opp: HomeAway = Away
}

case object Away extends HomeAway {
  override def opp: HomeAway = Home
}

case class Team(id: Long, name: String) {
  override def toString = name
}

case class Game(id: Long, date: DateTime, homeTeam: Team, awayTeam: Team, result: Option[Result]) {
  override def toString = result match {
    case Some(r) => "[%06d] %s %20s %3d at %20s %3d".format(id, date.toString("yyyy-MM-dd hh:mm"), awayTeam, r.awayScore, homeTeam, r.awayScore)
    case None => "[%06d] %s %20s     at %20s    ".format(id, date.toString("yyyy-MM-dd hh:mm"), awayTeam, homeTeam)
  }
}

case class Result(homeScore: Int, awayScore: Int)

case class Schedule(games: Map[Long, Game], teams: Map[Long, Team]) {
  def addTeam(t: Team): Either[Throwable, Schedule] = {
    if (teams.contains(t.id)) {
      Left(new RuntimeException("Team with id " + t.id + " exists already"))
    } else {
      Right(copy(teams = teams + (t.id -> t)))
    }
  }

  def addGame(g: Game): Either[Throwable, Schedule] = {
    if (games.contains(g.id)) {
      Left(new RuntimeException("Game with id " + g.id + " exists already"))
    } else {
      Right(copy(games = games + (g.id -> g)))
    }
  }
}

case class Bettor(id: Long, name: String, balance: Double) {
  override def toString = "[%06d] %20s     %12.2f    ".format(id, name, balance)
}

case class Offer(id: Long, timestamp: DateTime, bettorId: Long, gameId: Long, ha: HomeAway, doubleSpread: Int, amount: Double) {
  def matches(o: Offer) = gameId == o.gameId && doubleSpread == (-o.doubleSpread) && ha != o.ha

  def createMatchingOffer(idContext: () => (Long, DateTime), b: Long): Offer = {
    val (mId, mTimestamp) = idContext()
    Offer(mId, mTimestamp, b, gameId, ha.opp, -doubleSpread, amount)
  }

  def createBet(o: Offer): (Bet, Offer, Offer) = {
    assert(this.matches(o))
    val betAmount = math.min(amount, o.amount)
    val newSelf: Offer = copy(amount = amount - betAmount)
    val newOffer: Offer = o.copy(amount = amount - betAmount)
    ha match {
      case Home => (Bet(gameId, this.id, o.id, doubleSpread, betAmount), newOffer, newSelf)
      case Away => (Bet(gameId, o.id, this.id, -doubleSpread, betAmount), newOffer, newSelf)
    }
  }

  def isEligible(b: Book): Boolean = b.bettors(bettorId).balance > 0

  implicit val ordering:Ordered[Offer] = new Ordered[Offer] {
    override def compare(that: Offer): Int = {
      val s = doubleSpread - that.doubleSpread
      if (s!=0) {
        s
      } else {
        timestamp.compareTo(that.timestamp)
      }
    }
  }

}

case class Bet(gameId: Long, homeOfferId: Long, awayOfferId: Long, doubleSpread: Int, amount: Double) {

}

case class Book(schedule: Schedule, bettors: Map[Long, Bettor], bets: List[Bet], offers: Map[Long, Offer]) {

  def addBettor(p: Bettor): Either[Throwable, Book] = {
    if (bettors.contains(p.id)) {
      Left(new RuntimeException("Bettor with id " + p.id + " exists already"))
    } else {
      Right(copy(bettors = bettors + (p.id -> p)))
    }
  }

  def addTeam(t: Team): Either[Throwable, Book] = {
    schedule.addTeam(t) match {
      case Left(x) => Left(x)
      case Right(s) => Right(copy(schedule = s))
    }
  }

  def addGame(g: Game): Either[Throwable, Book] = {
    schedule.addGame(g) match {
      case Left(x) => Left(x)
      case Right(s) => Right(copy(schedule = s))
    }
  }

  def offerBet(o: Offer): Either[Throwable, Book] = {
    if (!bettors.contains(o.bettorId)) {
      Left(new IllegalArgumentException("Bettor " + o.bettorId + " does not exist"))
    } else if (!schedule.games.contains(o.gameId)) {
      Left(new IllegalArgumentException("Game " + o.gameId + " does not exist"))
    } else if (o.amount <= 0) {
      Left(new IllegalArgumentException("Invalid amount " + o.amount))
    } else {
      if (o.timestamp.isAfter(schedule.games(o.gameId).date)) {
        Left(new RuntimeException("Bet occurred after start time of game)"))
      } else {
        Right(processOffer(o))
      }
    }
  }

  def processOffer(o: Offer): Book = copy(offers=offers+(o.id->o)).matchBook(o.gameId)

  def matchBook(g:Long): Book = {
    val (thisGame, otherGames)= offers.partition(_._2.gameId == g)
    val sides: Map[HomeAway, Iterable[Offer]] = thisGame.values.groupBy(_.ha)
    val home = sides(Home).toList.sorted
    val away = sides(Away).toList.sorted
    this
  }

  def processResult(gameId: Long, result: Result): Either[Throwable, Book] = ???

  def sweepOffers(timestamp: DateTime): Either[Throwable, Book] = {
    val (activeOffers, expiredOfferes) = offers.partition(o => schedule.games(o._2.gameId).date.isAfter(timestamp))
    Right(copy(offers = activeOffers))
  }

}

object Runner {
  private var teamId = 0L
  private var gameId = 0L
  private var book = Book(Schedule(Map(), Map()), Map(), List(), Map())

  def main(args: Array[String]) {

    val g = createTeam("Georgetown").get
    val v = createTeam("Villanova").get

    val m = createGame(new DateTime("2015-12-31T22:00"), g, v).get
    val n = createGame(new DateTime("2016-02-05T14:00"), v, g).get
    println(g)
    println(v)
    println(m)
    println(n)
  }

  private def createTeam(name: String): Option[Team] = {
    teamId = teamId + 1
    val team: Team = Team(teamId, name)
    book.addTeam(team) match {
      case Left(x) =>
        println(x);
        None
      case Right(b) =>
        book = b;
        Some(team)
    }
  }

  private def createGame(date: DateTime, ht: Team, at: Team): Option[Game] = {
    gameId = gameId + 1
    val game: Game = Game(gameId, date, ht, at, None)
    book.addGame(game) match {
      case Left(x) =>
        println(x);
        None
      case Right(b) =>
        book = b;
        Some(game)
    }
  }

}
fijimf commented 9 years ago
package com.fijimf.deepfij

import org.joda.time.DateTime

import scala.collection.{SortedMap, SortedSet}

sealed trait Side extends Ordered[Side] {
  override def compare(that: Side): Int = ordinal.compare(that.ordinal)
  def ordinal:Int
}

case object Buy extends Side {
  override def ordinal: Int = 1
}

case object Sell extends Side {
  override def ordinal: Int = 2
}

case class LimitOrder(customer: Long, side: Side, price: Int, size: Int, timestamp: DateTime) extends Ordered[LimitOrder] {

  override def toString: String = customer+" "+side+" "+size+" @ "+price+" ["+timestamp.toString("HH:MM:ss.SSS")+"]"

  override def compare(that: LimitOrder): Int = {
    import scala.math.Ordered.orderingToOrdered
    (this.side, this.price, this.timestamp.getMillis, this.size, this.customer).compare((that.side, that.price, that.timestamp.getMillis, that.size, that.customer))
  }
}

case class Execution(buyer: Long, seller: Long, price: Int, amount: Int)

case class LimitOrderBook(bids: SortedMap[Int, SortedSet[LimitOrder]], asks: SortedMap[Int, SortedSet[LimitOrder]]) {

  override def toString: String = "Bids\n----\n"+formatBookSide(bids)+ "\nAsks\n----\n"+formatBookSide(asks)

  def formatBookSide(side: SortedMap[Int, SortedSet[LimitOrder]] ): String = {
    side.map((t: (Int, SortedSet[LimitOrder])) => t._1+"\n"+t._2.map("\t"+_).mkString("\n") ).mkString("\n")
  }

  def bestBid: Option[Int] = bids.keySet.lastOption

  def bestAsk: Option[Int] = asks.keySet.headOption

  def currentMarket(): (Option[Int], Option[Int]) = (bestBid, bestAsk)

  def placeOrder(o: LimitOrder): (LimitOrderBook, List[Execution]) = {
    o.side match {
      case Buy =>
        bestAsk match {
          case Some(a) =>
            if (o.price >= a) {

              (enqueueOrder(o), Nil)

            } else {
              (enqueueOrder(o), Nil)
            }

          case None => (enqueueOrder(o), Nil)
        }
      case Sell =>
        bestBid match {
          case Some(a) =>
            if (o.price <= a) {
              (enqueueOrder(o), Nil)
            } else {
              (enqueueOrder(o), Nil)
            }

          case None => (enqueueOrder(o), Nil)
        }
    }
  }

  def enqueueOrder(o: LimitOrder): LimitOrderBook = {
    o.side match {
      case Buy => copy(bids = bids + (o.price -> (bids.getOrElse(o.price, SortedSet.empty[LimitOrder]) + o)))
      case Sell => copy(asks = asks + (o.price -> (asks.getOrElse(o.price, SortedSet.empty[LimitOrder]) + o)))
    }
  }
}

object Runner2 {
  def main(args: Array[String]) {
     var lim = LimitOrderBook(SortedMap.empty[Int,SortedSet[LimitOrder]],SortedMap.empty[Int,SortedSet[LimitOrder]])

    println (lim.currentMarket())
    lim = lim.placeOrder(LimitOrder(1L,Buy, 100,100, new DateTime()))._1
    lim = lim.placeOrder(LimitOrder(1L,Sell, 110,100, new DateTime()))._1
    println (lim.currentMarket())
    lim = lim.placeOrder(LimitOrder(1L,Buy, 95,200, new DateTime()))._1
    lim = lim.placeOrder(LimitOrder(2L,Buy, 95,200, new DateTime()))._1
    lim = lim.placeOrder(LimitOrder(7L,Buy, 95,75, new DateTime()))._1
    println (lim.currentMarket())
    lim = lim.placeOrder(LimitOrder(1L,Buy, 105,200, new DateTime()))._1
    println (lim.currentMarket())

    println (lim)
  }
}
fijimf commented 9 years ago
package com.fijimf.deepfij

import org.joda.time.DateTime

import scala.collection.SortedSet

sealed trait Side extends Ordered[Side] {
  override def compare(that: Side): Int = ordinal.compare(that.ordinal)

  def ordinal: Int
}

case object Buy extends Side {
  override def ordinal: Int = 1
}

case object Sell extends Side {
  override def ordinal: Int = 2
}

case class LimitOrder(customer: Long, side: Side, price: Int, size: Int, timestamp: DateTime) extends Ordered[LimitOrder] {

  override def toString: String = customer + " " + side + " " + size + " @ " + price + " [" + timestamp.toString("HH:MM:ss.SSS") + "]"

  override def compare(that: LimitOrder): Int = {
    import scala.math.Ordered.orderingToOrdered
    (this.side, this.price, this.timestamp.getMillis, this.size, this.customer).compare((that.side, that.price, that.timestamp.getMillis, that.size, that.customer))
  }
}

case class Execution(buyer: Long, seller: Long, price: Int, amount: Int)

case class LimitOrderBook(bids: SortedSet[LimitOrder], asks: SortedSet[LimitOrder]) {

  override def toString: String = "Bids\n----\n" + formatBookSide(bids) + "\nAsks\n----\n" + formatBookSide(asks)

  def formatBookSide(side: SortedSet[LimitOrder]): String = {
    side.toList.map("\t" + _).mkString("\n")
  }

  def bestBid: Option[Int] = bids.lastOption.map(_.price)

  def bestAsk: Option[Int] = asks.headOption.map(_.price)

  def currentMarket(): (Option[Int], Option[Int]) = (bestBid, bestAsk)

  def executeBuyOrder(o: Option[LimitOrder], os: SortedSet[LimitOrder], es: List[Execution]): (Option[LimitOrder], SortedSet[LimitOrder], List[Execution]) = {
    o match {
      case Some(p) => {
        os.headOption match {
          case Some(q) => {
            if (p.size == q.size) {
              (None, os.tail, Execution(p.customer, q.customer, q.price, q.size) :: es)
            } else if (p.size > q.size) {
              executeBuyOrder(Some(p.copy(size = p.size - q.size)), os.tail, Execution(p.customer, q.customer, q.price, q.size) :: es)
            } else {
              (None, os.tail + q.copy(size = q.size - p.size), Execution(p.customer, q.customer, q.price, p.size) :: es)
            }
          }
          case None => (Some(p), os, es)
        }
      }
      case None => (None, os, es)
    }
  }

  def executeSellOrder(o: Option[LimitOrder], os: SortedSet[LimitOrder], es: List[Execution]): (Option[LimitOrder], SortedSet[LimitOrder], List[Execution]) = {
    o match {
      case Some(p) => {
        os.headOption match {
          case Some(q) => {
            if (p.size == q.size) {
              (None, os.tail, Execution(q.customer, p.customer, q.price, q.size) :: es)
            } else if (p.size > q.size) {
              executeBuyOrder(Some(p.copy(size = p.size - q.size)), os.tail, Execution(q.customer, p.customer, q.price, q.size) :: es)
            } else {
              (None, os.tail + q.copy(size = q.size - p.size), Execution(q.customer, p.customer, q.price, p.size) :: es)
            }
          }
          case None => (Some(p), os, es)
        }
      }
      case None => (None, os, es)
    }
  }

  def placeOrder(o: LimitOrder): (LimitOrderBook, List[Execution]) = {
    o.side match {
      case Buy =>
        val (matched, unmatched) = asks.partition(_.price <= o.price)
        val (p, os, es) = executeBuyOrder(Some(o), matched, List.empty[Execution])
        p match {
          case Some(p1) => (copy(bids = bids + p1, asks = unmatched ++ os), es)
          case None => (copy(asks = unmatched ++ os), es)
        }
      case Sell =>
        val (matched, unmatched) = bids.partition(_.price >= o.price)
        val (p, os, es) = executeSellOrder(Some(o), matched, List.empty[Execution])
        p match {
          case Some(p1) => (copy(asks = asks + p1, bids = unmatched ++ os), es)
          case None => (copy(bids = unmatched ++ os), es)
        }
    }
  }
}

object Runner2 {
  def main(args: Array[String]) {
    var lim = LimitOrderBook(SortedSet.empty[LimitOrder], SortedSet.empty[LimitOrder])
    var es: List[Execution] = Nil
    println(lim.currentMarket() + " : " + es)
    var tup = lim.placeOrder(LimitOrder(1L, Buy, 100, 100, new DateTime()))
    lim = tup._1
    println(tup._2)
    tup = lim.placeOrder(LimitOrder(1L, Sell, 110, 100, new DateTime()))
    lim = tup._1
    println(tup._2)
    println(lim.currentMarket() + " : " + es)
    tup = lim.placeOrder(LimitOrder(1L, Buy, 95, 200, new DateTime()))
    lim = tup._1
    tup = lim.placeOrder(LimitOrder(2L, Buy, 95, 200, new DateTime()))
    lim = tup._1
    tup = lim.placeOrder(LimitOrder(7L, Buy, 95, 75, new DateTime()))
    println(tup._2)
    lim = tup._1
    println(lim.currentMarket() + " : " + es)
    tup = lim.placeOrder(LimitOrder(1L, Buy, 105, 200, new DateTime()))
    lim = tup._1
    println(lim.currentMarket() + " : " + es)
    println(tup._2)
    println(lim)

    tup = lim.placeOrder(LimitOrder(1L, Sell, 105, 100, new DateTime()))
    println(tup._1)
    println(tup._2)
  }
}