Bitcoin Forum
May 10, 2024, 07:57:08 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 2 3 4 5 6 7 8 9 10 [11]  All
  Print  
Author Topic: Tagebuch eines Bot Entwicklers  (Read 16827 times)
FreeBit
Member
**
Offline Offline

Activity: 106
Merit: 10


View Profile
January 20, 2015, 10:01:02 PM
 #201

Nächstes Beispiel.

Die Werte des Währungspaars fasse ich in einer Klasse zusammen:

Code:

/* base/counter currency pair class and its companion object */
object BCPair extends XMLTools {
  def apply(b: Double, c: Double) = new BCPair(b, c)
  def apply(bcp: BCPair) = new BCPair(bcp.b, bcp.c)
  def apply() = new BCPair()
  def apply(xml: Elem) = new BCPair( b = tDbl(xml \ "base"),
                                     c = tDbl(xml \ "counter"))
  val zero = BCPair(0, 0)
  val error = BCPair(-1, -1)
}

class BCPair (var b: Double = 0, var c: Double = 0) {

  /* data manipulation */
  def set(in: (Double, Double)) {b = in._1; c = in._2}
  def set(bcp: BCPair) {b = bcp.b; c = bcp.c}
  def set(bb: Double, cc: Double) {b = bb; c = cc}


  /* abs, rounding*/
  def abs = BCPair(scala.math.abs(b), scala.math.abs(c))
  def rnd(decs: DecSet) = BCPair( b = decs.rndBase(b),
                                  c = decs.rndCntr(c) )


  /* check conditions */
  def cndAND (f: Double => Boolean) = f(b) && f(c)
  def cndOR (f: Double => Boolean) = f(b) || f(c)


  /* standard operators */
  def + (that: BCPair) = new BCPair(this.b + that.b, this.c + that.c)
  def - (that: BCPair) = new BCPair(this.b - that.b, this.c - that.c)
  def * (d: Double) = new BCPair(this.b * d, this.c * d)
  def / (d: Double) = new BCPair(this.b / d, this.c / d)
  def isEqual (that: BCPair) = this.b == that.b && this.c == that.c

  /* calc the rate: i * r = c  <=> r = c / i */
  def calcRate = if (b != 0) scala.math.abs(c / b) else -1D


  /* delivers min/max values of both entries */
  def mergeMax(that: BCPair) = BCPair( b = tools.max(b, that.b),
                                       c = tools.max(c, that.c) )

  def mergeMinPos(that: BCPair) = {
    def oz(x: Double, y: Double) = (x > 0, y > 0) match {
      case (true, true) => tools.min(x, y)
      case (false, true) => y
      case (true, false) => x
      case (false, false) => 0D }
    BCPair(b = oz(b, that.b), c = oz(c, that.c)) }


  /* formatted output */
  def print = "base:" + b + " cntr:" + c

  def toStr( bcu: BCUnits, decB: Int, decC: Int) =
      fmtAmt(b, bcu.b, decB) + " | " + fmtAmt(c, bcu.c, decC)

  def toStr( bcu: BCUnits, fmtB: Double => String, fmtC: Double => String) =
      fmtAmt(b, bcu.b, fmtB) + " | " + fmtAmt(c, bcu.c, fmtC)

  def toStr(decs: Decimals, units: BCUnits): String =
      toStr(bcu = units, decB = decs.decBase, decC = decs.decCntr)

  def toStr(decs: DecSet, units: BCUnits): String =
      toStr(bcu = units, decB = decs.decBase, decC = decs.decCntr)


  /* XML output */
  def toXML = fXML(b.toString, c.toString)
  def toXML(decs: DecSet) = fXML(decs.fmtBase(b), decs.fmtCntr(c))
  private def fXML(sb: String, sc: String) =
              <bcpair><base>{sb}</base><counter>{sc}</counter></bcpair>


  /* helper functions */
  private def cLen(s: String) = {if (s.indexOf("-") < 0) 1 else 0} + s.length

  private def fmtAmt(v: Double, unit: String, fmt: Double => String) = {
    val s = fmt(v)
    tools.pst( cLen(s), s) + " " + unit }

  private def fmtAmt(v: Double, unit: String, dec: Int) = {
    val s = tools.format(v, dec)
    tools.pst( cLen(s), s) + " " + unit }
}



Auch etwas länglich, aber ich kann jetzt ...

Code:

  // ... hiermit beispielsweise zwei Handelergebnisse aufsummieren.
  val a = BCPair(b = 1, c = 100)
  val b = BCPair(2, -30)
  val c = a + b // wäre hier BCPair(3, 70)

  // und mit der toStr-Methode ins Logfile schreiben
  log.trade("trade result -> " + c.toStr(decs.calc, ...)

  // oder testen, ob beide werte positiv sind
  if (c.cndAND (v => v > 0)) { ... }



Das erspart auch Arbeit bei der Deklaration von Klassen, beispielsweise einer Klasse, die die Handelsresultate aufnimmt:

Code:

/* the IFExTradeData class itself */
case class IFExTradeData ( dbid: Int,
                           typ: TTrdDir.TTrdDir,
                           bcu: BCUnits,
                           timestamp: Long,
                           tradeid: Long,
                           orderid: Long,
                           resultWOF: BCPair,
                           resultWF: BCPair,
                           fees: BCPair,
                           rateWOF: Double,
                           rateWF: Double)  extends IFExDataBase(dbid) {

  /* for error messages */
  override val errorClassName = "IFExTradeData"

  /* check on equality */
  def isEqual(that: IFExTradeData) = dbid == that.dbid &&
                                     typ == that.typ &&
                                     bcu == that.bcu &&
                                     timestamp == that.timestamp &&
                                     tradeid == that.tradeid &&
                                     orderid == that.orderid &&
                                     resultWOF.isEqual(that.resultWOF) &&
                                     resultWF.isEqual(that.resultWF) &&
                                     fees.isEqual(that.fees) &&
                                     rateWOF == that.rateWOF &&
                                     rateWF == that.rateWF

  /* type to string */
  def typStr = TTrdDir.toStr(typ)

  /* delivers a copy with setting of a changed database id */
  def copyWithDBID(id: Int) = copy(dbid = id)

  /* build log string */
  def toLog( indent: String, decs: DecSet) = {

    def strBCP(bcp: BCPair) =
      bcp.toStr( bcu, decs.fmtBase _, decs.fmtCntr _)

    List( "TRADEDATA",
          indent + "typ          :   " + typStr.toUpperCase,
          indent + "orderid      :   " + orderid,
          indent + "tradeid      :   " + tradeid,
          indent + "timestamp    :   " + tools.dateToString(timestamp),
          indent + "res w/o fee  :  " + strBCP(resultWOF),
          indent + "res w fee    :  " + strBCP(resultWF),
          indent + "fees         :  " + strBCP(fees),
          indent + "rate w/o fee : " + fmtValue(rateWOF, decs.fmtRate),
          indent + "rate w fee   : " + fmtValue(rateWF, decs.fmtRate)).mkString("\n") }




  /* creates a name/value map for database storing */
  override def dbValues(tableName: String, secID: Int) =
    Map( ("TableName", tableName),
         ("PrimaryKeyName", pkName),
         ("PrimaryKeyValue", dbid),
         ("secid", secID),
         ("typ", typStr),
         ("base", bcu.b),
         ("cntr", bcu.c),
         ("timestamp", timestamp),
         ("tradeid", tradeid),
         ("orderid", orderid),
         ("ratewof", rateWOF),
         ("ratewf", rateWF)) ++
         mapBCP("resultwof", resultWOF) ++
         mapBCP("resultwf", resultWF) ++
         mapBCP("fees", fees)

  /* stores to database, only if not exists */
  override def store(db: Database, table: String, secID: Int) =

    /* checks if dataset already exists */
    db.selectFromDB( table, "where tradeid=" + tradeid, "") match {

      /* dataset retrieved --> no action */
      case rs: ResultSet if rs.next() => rs.close()

      /* no dataset found --> store */
      case rs: ResultSet => super.store(db, table, secID); rs.close()
      case _ => super.store(db, table, secID) }


}



Wieder alles etwas länglich, aber sehr nützlich für die einheitliche Behandlung der Daten von verschiedenen Exchanges.
Pages: « 1 2 3 4 5 6 7 8 9 10 [11]  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!