Beispiel #1
0
func Sell() string {
	if PrevTrade == "sell" {
		return "0"
	}

	// compute the price
	price, _, warning := getSellPrice()

	// compute the amount
	Available_coin := GetAvailable_coin()
	if Available_coin < 0.01 {
		warning = "没有足够的币"
		logger.Infoln(warning)
		PrevTrade = "sell"
		PrevBuyPirce = 0
		return "0"
	}

	amount := Option["tradeAmount"]
	nAmount, err := strconv.ParseFloat(amount, 64)
	if err != nil {
		logger.Infoln("amount is not float")
		return "0"
	}

	if nAmount > Available_coin {
		nAmount = Available_coin
		amount = fmt.Sprintf("%02f", nAmount)
	}

	sellID := sell(price, amount)
	if sellID == "-1" {
		warning += " [模拟]"
	} else if sellID == "0" {
		warning += "[委托失败]"
	} else {
		warning += "[委托成功]" + sellID
	}

	logger.Infoln(warning)

	var coin string
	if Option["symbol"] == "btc_cny" {
		coin = "比特币"
	} else {
		coin = "莱特币"
	}

	if sellID != "0" {
		if !GetBacktest() {
			logger.Tradef("在%s,根据策略%s周期%s,以价格%s卖出%s个%s\n", Option["tradecenter"], Option["strategy"], Option["tick_interval"], price, amount, coin)
			go email.TriggerTrender(warning)
		} else {
			t := time.Unix(GetBtTime(), 0)
			logger.Backtestf("%s 在simulate,根据策略%s周期%s,以价格%s卖出%s个%s\n", t.Format("2006-01-02 15:04:05"), Option["strategy"], Option["tick_interval"], price, amount, coin)
		}
	}

	return sellID
}
Beispiel #2
0
// KDJ-EX strategy
func (kdjex *KDJexStrategy) Tick(records []Record) bool {
	const btcslap = 0.2
	const ltcslap = 0.01
	const timeout = 300 // 秒
	const ordercount = 5

	tradeAmount := Option["tradeAmount"]

	numTradeAmount, err := strconv.ParseFloat(Option["tradeAmount"], 64)
	if err != nil {
		logger.Errorln("config item tradeAmount is not float")
		return false
	}

	var slappage float64
	symbol := Option["symbol"]
	if symbol == "btc_cny" {
		slappage = btcslap
	} else {
		slappage = ltcslap
	}

	var coin string
	if Option["symbol"] == "btc_cny" {
		coin = "比特币"
	} else {
		coin = "莱特币"
	}

	nSplitTradeAmount := numTradeAmount / float64(ordercount)
	splitTradeAmount := fmt.Sprintf("%f", nSplitTradeAmount)

	stoploss, err := strconv.ParseFloat(Option["stoploss"], 64)
	if err != nil {
		logger.Errorln("config item stoploss is not float")
		return false
	}

	var Time []string
	var Price []float64
	var Volumn []float64
	for _, v := range records {
		Time = append(Time, v.TimeStr)
		Price = append(Price, v.Close)
		Volumn = append(Volumn, v.Volumn)
	}

	length := len(records)

	if kdjex.PrevTime == records[length-1].TimeStr &&
		kdjex.PrevPrice == records[length-1].Close {
		return false
	}

	// K线为白,D线为黄,J线为红,K in middle
	k, d, j := getKDJ(records)

	if kdjex.PrevTime != records[length-1].TimeStr ||
		kdjex.PrevPrice != records[length-1].Close {
		kdjex.PrevTime = records[length-1].TimeStr
		kdjex.PrevPrice = records[length-1].Close

		logger.Infoln(records[length-1].TimeStr, records[length-1].Close)
		logger.Infof("d(黄线)%0.0f\tk(白线)%0.0f\tj(红线)%0.0f\n", d[length-2], k[length-2], j[length-2])
		logger.Infof("d(黄线)%0.0f\tk(白线)%0.0f\tj(红线)%0.0f\n", d[length-1], k[length-1], j[length-1])
		if j[length-1] > k[length-1] {
			logger.Infoln("KDJ up trend")
		} else {
			logger.Infoln("KDJ down trend")
		}
	}

	if (j[length-2] < k[length-2] && k[length-2] < d[length-2]) &&
		(j[length-1] > k[length-1] && k[length-1] > d[length-1]) {

		logger.Infoln("----------------->KDJ up cross", kdjex.PrevKDJTrade, d[length-2])

		if kdjex.PrevKDJTrade != "buy" && j[length-2] <= 20 {
			// do buy
			ret, orderbook := GetOrderBook()
			if !ret {
				logger.Infoln("get orderbook failed 1")
				ret, orderbook = GetOrderBook() // try again
				if !ret {
					logger.Infoln("get orderbook failed 2")
					return false
				}
			}

			logger.Infoln("卖一", (orderbook.Asks[len(orderbook.Asks)-1]))
			logger.Infoln("买一", orderbook.Bids[0])

			logger.Infoln("X 两根K线最低价", records[length-2].Low, records[length-1].Low)
			logger.Infoln("X 两根K线最高价", records[length-2].High, records[length-1].High)

			avgLow := (records[length-2].Close + records[length-1].Low) / 2.0
			logger.Infoln("X 两根K线的最低平均价", avgLow)

			warning := "KDJ up cross, 买入buy In<----限价单"
			for i := 1; i <= ordercount; i++ {
				warning := "KDJ up cross, 买入buy In<----限价单"
				tradePrice := fmt.Sprintf("%f", avgLow+slappage*float64(i))
				buyID := buy(tradePrice, splitTradeAmount)
				if buyID != "0" {
					warning += "[委托成功]"
					kdjex.BuyId = append(kdjex.BuyId, buyID)
					if !GetBacktest() {
						logger.Tradef("在%s,根据策略%s周期%s,以价格%s买入%s个%s\n", Option["tradecenter"], Option["strategy"], Option["tick_interval"], tradePrice, splitTradeAmount, coin)
					} else {
						t := time.Unix(GetBtTime(), 0)
						logger.Backtestf("%s 在simulate,根据策略%s周期%s,以价格%s买入%s个%s\n", t.Format("2006-01-02 15:04:05"), Option["strategy"], Option["tick_interval"], tradePrice, splitTradeAmount, coin)
					}
				} else {
					warning += "[委托失败]"
				}

				logger.Infoln(warning)
			}

			kdjex.BuyBegin = time.Now()
			kdjex.PrevKDJTrade = "buy"

			kdjex.PrevBuyPirce = avgLow

			logger.Infoln("------------>>>stoploss price", kdjex.PrevBuyPirce*(1-stoploss*0.01))

			_, ret = GetAccount()
			if !ret {
				logger.Infoln("GetAccount failed")
			}

			SendEmail(warning)
		}
	}

	if (j[length-2] > k[length-2] && k[length-2] > d[length-2]) &&
		(j[length-1] < k[length-1] && k[length-1] < d[length-1]) {

		logger.Infoln("<----------------------KDJ down cross", kdjex.PrevKDJTrade, d[length-2])

		if kdjex.PrevKDJTrade != "sell" && j[length-2] >= 80 {
			// do sell
			ret, orderbook := GetOrderBook()
			if !ret {
				logger.Infoln("get orderbook failed 1")
				ret, orderbook = GetOrderBook() // try again
				if !ret {
					logger.Infoln("get orderbook failed 2")
					return false
				}
			}

			logger.Infoln("卖一", (orderbook.Asks[len(orderbook.Asks)-1]))
			logger.Infoln("买一", orderbook.Bids[0])

			logger.Infoln("X 两根K线最低价", records[length-2].Low, records[length-1].Low)
			logger.Infoln("X 两根K线最高价", records[length-2].High, records[length-1].High)

			avgHigh := (records[length-2].Close + records[length-1].High) / 2.0
			logger.Infoln("X 两根K线的最高平均价", avgHigh)
			warning := "KDJ down cross, 卖出Sell Out---->限价单"

			for i := 1; i <= ordercount; i++ {
				warning := "KDJ down cross, 卖出Sell Out---->限价单"
				tradePrice := fmt.Sprintf("%f", avgHigh-slappage*float64(i))
				sellID := sell(tradePrice, splitTradeAmount)
				if sellID != "0" {
					warning += "[委托成功]"
					kdjex.SellId = append(kdjex.SellId, sellID)
					if !GetBacktest() {
						logger.Tradef("在%s,根据策略%s周期%s,以价格%s卖出%s个%s\n", Option["tradecenter"], Option["strategy"], Option["tick_interval"], tradePrice, splitTradeAmount, coin)
					} else {
						t := time.Unix(GetBtTime(), 0)
						logger.Backtestf("%s 在simulate,根据策略%s周期%s,以价格%s卖出%s个%s\n", t.Format("2006-01-02 15:04:05"), Option["strategy"], Option["tick_interval"], tradePrice, splitTradeAmount, coin)
					}
				} else {
					warning += "[委托失败]"
				}

				logger.Infoln(warning)
			}

			kdjex.SellBegin = time.Now()
			kdjex.PrevKDJTrade = "sell"

			_, ret = GetAccount()
			if !ret {
				logger.Infoln("GetAccount failed")
			}
			SendEmail(warning)
		}
	}

	// do sell when price is below stoploss point

	if Price[length-1] < kdjex.PrevBuyPirce*(1-stoploss*0.01) {
		if Option["disable_trading"] != "1" && kdjex.PrevKDJTrade != "sell" {
			kdjex.PrevKDJTrade = "sell"
			kdjex.PrevBuyPirce = 0
			warning := "!<------------------stop loss, 卖出Sell Out---->市价" + getTradePrice("", Price[length-1]) + ",委托价" + getTradePrice("sell", Price[length-1])
			logger.Infoln(warning)
			tradePrice := getTradePrice("sell", Price[length-1])
			if sell(tradePrice, tradeAmount) != "0" {
				warning += "[委托成功]"
				if !GetBacktest() {
					logger.Tradef("在%s,根据策略%s周期%s,以价格%s卖出%s个%s\n", Option["tradecenter"], Option["strategy"], Option["tick_interval"], tradePrice, tradeAmount, coin)
				} else {
					t := time.Unix(GetBtTime(), 0)
					logger.Backtestf("%s 在simulate,根据策略%s周期%s,以价格%s卖出%s个%s\n", t.Format("2006-01-02 15:04:05"), Option["strategy"], Option["tick_interval"], tradePrice, tradeAmount, coin)
				}
			} else {
				warning += "[委托失败]"
				for i := 1; i <= ordercount; i++ {
					warning := "stop loss, 卖出Sell Out---->限价单"
					tradePrice := getTradePrice("sell", Price[length-1])
					sellID := sell(tradePrice, splitTradeAmount)
					if sellID != "0" {
						warning += "[委托成功]"
						kdjex.SellId = append(kdjex.SellId, sellID)
						if !GetBacktest() {
							logger.Tradef("在%s,根据策略%s周期%s,以价格%s卖出%s个%s\n", Option["tradecenter"], Option["strategy"], Option["tick_interval"], tradePrice, splitTradeAmount, coin)
						} else {
							t := time.Unix(GetBtTime(), 0)
							logger.Backtestf("%s 在simulate,根据策略%s周期%s,以价格%s卖出%s个%s\n", t.Format("2006-01-02 15:04:05"), Option["strategy"], Option["tick_interval"], tradePrice, splitTradeAmount, coin)
						}
					} else {
						warning += "[委托失败]"
					}

					logger.Infoln(warning)
				}
			}

			kdjex.SellBegin = time.Now()
			kdjex.PrevKDJTrade = "sell"

			_, ret := GetAccount()
			if !ret {
				logger.Infoln("GetAccount failed")
			}
			SendEmail(warning)
		}
	}

	// check timeout trade
	now := time.Now()

	logger.Infoln("time go ", int64(now.Sub(kdjex.BuyBegin)/time.Second))
	logger.Infoln("BuyId len", len(kdjex.BuyId), cap(kdjex.BuyId))
	logger.Infoln("SellId len", len(kdjex.SellId), cap(kdjex.SellId))

	if len(kdjex.BuyId) != 0 &&
		int64(now.Sub(kdjex.BuyBegin)/time.Second) > timeout {
		// todo
		for _, BuyId := range kdjex.BuyId {
			warning := "<--------------buy order timeout, cancel-------------->" + BuyId
			if CancelOrder(BuyId) {
				warning += "[Cancel委托成功]"
			} else {
				warning += "[Cancel委托失败]"
			}
			logger.Infoln(warning)
			time.Sleep(1 * time.Second)
			time.Sleep(500 * time.Microsecond)
		}
		kdjex.BuyId = kdjex.BuyId[:0]
	}

	if len(kdjex.SellId) != 0 &&
		int64(now.Sub(kdjex.SellBegin)/time.Second) > timeout {
		// todo
		for _, SellId := range kdjex.SellId {
			warning := "<--------------sell order timeout, cancel------------->" + SellId
			if CancelOrder(SellId) {
				warning += "[Cancel委托成功]"
			} else {
				warning += "[Cancel委托失败]"
			}
			logger.Infoln(warning)
			time.Sleep(1 * time.Second)
			time.Sleep(500 * time.Microsecond)
		}
		kdjex.SellId = kdjex.SellId[:0]
	}

	return true
}
Beispiel #3
0
func Buy() string {
	if PrevTrade == "buy" {
		return "0"
	}

	// init
	isStoploss = false

	// compute the price
	price, nPrice, warning := getBuyPrice()

	// compute the amount
	amount := Option["tradeAmount"]
	nAmount, err := strconv.ParseFloat(amount, 64)
	if err != nil {
		logger.Infoln("amount is not float")
		return "0"
	}

	Available_cny := GetAvailable_cny()
	if Available_cny < nPrice*nAmount {
		var nMinTradeAmount float64
		nAmount = Available_cny / nPrice
		symbol := Option["symbol"]
		if symbol == "btc_cny" {
			nMinTradeAmount = 0.1
		} else {
			nMinTradeAmount = 0.01
		}
		if nAmount < nMinTradeAmount {
			warning += "没有足够的法币余额"
			logger.Infoln(warning)
			PrevTrade = "buy"
			PrevBuyPirce = nPrice
			return "0"
		}

		amount = fmt.Sprintf("%02f", nAmount)
	}

	warning += "---->数量" + amount

	buyID := buy(price, amount)
	if buyID == "-1" {
		warning += " [模拟]"
	} else if buyID == "0" {
		warning += "[委托失败]"
	} else {
		warning += "[委托成功]" + buyID
	}

	logger.Infoln(warning)

	var coin string
	if Option["symbol"] == "btc_cny" {
		coin = "比特币"
	} else {
		coin = "莱特币"
	}

	if buyID != "0" {
		if !GetBacktest() {
			logger.Tradef("在%s,根据策略%s周期%s,以价格%s买入%s个%s\n", Option["tradecenter"], Option["strategy"], Option["tick_interval"], price, amount, coin)
			go email.TriggerTrender(warning)
		} else {
			t := time.Unix(GetBtTime(), 0)
			logger.Backtestf("%s 在simulate,根据策略%s周期%s,以价格%s买入%s个%s\n", t.Format("2006-01-02 15:04:05"), Option["strategy"], Option["tick_interval"], price, amount, coin)
		}
	}

	return buyID
}