/// <summary> /// Execute get market info /// </summary> public void ExecGetMarketInfo() { while (true) { try { dragonExApiForA.UpdateTradeDepth(ConfigTool.CurrentPair.Value); this.Invoke(new ResetTradeDepth(ResetCurrentDepth), new object[] { dragonExApiForA.Tde }); this.Invoke(new ResetUI(UpdateCurrentUI), new object[] { }); } catch (ThreadAbortException) { //Do nothing when aborting thread } catch (Exception ex) { //Error happened when getting var logMsg = "Exception happened when getting Ticker.Details:" + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace; Console.WriteLine(logMsg); LogTool.LogTradeInfo(logMsg, LogLevels.ERROR); } Thread.Sleep(1000); } }
/// <summary> /// Check order succeed /// </summary> /// <param name="orderId">Order Id</param> /// <returns>If succeed:true, else false.</returns> public bool CheckOrderSucceed(string orderId) { try { if (ConfigTool.RunMode == RunMode.TEST) { return(true); } else { var data = privateApiInstance.GetOrderDetail(ConfigTool.CurrentPair.Value, orderId); var receivedValue = data.Element("data").Element("status").Value; //1:UNFILLED,2:FILLED,3:CANCELED if (!string.IsNullOrEmpty(receivedValue) && string.Equals(receivedValue.ToUpper(), "2")) { return(true); } else { var logMsg = "Error happened when check dragonex trading succeed.The result is:" + data.ToString(); LogTool.LogTradeInfo(logMsg, LogLevels.ERROR); } } } catch (Exception ex) { var logMsg = "Exception happened when check dragonex trading succeed:" + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace; LogTool.LogTradeInfo(logMsg, LogLevels.ERROR); } return(false); }
/// <summary> /// Get user info /// </summary> public void GetUserInfo() { try { dragonExApiForA.UpdateUserInfo(pairChanged); dragonExApiForB.UpdateUserInfo(pairChanged); pairChanged = false; this.Invoke(new ResetUI(ResetCurrentUserInfos), new object[] { }); } catch (ThreadAbortException) { //Do nothing when aborting thread } catch (Exception ex) { //Error happened when getting var logMsg = "Exception happened when getting User Infos.Details:" + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace; Console.WriteLine(logMsg); LogTool.LogTradeInfo(logMsg, LogLevels.ERROR); } }
/// <summary> /// Cancel order /// </summary> /// <param name="orderId"></param> /// <returns></returns> public bool CancelOrder(string orderId) { try { if (ConfigTool.RunMode == RunMode.TEST) { if (TestConfigTool.CancelAOrderFailed && name == AccountSide.A) { return(false); } else if (TestConfigTool.CancelBOrderFailed && name == AccountSide.B) { return(false); } return(true); } XElement data = privateApiInstance.CancelOrder(ConfigTool.CurrentPair.Value, orderId); var id = data.Element("data").Element("order_id"); if (id != null && !string.IsNullOrEmpty(id.Value)) { return(true); } else { return(false); } } catch (Exception ex) { // If any error happened when Trading, out error log var logMsg = "Exception happened when cancel trading in dragonex.Exception:" + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace + Environment.NewLine; LogTool.LogTradeInfo(logMsg, LogLevels.ERROR); return(false); } }
/// <summary> /// Get trade Depth /// </summary> /// <returns></returns> public TradeDepthEntity GetTradeDepth(int symbolId) { try { var buyResult = DragonExPublicApis.Instance.GetMarketBuy(symbolId); var sellResult = DragonExPublicApis.Instance.GetMarketSell(symbolId); TradeDepthEntity tde = new TradeDepthEntity(); tde.TradeName = Constants.TRADE_NAME_DRAGON_EX; tde.AsksList = new List <AskBidEntity>(); tde.BidsList = new List <AskBidEntity>(); var bidsNodes = buyResult.Elements("data"); var asksNodes = sellResult.Elements("data"); AskBidEntity tempItem; int getRow = Constants.DEPTH_DISPLAY_ROW - 1; if (asksNodes.Count() < Constants.DEPTH_DISPLAY_ROW) { getRow = asksNodes.Count() - 1; } for (int i = getRow; i >= 0; i--) { var asksItem = asksNodes.ElementAt(i); tempItem = new AskBidEntity(); tempItem.No = i + 1; tempItem.Price = decimal.Parse(CommonUtils.GetAskBidElementValue(asksItem.FirstNode)); tempItem.Amount = decimal.Parse(CommonUtils.GetAskBidElementValue(asksItem.LastNode)); tde.AsksList.Add(tempItem); } tde.MinAsk = tde.AsksList[getRow]; tde.MinSecAsk = tde.AsksList[getRow - 1]; tde.MinThdAsk = tde.AsksList[getRow - 2]; getRow = Constants.DEPTH_DISPLAY_ROW - 1; if (bidsNodes.Count() < Constants.DEPTH_DISPLAY_ROW) { getRow = bidsNodes.Count() - 1; } for (int i = 0; i <= getRow; i++) { var bidsItem = bidsNodes.ElementAt(i); tempItem = new AskBidEntity(); tempItem.No = i + 1; tempItem.Price = decimal.Parse(CommonUtils.GetAskBidElementValue(bidsItem.FirstNode)); tempItem.Amount = decimal.Parse(CommonUtils.GetAskBidElementValue(bidsItem.LastNode)); tde.BidsList.Add(tempItem); } tde.MaxBid = tde.BidsList[0]; tde.MaxSecBid = tde.BidsList[1]; tde.MaxThdBid = tde.BidsList[2]; return(tde); } catch (Exception ex) { // If any error happened when Trading, out error log var logMsg = "Exception happened when getting market info in dragonex.Exception:" + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace + Environment.NewLine; LogTool.LogTradeInfo(logMsg, LogLevels.ERROR); } return(null); }
/// <summary> /// Trade /// </summary> /// <param name="symbolId">Symbol id</param> /// <param name="side">buy or sell</param> /// <param name="price">Base Price</param> /// <param name="amount">Amount</param> /// <param name="retryCount">Retry count when failed</param> /// <returns>Trade entity</returns> private TradeEntity Trade(int symbolId, TradeTypes side, decimal price, decimal amount, int retryCount = 1) { if (retryCount > ConfigTool.TradeFailedRetryCount) { // If retry ended, return return(null); } TradeEntity te = new TradeEntity(); bool isSucceeded = false; try { if (ConfigTool.RunMode == RunMode.TEST) { if (side == TradeTypes.BUY && TestConfigTool.TradeBaseToCoinFailed) { return(null); } else if (side == TradeTypes.SELL && TestConfigTool.TradeCoinToBaseFailed) { return(null); } else { // If test var receivedValue = amount.ToString(); var remainsValue = amount.ToString(); var orderId = "1"; var receivedD = (decimal)double.Parse(receivedValue); var remainsD = (decimal)double.Parse(remainsValue); te.Received = receivedD; te.Remains = remainsD; te.OrderId = orderId; isSucceeded = true; } } else { XElement data = null; if (side == TradeTypes.BUY) { //Try to buy data = privateApiInstance.BuyOrder(symbolId, price.ToString(), amount.ToString()); } else { //Try to sell data = privateApiInstance.SellOrder(symbolId, price.ToString(), amount.ToString()); } var id = data.Element("data").Element("order_id"); if (id != null && !string.IsNullOrEmpty(id.Value)) { // If id is returned var receivedValue = data.Element("data").Element("trade_volume").Value; var remainsValue = data.Element("data").Element("volume").Value; var orderId = id.Value; var receivedD = (decimal)double.Parse(receivedValue); var remainsD = (decimal)double.Parse(remainsValue); te.Received = receivedD; te.Remains = remainsD; te.OrderId = orderId; isSucceeded = true; } else { // If result is incorrect, output error log and retry if retry count is set var logMsg = "Error happened when trading in dragonex.The result is:" + data.ToString(); LogTool.LogTradeInfo(logMsg, LogLevels.ERROR); return(Trade(symbolId, side, price, amount, ++retryCount)); } } } catch (Exception ex) { // If any error happened when Trading, out error log var logMsg = "Exception happened when trading in dragonex.Exception:" + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace + Environment.NewLine; LogTool.LogTradeInfo(logMsg, LogLevels.ERROR); return(Trade(symbolId, side, price, amount, ++retryCount)); } te.Success = isSucceeded; return(te); }
/// <summary> /// Execute trading B=>A /// </summary> public void ExecTradingBA() { try { var logMsg = "Start B=>A Trading with " + DateTime.Now.ToString("yyyyMMdd HHmmss") + Environment.NewLine + "B Sell:" + tradingEntity.Sell.ToString() + " Amount:" + tradingEntity.Amount.ToString(); LogTool.LogTradeInfo(logMsg, LogLevels.TRACE); this.Invoke(new ResetTradingInfos(ResetTradingLog), new object[] { logMsg, false }); //Start B Sell var te = dragonExApiForB.TradeCoinToBase(ConfigTool.CurrentPair.Value, tradingEntity.Sell, tradingEntity.Amount); if (te != null) { dragonExApiForB.UserAmounts.CoinAmount -= CommonUtils.GetTruncateDecimal(tradingEntity.Amount, ConfigTool.Digits); dragonExApiForB.UserAmounts.BaseAmount += CommonUtils.GetTruncateDecimal( tradingEntity.Amount * tradingEntity.Sell * (1 - ConfigTool.TradeFee), ConfigTool.Digits); this.Invoke(new ResetUI(ResetCurrentUserInfos), new object[] { }); logMsg = "B Sell Succeed" + Environment.NewLine + "A Buy:" + tradingEntity.Buy.ToString() + " Amount:" + tradingEntity.Amount.ToString(); LogTool.LogTradeInfo(logMsg, LogLevels.TRACE); this.Invoke(new ResetTradingInfos(ResetTradingLog), new object[] { logMsg, false }); //Start A Buy var qte = dragonExApiForA.TradeBaseToCoin(ConfigTool.CurrentPair.Value, tradingEntity.Buy, tradingEntity.Amount); if (qte == null) { for (int tryCount = 0; tryCount < ConfigTool.TradeTryCountWhenSellSucceed; tryCount++) { qte = dragonExApiForA.TradeBaseToCoin(ConfigTool.CurrentPair.Value, tradingEntity.Buy, tradingEntity.Amount); if (qte != null) { logMsg = "A Buy failed.Retry " + tryCount.ToString() + " succeed"; LogTool.LogTradeInfo(logMsg, LogLevels.TRACE); this.Invoke(new ResetTradingInfos(ResetTradingLog), new object[] { logMsg, false }); break; } else { logMsg = "A Buy failed.Retry " + tryCount.ToString() + " failed."; LogTool.LogTradeInfo(logMsg, LogLevels.ERROR); this.Invoke(new ResetTradingInfos(ResetTradingLog), new object[] { logMsg, false }); } Thread.Sleep(200); } } if (qte != null) { logMsg = "A Buy Succeed"; LogTool.LogTradeInfo(logMsg, LogLevels.TRACE); this.Invoke(new ResetTradingInfos(ResetTradingLog), new object[] { logMsg, false }); dragonExApiForA.UserAmounts.CoinAmount += CommonUtils.GetTruncateDecimal(tradingEntity.Amount, ConfigTool.Digits); dragonExApiForA.UserAmounts.BaseAmount -= CommonUtils.GetTruncateDecimal( tradingEntity.Amount * tradingEntity.Buy * (1 + ConfigTool.TradeFee), ConfigTool.Digits); this.Invoke(new ResetUI(ResetCurrentUserInfos), new object[] { }); //try * count check bool aResult, bResult; aResult = false; bResult = false; for (int tryCount = 0; tryCount < ConfigTool.ConfirmTryCountForTradeSucceed; tryCount++) { Thread.Sleep(2000); if (!bResult) { bResult = dragonExApiForB.CheckOrderSucceed(te.OrderId); if (bResult) { logMsg = "Check B Sell Succeed"; this.Invoke(new ResetTradingInfos(ResetTradingLog), new object[] { logMsg, false }); } } if (!aResult) { aResult = dragonExApiForA.CheckOrderSucceed(qte.OrderId); if (aResult) { logMsg = "Check A Buy Succeed"; this.Invoke(new ResetTradingInfos(ResetTradingLog), new object[] { logMsg, false }); } } if (aResult && bResult) { //If all succeeded, exit try break; } } logMsg = ""; this.Invoke(new ResetTradingInfos(ResetTradingLog), new object[] { logMsg, true }); GetUserInfo(); } else { logMsg = "A Buy Failed." + Environment.NewLine + "Abort Trading"; LogTool.LogTradeInfo(logMsg, LogLevels.TRACE); this.Invoke(new ResetTradingInfos(ResetTradingLog), new object[] { logMsg, true }); } } else { logMsg = "B Sell Failed." + Environment.NewLine + "Abort Trading"; LogTool.LogTradeInfo(logMsg, LogLevels.TRACE); this.Invoke(new ResetTradingInfos(ResetTradingLog), new object[] { logMsg, true }); } } catch (ThreadAbortException) { //Do nothing when aborting thread var logMsg = "Trading thread is immediately aborted.Trading failed."; LogTool.LogTradeInfo(logMsg, LogLevels.ERROR); this.Invoke(new ResetTradingInfos(ResetTradingLog), new object[] { "Failed", true }); } catch (Exception ex) { this.Invoke(new ResetTradingInfos(ResetTradingLog), new object[] { "Failed:" + ex.Message, true }); //Error happened when getting var logMsg = "Exception happened when Trading A to B.Details:" + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace; Console.WriteLine(logMsg); LogTool.LogTradeInfo(logMsg, LogLevels.ERROR); } finally { lastTradeTime = DateTime.Now.Ticks; } }