/src/main/scala/com.coinmachine.ares/trade/future/FutureWaveCutter.scala
Scala | 199 lines | 163 code | 26 blank | 10 comment | 41 complexity | 441020f97fa7edba42be20bfe542f40c MD5 | raw file
- package com.coinmachine.ares.trade.future
- import com.alibaba.fastjson.{JSONObject, JSON}
- import com.coinmachine.ares.Logging
- import com.coinmachine.ares.trade.{Exchange, Order, Strategy, UserInfo}
- import com.coinmachine.ares.util.{StrategyUtil, MathUtil, LoopQuery}
- import org.apache.commons._
- import scala.collection.mutable
- /**
- * Created by bobo on 16/4/5.
- */
- class FutureWaveCutter(val user: UserInfo, val coinType: String = "ltc", val orderDistance: Float = 0.005f,
- val tradeUnit: Float = 1, val stopRiskRate: Float = 10,
- val stopPrice: Float = 5, val contractTypes: String = "this_week,next_week,quarter") extends Strategy with Logging {
- val upPlace = new mutable.Stack[Order]()
- val downPlace = new mutable.Stack[Order]()
- val symbol = coinType + "_usd"
- logInfo(toString)
- class RiskController extends Logging with Runnable {
- override def run(): Unit = {
- while(!shutDownFlag) {
- val userInfo = LoopQuery.futureUserInfo(user);
- val marketUserInfo = userInfo.getJSONObject(coinType)
- val accountRights = marketUserInfo.getFloat("account_rights")
- val keepDeposit = marketUserInfo.getFloat("keep_deposit")
- val profitReal = marketUserInfo.getFloat("profit_real")
- val profitUnreal = marketUserInfo.getFloat("profit_unreal")
- val riskRate = marketUserInfo.getFloat("risk_rate")
- logDebug(s"Account rights:$accountRights, KeepDeposit:$keepDeposit, ProfitReal:$profitReal, ProfitUnreal:$profitUnreal, RiskRate:$riskRate")
- if (riskRate < stopRiskRate) {
- logWarn(s"riskRate($riskRate) < stopRiskRate($stopRiskRate)")
- shutDownFlag = true
- System.exit(-1)
- } else {
- logDebug(s"riskRate($riskRate) >= stopRiskRate($stopRiskRate)")
- }
- // contractTypes.split(",").foreach(ct => {
- // val futurePosition = LoopQuery.futurePosition(user, coinType + "_" + "usd", ct)
- // val forceLiquPrice = futurePosition.getFloat("force_liqu_price")
- // if (forceLiquPrice < stopPrice) {
- // logWarn("")
- // }
- // })
- Thread.sleep(100)
- }
- }
- }
- override def init(): Unit = {
- new Thread(new RiskController).start()
- Thread.sleep(2000)
- val ticker = LoopQuery.futureTicker(user, symbol, "quarter")
- val lastPrice = ticker.getFloat("last")
- logInfo(s"Ticker:$ticker")
- placeUpDownOrders(upPlace, downPlace, lastPrice)
- }
- def placeUpDownOrders(upPlace: mutable.Stack[Order], downPlace: mutable.Stack[Order], price: Float): Unit = {
- val downOrderPrice = ((math floor (price - orderDistance) * 1000) / 1000).toFloat
- if (!downPlace.exists(o => o.price == downOrderPrice)) {
- val orderId = LoopQuery.placeFutureOrder(user, symbol, "quarter", downOrderPrice, tradeUnit, "4")
- downPlace.push(new Order(orderId, downOrderPrice))
- Thread.sleep(20L)
- logInfo(s"Place an close_short order:$orderId with price:$downOrderPrice and amount:$tradeUnit")
- } else {
- logInfo(s"Already placed an close_short order with price:" + downOrderPrice)
- }
- val upOrderPrice = ((math floor (price + orderDistance) * 1000) / 1000).toFloat
- if (!upPlace.exists(o => o.price == upOrderPrice)) {
- val orderId = LoopQuery.placeFutureOrder(user, coinType + "_usd", "quarter", upOrderPrice, tradeUnit, "2")
- upPlace.push(new Order(orderId, upOrderPrice))
- Thread.sleep(20L)
- logInfo(s"Place an short order:$orderId with price:$upOrderPrice and amount:$tradeUnit")
- } else {
- logInfo(s"Already placed an short order with price:" + upOrderPrice)
- }
- }
- def processDeals() = {
- try {
- if (upPlace.nonEmpty) {
- val order = upPlace.top
- logDebug("Top Order of upPlace:" + order)
- val orderInfo = LoopQuery.futureOrderInfo(user, symbol, "quarter", order.id)
- Option(orderInfo.getIntValue("status")) match {
- case Some(oi) =>
- Option(orderInfo.getIntValue("status")) match {
- case Some(x) if x == -1 => //already canceled,被人工取消了理应再放一次
- upPlace.pop()
- case Some(x) if x == 2 => //totally concluded
- upPlace.pop()
- val price = orderInfo.getFloatValue("price")
- placeUpDownOrders(upPlace, downPlace, price)
- case _ =>
- }
- case None =>
- logError(s"Can't get order info for $order")
- }
- } else {
- logWarn(s"upPlace is empty.$upPlace")
- }
- if (downPlace.nonEmpty) {
- val order = downPlace.top
- val orderInfo = LoopQuery.futureOrderInfo(user, symbol, "quarter", order.id)
- Option(orderInfo) match {
- case Some(oi) =>
- Option(orderInfo.getIntValue("status")) match {
- case Some(x) if x == -1 =>
- downPlace.pop()
- case Some(x) if x == 2 =>
- downPlace.pop()
- val price = orderInfo.getFloatValue("price")
- placeUpDownOrders(upPlace, downPlace, price)
- case _ =>
- }
- case None =>
- logError(s"Can't get order info for $order")
- }
- } else {
- logWarn(s"downPlace is empty:$downPlace")
- }
- } catch {
- case e: Exception =>
- logError("Exception when placing order", e)
- }
- Thread.sleep(100)
- }
- override def run(): Unit = {
- init()
- while (!shutDownFlag) {
- processDeals()
- }
- }
- override def toString = s"FutureWaveCutter(symbol=$symbol, coinType=$coinType, orderDistance=$orderDistance, tradeUnit=$tradeUnit, stopRiskRate=$stopRiskRate, stopPrice=$stopPrice, contractTypes=$contractTypes)"
- }
- object FutureWaveCutter extends Logging {
- def main(args: Array[String]) {
- val (userInfo, coinType, distance, unit, srr): (UserInfo, String, Float, Float, Float) = {
- if (args.length > 0) {
- val parser: cli.CommandLineParser = new cli.DefaultParser
- val options: cli.Options = {
- val opts = new cli.Options
- opts.addOption("btc", false, "Trade in BTC Future Market, Other wise LTC Future Market")
- opts.addOption("d", true, "Order distance")
- opts.addOption("unit", true, "TradeUnit")
- opts.addOption("srr", true, "Stop Risk Rate")
- opts.addOption("apikey", true, "API Key")
- opts.addOption("secretkey", true, "Secret Key")
- opts
- }
- try {
- val cmdLine = parser.parse(options, args)
- val coinType: String = if (cmdLine.hasOption("btc")) "btc" else "ltc"
- val distance: Float = if (cmdLine.hasOption("d")) {
- cmdLine.getOptionValue("d").toFloat
- } else if (coinType == "ltc") 0.1f else 1
- val unit: Float = if (cmdLine.hasOption("unit")) cmdLine.getOptionValue("unit").toFloat else if (coinType == "ltc") 1 else 0.1f
- val srr: Float = if (cmdLine.hasOption("srr")) cmdLine.getOptionValue("srr").toFloat else 10.0f
- val apiKey: String = if (cmdLine.hasOption("apikey")) cmdLine.getOptionValue("apikey") else throw new IllegalArgumentException("API key not giving.")
- val secretKey: String = if (cmdLine.hasOption("secretkey")) cmdLine.getOptionValue("secretkey") else throw new IllegalArgumentException("Secret key not giving.")
- (new UserInfo(apiKey, secretKey, Exchange.OKCOINCOM_FUTURE), coinType, distance, unit, srr)
- } catch {
- case e: Exception =>
- logError(s"Error:$e")
- val formatter: cli.HelpFormatter = new cli.HelpFormatter
- formatter.printHelp("FutureWaveCutter", options)
- System.exit(-1)
- (null, "ltc", 0.1f, 0.1f, 100)
- }
- } else {
- StrategyUtil.config()
- }
- }
- val wc = new FutureWaveCutter(userInfo, coinType = coinType, orderDistance = distance, tradeUnit = unit, stopRiskRate = srr)
- new Thread(wc).run()
- }
- }