private decimal GetSpanPrice(decimal format = 0.1m) { if (info.SpanPrice <= 0.1m) { return(info.SpanPrice); } string kr1 = "M1"; string kr2 = "M15"; var kline1 = robotMarket.GetKlines(Symbol, kr1) ?? new List <Kline>(); var kline2 = robotMarket.GetKlines(Symbol, kr2) ?? new List <Kline>(); decimal width1 = GetKlinePriceWidth(kline1, info.OrderQty, format, 5, 1.0m); decimal width15 = GetKlinePriceWidth(kline2, info.OrderQty, format, 5, 0.5m); decimal width = Math.Max(width1, width15); if (Math.Abs(width - info.SpanPrice) >= info.SpanPrice / 4) { if (info.Symbol.ToLower().Contains("btcusdt") && width <= 1m) { width = 1; } info.SpanPrice = width; } Log4NetUtility.Debug($"kline{kr1} width : {width1} kline{kr2} width : {width15} SpanPrice:{info.SpanPrice}->{width}"); return(info.SpanPrice); }
public bool Connnet() { try { websocket = new WebSocketSharp.WebSocket(WEBSOCKET_API); websocket.OnError += (sender, e) => { Console.WriteLine("Error:" + e.Exception.Message.ToString()); Log4NetUtility.Debug("OnError", e.Exception.Message); }; websocket.OnOpen += OnOpened; websocket.OnClose += Websocket_Closed;; websocket.OnMessage += ReceviedMsg; websocket.ConnectAsync(); while (!websocket.IsAlive) { Console.WriteLine("Waiting WebSocket connnet......"); Thread.Sleep(1000); } heartBeatTimer.Elapsed += new System.Timers.ElapsedEventHandler(heatBeat); //heartBeatTimer.Start(); } catch (Exception ex) { Console.WriteLine("Exception:" + ex.Message); Log4NetUtility.Error("WebSocketApi_OK", Utils.Exception2String(ex)); } return(true); }
public Trade PostMarketTrade_FC(string symbol, string side, decimal price, decimal amount) { var coinInfo = CoinConfigs.FirstOrDefault(a => a.Symbol == symbol); if (coinInfo == null || coinInfo.AmountLimit == 0 || coinInfo.PriceLimit == 0) { throw (new Exception()); } decimal rate = 1; if (side == "buy") { rate = 1.08m; } else { rate = 0.92m; } string priceStr = coinInfo.FormatPrice2S(price * rate); string amountStr = coinInfo.FormatAmount2S(amount); Log4NetUtility.Debug("Trade", $"MarketTrade. price:{price} priceStr:{priceStr} amount:{amount} amountStr:{amountStr}"); string JsonStr = restApi_FC.trade(symbol, side, "limit", priceStr, amountStr); Log4NetUtility.Debug("Trade", JsonStr); var data = ModelHelper <API.Rest.FCoin.trade> .Json2Model(JsonStr); return(new Trade(data)); }
private void CurrentLostOrders(List <Order> lostOrders) { foreach (var lost in lostOrders) { robotSession.AddUpdateSessionOrder(lost); Log4NetUtility.Debug($"CurrentEvent,Add lostOrders Price:{lost.price.ToString("#0.00")} Id:{Utils.ShortID(lost.order_id)}"); } }
private void Websocket_OnError(object sender, ErrorEventArgs e) { Console.WriteLine("Error:" + e.Exception.Message.ToString()); Console.WriteLine("websocket.IsAlive:" + websocket.IsAlive); Log4NetUtility.Debug("OnError", "websocket.IsAlive:" + websocket.IsAlive); Log4NetUtility.Debug("OnError", e.Exception.Message); if (!websocket.IsAlive) { websocket.Close(); } }
public void CheckLostOrders(List <Order> currentOrder) { var lostOrders = currentOrder.Where(a => !SessionOrders.Exists(b => b.order_id == a.order_id)).ToList(); if (lostOrders.Count > 0) { foreach (var lost in lostOrders) { AddUpdateSessionOrder(lost); Log4NetUtility.Debug($"CurrentEvent,Add lostOrders Price:{lost.price.ToString("#0.00")} Id:{Utils.ShortID(lost.order_id)}"); } } }
private Trade TradeOrder(Order order) { if (order == null) { return(null); } Trade trade = robotTrade.Trade(Symbol, order.type, order.price, order.amount); for (int i = 0; i < 3; i++) { if (trade.result && !string.IsNullOrEmpty(trade.order_id)) { order.order_id = trade.order_id; order.create_date = Utils.GetUtcTimeDec(); robotSession.AddUpdateSessionOrder(order); Log4NetUtility.Debug($"New 《{order.type}》 Price:{order.price.ToString("#0.0000")} id:{Utils.ShortID(order.order_id)}"); break; } else { string type = order.type == "buy" ? "-S" : "+B"; Log4NetUtility.Info("RobotHFT", $"《{type}》委托失败,P:《{order.price.ToString("#0.00")}》A:《{order.amount.ToString("#0.0000")}》,第{i + 1}次返回:{trade.error_code} {trade.msg}"); Thread.Sleep(1000); if (trade.error_code.Contains("1002")) { Thread.Sleep(2000 * i); //i -= 1; } if (trade.error_code.Contains("1016")) { var side = order.type == "buy" ? "sell" : "buy"; var ticker = robotMarket.GetTicker(Symbol); decimal price = side == "buy" ? ticker.sell : ticker.buy; Trade tradeM = robotTrade.MarketTrade(Symbol, side, price, order.amount); if (tradeM.result) { Log4NetUtility.Info("RobotHFT", $"《{side}》市价调整,P:《{price.ToString("#0.00")}》A:《{order.amount.ToString("#0.0000")}》 "); } else { Log4NetUtility.Info("RobotHFT", $"《{side}》市价失败,P:《{price.ToString("#0.00")}》A:《{order.amount.ToString("#0.0000")}》 {tradeM.error_code} {tradeM.msg}"); } Thread.Sleep(2000 * i); } } } return(trade); }
/// <summary> /// 成交挂单 /// </summary> /// <param name="filledOrder"></param> /// <param name="newOrder"></param> private void CurrentOrderFilled(Order filledOrder, Order newOrder) { var trade = TradeOrder(newOrder); if (trade.result && !string.IsNullOrEmpty(trade.order_id)) { #region 反向挂单成功,处理缓存 newOrder.order_id = trade.order_id; newOrder.create_date = Utils.GetUtcTimeDec(); robotSession.AddUpdateSessionOrder(newOrder); filledOrder.status = "2"; robotSession.RemoveSessionOrder(filledOrder); #endregion #region 统计震荡 if (filledOrder.type == "buy")//买成交,行情下降 { info.dealDCount += 1; //info.DownCount_tmp += 1; info.floatPrice -= info.SpanPrice; } else//卖成交,行情上升 { info.dealUCount += 1; //info.UpCount_tmp += 1; info.floatPrice += info.SpanPrice; } long shockCount = Math.Min(info.dealDCount, info.dealUCount); if (info.dealCount != shockCount) { //string timeStr = DateTime.Now.ToString("yyyyMMddHHmmss"); info.ShockTimes.Add(Utils.GetUtcTimeDec()); info.dealCount = shockCount; } //int shockCount_tmp = Math.Min(info.DownCount_tmp, info.UpCount_tmp); //if (info.ShockCount_tmp != shockCount_tmp) //{ // info.ShockCount_tmp += 1; // //info.EarnAmt = info.EarnAmt + info.SpanPrice * info.TradeQty; //} #endregion #region log int buynum = robotSession.CountOrder(true); int sellnum = robotSession.CountOrder(false); string type = filledOrder.type == "sell" ? "+B" : "-S"; Log4NetUtility.Debug($"OrderFilled {type} [{newOrder.price.ToString("#0.00")}] ID: {Utils.ShortID(trade.order_id)} S:[{sellnum}] B:[{buynum}] "); #endregion } }
private decimal GetKlinePriceWidth(List <Kline> klines, int orderQty, decimal format, int count = 5, decimal rTimes = 1) { var list = klines.OrderBy(a => a.id).Skip(klines.Count - count).ToList(); decimal max = list.Max(a => a.high); decimal min = list.Min(a => a.low); var priceWidth = max - min; Log4NetUtility.Debug($"max : {max} min : {min} width: {priceWidth}"); var width = priceWidth / orderQty * rTimes; int f = (int)(1 / format); f = f < 1 ? 1 : f; width = Math.Round(width * f) / f; return(width < format ? format : width); }
private void CurrentDirtyOrders(List <Order> dirtyOrders) { foreach (var dirtyOrder in dirtyOrders) { var order = robotTrade.GetOrders(Symbol, dirtyOrder.order_id); if (order.result && order.orders.Count != 0) { Order o = order.orders.FirstOrDefault(); if (o.status == "filled") { robotSession.RemoveSessionOrder(dirtyOrder); Log4NetUtility.Debug($"CurrentEvent,Remove dirtyOrders {dirtyOrder.type} Price:{dirtyOrder.price.ToString("#0.00")} Id:{Utils.ShortID(dirtyOrder.order_id)} status:{o.status}"); } } } }
private void RobotHFT_SessionEvent(object sender, SessionEventArgs e) { try { Log4NetUtility.Debug($"SessionEvent:{e.EventType} {e.OrderList?.FirstOrDefault()?.type} {e.OrderList?.FirstOrDefault()?.price.ToString("0.0000")}"); switch (e.EventType) { case SessionEventType.Normal: break; case SessionEventType.DoubleOrder: CancelOrders(e.OrderList); break; case SessionEventType.ErrPrice: CancelOrders(e.OrderList); break; case SessionEventType.MoreOrder: CancelOrders(e.OrderList); break; case SessionEventType.LessOrder: TradeOrder(CreateLessOrder()); break; case SessionEventType.LostOrder: TradeOrder(e.OrderList?.FirstOrDefault()); break; case SessionEventType.Reset: ReSetOrder(); break; } } catch (Exception ex) { Log4NetUtility.Error("SessionEvent", Utils.Exception2String(ex)); } }
private void Init() { coinConfigs = CoinConfig.Load(); robotMarket = new Robot_Market(Platform); var list = coinConfigs.Where(a => a.Platform.ToLower() == Platform.ToLower()).Select(a => a.Symbol).ToList(); robotMarket.Run(new List <string>() { "btcusdt" }); decimal lastTicker = 0; int lastflag = 0; decimal count = 0; decimal guessR = 0; while (true) { try { Thread.Sleep(1000 * 30); if (!robotMarket.Running) { continue; } var depth = robotMarket.GetDepth("btcusdt"); var ticker = robotMarket.GetTicker("btcusdt"); #region depth item = new depth(); item.date = DateTime.Now; item.id = Utils.GetUtcTimeDec(); item.ticker = ticker?.last; item.json = ModelHelper <Depth> .Model2Json(depth);; if (item.ticker != 0 && !string.IsNullOrEmpty(item.json)) { DbHelper.CreateInstance().AddDepth(item); } #endregion StringBuilder sb = new StringBuilder(); if (depth != null && depth.asks.Count > 0 && depth.bids.Count > 0) { var asks = depth.asks.ToArray(); var bids = depth.bids.ToArray(); var firstA = asks.FirstOrDefault(); var firstB = bids.FirstOrDefault(); string ss = "----"; if (ticker.last > lastTicker * 1.02m) { ss = "up"; } if (ticker.last < lastTicker * 0.98m) { ss = "down"; } string sss = "Guess Wrong!"; if (ss == "up" && lastflag == 1) { sss = "Guess Right!"; guessR++; } if (ss == "down" && lastflag == 2) { sss = "Guess Right!"; guessR++; } if (lastflag == 0) { sss = ""; } sb.AppendLine($"depth asks:{asks.Count()} bids:{bids.Count()}"); sb.AppendLine($"lastTicker :{lastTicker.ToString("0.00")} thisTicker:{ticker.last.ToString("0.00")} price go {ss} {sss}"); var rate = count == 0 ? 1 : guessR / count; sb.AppendLine($"GuessCount :{count} Right:{guessR} Rate:{rate.ToString("p")}"); lastTicker = ticker.last; var aSum = asks.Sum(a => a[1]); var bSum = bids.Sum(a => a[1]); sb.AppendLine($"Amount Sum asks:{aSum.ToString("0.000")} bids:{bSum.ToString("0.000")}"); var avA = asks.Sum(a => a[0] * a[1]) / aSum; var avB = bids.Sum(a => a[0] * a[1]) / bSum; sb.AppendLine($"Price Ave asks:{avA.ToString("0.00")} bids:{avB.ToString("0.00")}"); var lastA = asks.LastOrDefault(); var lastB = bids.LastOrDefault(); sb.AppendLine($"depth asks from:{lastA[0].ToString("0.000")},{lastA[1].ToString("0.000")} to:{firstA[0].ToString("0.000")},{firstA[1].ToString("0.000")}"); sb.AppendLine($"depth bids from:{firstB[0].ToString("0.000")},{firstB[1].ToString("0.000")} to:{lastB[0].ToString("0.000")},{lastB[1].ToString("0.000")}"); //sb.AppendLine($"{asks.Where(a => a[0] == 0).Count()}{asks.Where(a => asks.Where(b => b[0] == a[0]).Count() > 1).Count()}"); var isUp = aSum * 2.5m < bSum; var isDown = bSum * 2.5m < aSum; var flag = 0; string str = "----"; if (isUp) { flag = 1; str = "Maybe Up"; count++; } if (isDown) { flag = 2; str = "Maybe Down"; count++; } sb.AppendLine($"{str}"); lastflag = flag; //Console.WriteLine(sb.ToString()); Log4NetUtility.Debug(sb.ToString()); } } catch (Exception e) { Log4NetUtility.Error("while", e.Message); } } }
public void FilledSessionOrders(List <Order> filledSessionOrders, List <Order> currentOrder) { var sessionOrders = new List <Order>(SessionOrders); Parallel.ForEach(sessionOrders, (sessionOrder, loop) => { try { #region 缓存订单在成交订单中 var filledOrder = filledSessionOrders.FirstOrDefault(a => a != null && a.order_id == sessionOrder.order_id); if (filledOrder != null) { string type = filledOrder.type == "buy" ? "+B" : "-S"; Log4NetUtility.Debug($"OrderFilled {type} [{filledOrder.price.ToString("#0.00")}] ID: {Utils.ShortID(filledOrder.order_id)} "); decimal new_price = 0; //补单Price string new_type = filledOrder.type == "buy" ? "sell" : "buy"; if (filledOrder.type == "sell") //卖单成交 { //补单价格为成交价的少一单位价格 new_price = filledOrder.price - info.SpanPrice; } else { //补单价格为成交价的多一单位价格 new_price = filledOrder.price + info.SpanPrice; } Order new_order = new Order() { price = new_price, amount = info.TradeQty, type = new_type, create_date = Utils.GetUtcTimeDec() }; CurrentOrderFilled(filledOrder, new_order); //list.Add(new_order); } #endregion #region 缓存订单不在成交\当前订单中 else//缓存订单不在成交订单中 { //缓存订单也不在当前订单中 if (!currentOrder.Exists(a => a.order_id == sessionOrder.order_id)) { decimal time = Utils.GetUtcTimeDec(-60); //若订单时间较短可能平台延迟,忽略。否则缓存脏数据 if (sessionOrder.create_date < time) { var order = robotTrade.GetOrders(symbol, sessionOrder.order_id); if (order.result && order.orders.Count != 0) { Order o = order.orders.FirstOrDefault(); if (o.status == "filled") { if (sessionOrder.flag == "dirty") { RemoveSessionOrder(sessionOrder); Log4NetUtility.Debug($"Remove dirtyOrders {sessionOrder.type} Price:{sessionOrder.price.ToString("#0.00")} Id:{Utils.ShortID(sessionOrder.order_id)} status:{o.status}"); } else { sessionOrder.flag = "dirty"; } } } } } } #endregion } catch (Exception e) { throw (e); } }); }