public bool Redo(SpotOrder so) { if (so == null) { return(false); } if (!so.IsArrangable()) { return(false); } if (so.IsArranging()) { return(false); } so.State = OrderState.已撤销; var r = Container.Remove(so); so.UnFreeze(); if (OnFinish != null) { foreach (var v in OnFinish.GetInvocationList()) { ((Action <SpotOrder>)v)(so); } } return(r); }
void MakeDeal(SpotOrder main, SpotOrder slave) { var count = Math.Min(main.Count, slave.Count); var price = slave.Price; var total = count * price; //设置成交价格和成交数量 main.DonePrice = slave.DonePrice = price; main.DoneCount = slave.DoneCount = count; main.TotalDoneCount += count; slave.TotalDoneCount += count; main.Count -= count; slave.Count -= count; main.TotalDoneSum += total; slave.TotalDoneSum += total; //设置状态 main.State = main.IsDone() ? OrderState.已成交 : OrderState.部分成交; slave.State = slave.IsDone() ? OrderState.已成交 : OrderState.部分成交; //从容器中移除如果已经成交 if (slave.IsDone()) { Container.Remove(slave); } //处理账户和金额 HandleCache(main); HandleCache(slave); //引发事件 RaiseDeal(main, slave); RaiseFinish(main); RaiseFinish(slave); }
public void Match(SpotOrder so) { if (so == null) { Log.Info("委托对象为空,不能撮合"); return; } switch (so.OrderPolicy) { case OrderPolicy.限价申报: price.Match(so); break; case OrderPolicy.限价FOK: priceOk.Match(so); break; case OrderPolicy.市价剩余转限价: mtp.Match(so); break; case OrderPolicy.市价FOK: marketFok.Match(so); break; case OrderPolicy.市价IOC: marketIoc.Match(so); break; default: Log.Info("交易策略有问题,不能撮合:{0}", so.ToString()); break; } }
public void RestoreOrders() { FlushSpotOrder fso = new FlushSpotOrder(); var ok = fso.GetOldGeneration(); if (ok == null) { return; } string sql = string.Format(@"select * from tempspotorders where id in (select id from tempspotorders where detail='{0}' except select id from spotorders)", (int)ok); using (var db = new OptionDbCtx()) { var q = db.Database.SqlQuery <SpotOrder>(sql); foreach (var v in q) { var coin = Model.Coins.Where(a => a.Id == v.CoinId).FirstOrDefault(); var trader = Model.Traders.Where(a => a.Id == v.TraderId).FirstOrDefault(); var so = new SpotOrder { Id = v.Id, CoinId = v.CoinId, Count = v.Count, Detail = v.Detail, Direction = v.Direction, DoneCount = v.DoneCount, DonePrice = v.DonePrice, IsBySystem = v.IsBySystem, OrderPolicy = v.OrderPolicy, OrderTime = v.OrderTime, Price = v.Price, ReportCount = v.ReportCount, RequestStatus = v.RequestStatus, State = v.State, TotalDoneCount = v.TotalDoneCount, TotalDoneSum = v.TotalDoneSum, TraderId = v.TraderId, Coin = coin, Trader = trader }; SpotOrders.Add(so); } } }
static bool CouldUnfreezeAll(this SpotOrder o) { if (o.State == OrderState.已行权 || o.State == OrderState.已成交 || o.State == OrderState.已撤销) { return(true); } return(false); }
static decimal GetUnfreezeCount(this SpotOrder o, SoFreeze sof) { decimal c = o.DoneCount; if (o.State == OrderState.已撤销) { c = o.ReportCount - o.TotalDoneCount; } return(c); }
void RaisePartialFinish(SpotOrder so) { if (so.State == OrderState.部分成交 && OnPartialFinish != null) { foreach (var v in OnPartialFinish.GetInvocationList()) { ((Action <SpotOrder>)v)(so); } } }
public void Should_Be_Invalid_If_Amount_Is_Negative() { SetTestEnvironnement(); var spotOrder = new SpotOrder(0, -10); _orderCreator.CreateNewOrder(spotOrder); Assert.IsFalse(spotOrder.IsValid()); }
public static bool RemoveSpotOrder(this Trader t, SpotOrder so) { var sl = t.GetSpotOrders(); if (sl == null) { return(false); } return(sl.Remove(so)); }
public static void AddSpotOrder(this Trader t, SpotOrder so) { var sl = t.GetSpotOrders(); if (sl == null) { sl = new List <SpotOrder>(); sos.Set(t, sl); } sl.Add(so); }
public void UpdatePartial(SpotOrder so) { Task.Factory.StartNew(() => { string sql = string.Format(f, so.Count, so.DoneCount, so.TotalDoneCount, so.DonePrice, so.TotalDoneSum, (int)so.State, so.Price, so.Id); using (DBServer db = new DBServer()) { db.ExecNonQuery(sql); } }); }
public override void Match(SpotOrder o) { try { var r = FindPossibleMatch(o, false); HandleCount(o, r); } catch (Exception e) { Singleton <TextLog> .Instance.Error(e, "撮合异常"); } }
public SpotOrderDto(SpotOrder so) { if (so != null) { this.Id = so.Id; this.Price = so.Price; this.Coin = so.Coin.Name; this.Count = so.Count; //this.Detail = so.Detail; this.Direction = so.Direction.ToString(); this.DoneCount = so.DoneCount; this.DonePrice = so.DonePrice; this.TotalDoneCount = so.TotalDoneCount; this.TotalDoneSum = so.TotalDoneSum; this.OrderTime = so.OrderTime.ToString("yyyy-MM-dd HH:mm:ss"); this.ReportCount = so.ReportCount; this.RequestStatus = so.RequestStatus.ToString(); this.State = so.State.ToString(); this.Undeal = so.ReportCount - so.TotalDoneCount; } }
public bool Remove(SpotOrder so) { if (!dic.ContainsKey(so.Coin)) { lock (loc) { if (!dic.ContainsKey(so.Coin)) { dic.Add(so.Coin, new CoinOrderContainer(so.Coin, OnFinish)); } } } return(dic[so.Coin].Remove(so)); }
public void Add(SpotOrder so) { if (!dic.ContainsKey(so.Coin)) { lock (loc) { if (!dic.ContainsKey(so.Coin)) { dic.Add(so.Coin, new CoinOrderContainer(so.Coin, OnFinish)); } } } dic[so.Coin].Add(so); }
public void Should_Be_Invalid_If_It_Has_Already_Been_Paid() { SetTestEnvironnement(); var spotOrder = new SpotOrder(0, 10); _orderCreator.CreateNewOrder(spotOrder); Assert.IsTrue(spotOrder.IsValid()); _orderPayer.Pay(spotOrder); Assert.IsFalse(spotOrder.IsValid()); }
public int CouldOrder(SpotOrder so) { var cc = CheckCount(so); if (!cc) { return(1); } var cm = CheckMoney(so); if (!cm) { return(2); } return(0); }
public static SoFreeze Freeze(this SpotOrder o) { SoFreeze f; if (o.Direction == TradeDirectType.卖) { f = new SoFreeze(true, true, o.ReportCount, o.Price); } else { f = new SoFreeze(false, true, o.ReportCount, o.Price); } sof.Set(o.Id, f); f.Execute(o); return(f); }
public virtual void HandleCount(SpotOrder so, List <SpotOrder> p) { lock (matchLock) { if (p == null || p.Count == 0) { if (so.IsArrangable()) { Container.Add(so); model.SpotOrders.Add(so); so.Trader.AddSpotOrder(so); } return; } foreach (var v in p) { if (!v.IsArrangable()) { continue; } if (v.IsArranging()) { continue; } v.SetArranging(true); if (v.Count >= so.Count) { MakeDeal(so, v); v.SetArranging(false); break; } else { MakeDeal(so, v); v.SetArranging(false); continue; } } if (so.IsArrangable()) { // if() Container.Add(so); model.SpotOrders.Add(so); so.Trader.AddSpotOrder(so); } } }
/// <summary> /// 买:只有钱够才能买 /// 卖:无限制 /// </summary> /// <param name="so"></param> /// <returns></returns> bool CheckMoney(SpotOrder so) { if (so.Direction == TradeDirectType.卖) { return(true); } var needed = so.GetTotal();// so.Count * so.Price; if (so.Trader.Account.CacheAccount.CnyAccount.Sum >= needed) { return(true); } else { return(false); } }
public override void Match(SpotOrder o) { var l = FindPossibleMatch(o, true); if (l == null) { Redo(o); return; } var ll = FindPossibleMatch(o, true).Where(d => d.Price == l.FirstOrDefault().Price).ToList(); HandleCount(o, ll); if (o.State != OrderState.已成交) { Redo(o); } }
static void Raise(SpotOrder o, int op) { if (OnOrderAddRemove != null) { foreach (var v in OnOrderAddRemove.GetInvocationList()) { try { ((Action <SpotOrder, int>)v).BeginInvoke(o, op, null, null); } catch (Exception e) { Singleton <TextLog> .Instance.Error(e, "spot add remove"); } } } }
public override void Match(SpotOrder o) { var r = FindPossibleMatch(o, false); if (r.Count == 0) { Redo(o); return; } var rc = r.Select(a => a.Count).Sum(); if (rc < o.Count) { Redo(o); return; } HandleCount(o, r); }
public void Add(SpotOrder so) { if (so.Coin != coin) { return; } if (so.Direction == TradeDirectType.卖) { lock (sl) sellList.Add(so); } else { lock (bl) buyList.Add(so); } Raise(so, 1); }
public override void Match(SpotOrder o) { var l = FindPossibleMatch(o, true);// Container.FindByDirAndPos(o); if (l == null || l.Count == 0) { Redo(o); return; } var lc = l.Select(a => a.Count).Sum(); if (lc < o.Count) { Redo(o); return; } HandleCount(o, l); }
//TextLog log = new TextLog("jd.txt"); void HandleCache(SpotOrder so) { so.UnFreeze(); if (so.Direction == TradeDirectType.卖) { var ca = so.Trader.Account.CacheAccount.BtcAccount; //收款 TraderService.OperateAccount(so.Trader, so.DonePrice * so.DoneCount, AccountChangeType.现金收款, so.Trader.Name, null); TraderService.OperateAccount(so.Trader, so.DoneCount, AccountChangeType.BTC付款, so.Trader.Name, null); } else { TraderService.OperateAccount(so.Trader, so.DoneCount * so.DonePrice, AccountChangeType.现金付款, so.Trader.Name, null); TraderService.OperateAccount(so.Trader, so.DoneCount, AccountChangeType.BTC收款, so.Trader.Name, null); } }
/// <summary> /// 卖:只能卖有的,且一个只能卖一次 /// 买无限制 /// </summary> /// <param name="so"></param> /// <returns></returns> bool CheckCount(SpotOrder so) { if (so.Direction == TradeDirectType.卖) { var cc = so.Trader.Account.CacheAccount.BtcAccount.Sum;//.GetCoinAcount(so.Coin).Balance;(可用的) log.Info(string.Format("实际:{0},我卖:{1}", cc, so.Count)); if (cc < so.Count) { return(false); } var soc = so.Trader.GetSpotOrders(); decimal ocs = 0; log.Info(string.Format("soc的结果:{0}", soc)); log.Info(string.Format("比特币的可用资金:{0}", cc)); if (soc != null) { //注:卖出去的马上就会被冻结(相当于不是我的),为什么还要用可用的减去卖出去的BTC(相当于要扣除了一次BTC) ocs = soc.Where(a => a.Coin == so.Coin && a.Direction == TradeDirectType.卖 && a.State == OrderState.等待中 || a.State == OrderState.部分成交).Select(a => a.Count).Sum(); //var kk = soc.Where(a => a.Coin == so.Coin && a.Direction == TradeDirectType.卖).ToList(); // log.Info(string.Format("soc里面SUM:{0}///{1}", ocs,kk.Count())); // foreach (var item in kk) // { // log.Info(string.Format("数据:{0},{1},{2},{3}", item.Id, item.Direction, item.State,kk.Count())); // } // var r = cc - ocs - so.Count; var r = cc - so.Count; //log.Info(string.Format("soc里面计算:{0}={1} - {2}-{3}", r, cc,ocs , so.Count)); if (r >= 0) { return(true); } else { return(false); } } return(true); } return(true); }
void RaiseFinish(SpotOrder so) { if (so.IsDone()) { so.Trader.RemoveSpotOrder(so); model.SpotOrders.Remove(so); if (OnFinish != null) { foreach (var v in OnFinish.GetInvocationList()) { ((Action <SpotOrder>)v)(so); } } } else { model.UpdatePartial(so); RaisePartialFinish(so); } }
void RaiseDeal(SpotOrder main, SpotOrder slave) { SpotDeal sd = new SpotDeal { Id = IdService <SpotDeal> .Instance.NewId(), When = DateTime.Now, Count = main.DoneCount, Price = main.DonePrice, MainId = main.Id, SlaveId = slave.Id, MainTraderName = main.Trader.Name, SlaveTraderId = slave.Trader.Name, Coin = main.Coin, CoinId = main.CoinId, MainOrderDir = main.Direction }; if (OnDeal != null) { OnDeal(sd); } }
public static void UnFreeze(this SpotOrder o) { lock (o.Sign) { var f = sof.Get(o.Id); if (f == null) { return; } var c = o.GetUnfreezeCount(f); if (c > 0) { SoFreeze sf = new SoFreeze(f.IsCoin, false, c, f.Price); sf.Execute(o); } if (o.CouldUnfreezeAll()) { sof.Clear(o.Id); } } }