/// <summary> /// 是否禁止交易指定证券类型的证券 /// </summary> /// <param name="sType"></param> /// <returns></returns> private bool IsBanned(TradingSystem.StockType sType) { try { string strSpecies = ""; for (int i = 0; i < 100; i++) { strSpecies = Common.Config("Trading", "Species-" + i.ToString("00").Trim()); if (strSpecies.Length > 0) { if (string.Compare(strSpecies.ToUpper().Trim(), sType.ToString().ToUpper().Trim()) == 0) { return(false); } } } return(true); } catch { return(true); } }
/// <summary> /// 获取快照,存储片断 /// </summary> /// <returns></returns> public bool GetSnapShot() { try { lock (mapSHRates) { if (mapSHRates != null && mapSHRates.Count > 0) { lock (mapSHSnapShot) { mapSHSnapShot.Clear(); mapSHSnapShot = new Dictionary <string, Show2003DBFRecord>(mapSHRates); } } } lock (mapSZRates) { if (mapSZRates != null && mapSZRates.Count > 0) { lock (mapSZSnapShot) { mapSZSnapShot.Clear(); mapSZSnapShot = new Dictionary <string, SjshqDBFRecord>(mapSZRates); } } } if (mapSHSnapShot != null && mapSHSnapShot.Count > 0 && mapSZSnapShot != null && mapSZSnapShot.Count > 0) { foreach (object objSh in mapSHSnapShot.Keys) { if (objSh == null || objSh.ToString() == null) { continue; } string strKey = objSh.ToString().Trim(); if (!mapSHSnapShot.ContainsKey(strKey)) { continue; } TradingSystem.StockType sType = Common.stkTrading.GetStockType(strKey, TradingSystem.StockMarket.Shanghai); if (sType != TradingSystem.StockType.SH_A && sType != TradingSystem.StockType.ETF && sType != TradingSystem.StockType.SH_ClosedFund && sType != TradingSystem.StockType.SH_Warrant && sType != TradingSystem.StockType.SH_B && sType != TradingSystem.StockType.SH_Bond) { continue; } SaveQuotation(mapSHSnapShot[strKey]);//存储上证类股票 } foreach (object objSh in mapSZSnapShot.Keys) { if (objSh == null || objSh.ToString() == null) { continue; } string strKey = objSh.ToString().Trim(); if (!mapSZSnapShot.ContainsKey(strKey)) { continue; } TradingSystem.StockType sType = Common.stkTrading.GetStockType(strKey, TradingSystem.StockMarket.Shenzhen); if (sType != TradingSystem.StockType.SZ_A && sType != TradingSystem.StockType.ETF && sType != TradingSystem.StockType.SZ_ClosedFund && sType != TradingSystem.StockType.SZ_Warrant && sType != TradingSystem.StockType.SZ_B && sType != TradingSystem.StockType.SZ_Bond) { continue; } SaveQuotation(mapSZSnapShot[strKey]);//存储深证类股票 } return(true); } else { return(false); } } catch (Exception err) { Common.Log(err); return(false); } }
/// <summary> /// 添加即时订单 /// </summary> /// <param name="strUserKey"></param> /// <param name="UserID"></param> /// <param name="StockCode"></param> /// <param name="Market"></param> /// <param name="Volume"></param> /// <param name="Side"></param> /// <param name="ValidDays"></param> /// <param name="OrderID"></param> /// <returns></returns> public RI_Result RequestImmediateOrder(string strUserKey, int UserID, string StockCode, RI_Market Market, int Volume, bool Side, ushort ValidDays, out int OrderID) { OrderID = -1; try { if (strUserKey == null || string.Compare(strUserKey.Trim(), Common.Config("Authorization", "UserKey").Trim()) != 0) { if (strUserKey != null) { Common.Log("The Invoker [" + strUserKey.Trim() + "] Is Unauthorized. [UserID=" + UserID + "]"); } else { Common.Log("The Invoker [null] Is Unauthorized. [UserID=" + UserID + "]"); } return(RI_Result.Unauthorized); } else if (!Common.Switch_ImmediateOrder || !Management.Work) { Common.Log("The Interface [ProcessImmediateOrder] Is Closed. [UserID=" + UserID + "]"); return(RI_Result.Closed_Interface); } if (!Common.IsInInterfaceQuotationTime) { return(RI_Result.Out_Of_Quotation_Time); } else if (Common.stkTrading == null) { return(RI_Result.Internal_Error); } else if (UserID <= 0) { return(RI_Result.Illegal_UserID); } TradingSystem.StockType stkType = Common.stkTrading.GetStockType(StockCode, (TradingSystem.StockMarket)((byte)Market)); if (Volume <= 0 || (Side && (stkType != TradingSystem.StockType.SH_Warrant && stkType != TradingSystem.StockType.SZ_Warrant && Volume % 100 != 0) || ((stkType == TradingSystem.StockType.SH_Warrant || stkType == TradingSystem.StockType.SZ_Warrant) && Volume % 1000 != 0))) { return(RI_Result.Illegal_Volume); } else if (StockCode == null || Market == RI_Market.Unknown) { return(RI_Result.Banned_Stock); } StockCode = StockCode.Trim(); if (IsBanned(stkType)) { return(RI_Result.Banned_Stock); } TradingSystem.Currency Curr = TradingSystem.Currency.Unknown; switch (stkType) { case TradingSystem.StockType.SH_B: Curr = TradingSystem.Currency.USD; break; case TradingSystem.StockType.SZ_B: Curr = TradingSystem.Currency.HKD; break; default: Curr = TradingSystem.Currency.RMB; break; } Show2003DBFRecord SHRec = new Show2003DBFRecord(); SHRec.Clear(); SjshqDBFRecord SZRec = new SjshqDBFRecord(); SZRec.Clear(); if (Common.stkQuotation.CheckSuspended(StockCode, (TradingSystem.StockMarket)((byte)Market))) { if (Market == RI_Market.Shanghai && SHRec.OpenPrice < 0.001) { return(RI_Result.Suspended_Stock); } else if (Market == RI_Market.Shenzhen && SZRec.OpenPrice < 0.001) { return(RI_Result.Suspended_Stock); } } else { return(RI_Result.Banned_Stock); } short sCurrCount = Common.stkTrading.GetUserOrdersCount(UserID); if (sCurrCount == -2) { return(RI_Result.Illegal_UserID); } if (sCurrCount < 0 || sCurrCount >= Common.MaxOrders) { return(RI_Result.Too_Many_Orders); } Dictionary <byte, TradingSystem.UserFund> mapUsableFund = new Dictionary <byte, TradingSystem.UserFund>(); if (!Common.stkTrading.GetUserFund(UserID, out mapUsableFund)) { return(RI_Result.Illegal_UserID); } int UserVolume = Common.stkTrading.GetSellableStockVolume(UserID, StockCode, (TradingSystem.StockMarket)((byte)Market)); if (!Side && (UserVolume < Volume)) { return(RI_Result.Not_Enough_Stock); } if (!Side && (Volume % 100 != 0) && (Volume % 100 != UserVolume % 100)) { return(RI_Result.Illegal_Volume); } if (Side && !Common.stkTrading.CanBuy(UserID, StockCode, (TradingSystem.StockMarket)((byte)Market), Curr, 10 * Volume * (1 + Common.stkTrading.defaultBuyTax))) { return(RI_Result.Speculation_Behavior); } TradingSystem.UserOrders userOrder = new TradingSystem.UserOrders(); userOrder.Initialize(); userOrder.OrderID = Common.stkTrading.nLastOrderID++; userOrder.UserID = UserID; userOrder.StockCode = StockCode.Trim(); userOrder.Market = (TradingSystem.StockMarket)((byte)Market); userOrder.OrderVolume = Volume; userOrder.Side = Side; userOrder.OrderDate = DateTime.Now; userOrder.ExpiredDate = userOrder.OrderDate.Date.Add(new TimeSpan(ValidDays, Common.EndPMTS.Hours, Common.EndPMTS.Minutes, Common.EndPMTS.Seconds)); userOrder.OrdStatus = TradingSystem.OrderStatus.Waiting; userOrder.OrdType = TradingSystem.OrderType.ImmediateOrder; userOrder.Curr = Curr; lock (Common.stkTrading.listNewUserOrders) { Common.stkTrading.listNewUserOrders.Add(userOrder); Common.DBSync.OrderAppended(userOrder, UserID); } Common.Debug("Immediate Order Requested [UserID=" + UserID + "; StockCode=" + StockCode.Trim() + "-" + (byte)Market + "]."); OrderID = userOrder.OrderID; return(RI_Result.Success); } catch (Exception ex) { Common.Debug("Immediate Order Requested error :" + UserID + "; StockCode=" + StockCode.Trim() + "-" + (byte)Market + "]." + ex.ToString()); return(RI_Result.Internal_Error); } }
/// <summary> /// 添加限价订单 /// </summary> /// <param name="strUserKey"></param> /// <param name="UserID"></param> /// <param name="StockCode"></param> /// <param name="Market"></param> /// <param name="Volume"></param> /// <param name="OrderPrice"></param> /// <param name="Side"></param> /// <param name="ValidDays"></param> /// <param name="OrderID"></param> /// <returns></returns> public RI_Result RequestLimitedOrder(string strUserKey, int UserID, string StockCode, RI_Market Market, int Volume, double OrderPrice, bool Side, ushort ValidDays, out int OrderID) { OrderID = -1; try { if (strUserKey == null || string.Compare(strUserKey.Trim(), Common.Config("Authorization", "UserKey").Trim()) != 0) { if (strUserKey != null) { Common.Log("The Invoker [" + strUserKey.Trim() + "] Is Unauthorized. [UserID=" + UserID + "]"); } else { Common.Log("The Invoker [null] Is Unauthorized. [UserID=" + UserID + "]"); } return(RI_Result.Unauthorized); } else if (!Common.Switch_LimitedOrder || !Management.Work) { Common.Log("The Interface [ProcessLimitedOrder] Is Closed. [UserID=" + UserID + "]"); return(RI_Result.Closed_Interface); } if (!Common.IsInInterfaceQuotationTime) { return(RI_Result.Out_Of_Quotation_Time); } else if (Common.stkTrading == null) { return(RI_Result.Internal_Error); } else if (UserID <= 0) { return(RI_Result.Illegal_UserID); } TradingSystem.StockType stkType = Common.stkTrading.GetStockType(StockCode, (TradingSystem.StockMarket)((byte)Market)); if (Volume <= 0 || (Side && (stkType != TradingSystem.StockType.SH_Warrant && stkType != TradingSystem.StockType.SZ_Warrant && Volume % 100 != 0) || ((stkType == TradingSystem.StockType.SH_Warrant || stkType == TradingSystem.StockType.SZ_Warrant) && Volume % 1000 != 0))) { return(RI_Result.Illegal_Volume); } else if (OrderPrice < 0.001) { return(RI_Result.Illegal_Price); } else if ((stkType == TradingSystem.StockType.SH_A || stkType == TradingSystem.StockType.SZ_A) && OrderPrice < 0.01) { return(RI_Result.Illegal_Price); } else if (StockCode == null || Market == RI_Market.Unknown) { return(RI_Result.Banned_Stock); } StockCode = StockCode.Trim(); TradingSystem.Currency Curr = TradingSystem.Currency.Unknown; switch (stkType) { case TradingSystem.StockType.SH_B: Curr = TradingSystem.Currency.USD; break; case TradingSystem.StockType.SZ_B: Curr = TradingSystem.Currency.HKD; break; default: Curr = TradingSystem.Currency.RMB; break; } if (IsBanned(stkType)) { Common.Debug("Banned_Stock:" + UserID + ";" + StockCode + ";" + Market.ToString().Trim() + ";" + stkType.ToString().Trim()); return(RI_Result.Banned_Stock); } Show2003DBFRecord SHRec = new Show2003DBFRecord(); SHRec.Clear(); SjshqDBFRecord SZRec = new SjshqDBFRecord(); SZRec.Clear(); if (Common.stkQuotation.CheckSuspended(StockCode, (TradingSystem.StockMarket)((byte)Market))) { Common.Debug("Suspended_Stock:" + UserID + ";" + StockCode + ";" + Market.ToString()); return(RI_Result.Suspended_Stock); } short sCurrCount = Common.stkTrading.GetUserOrdersCount(UserID); if (sCurrCount == -2) { return(RI_Result.Illegal_UserID); } if (sCurrCount < 0 || sCurrCount >= Common.MaxOrders) { Common.Debug("Too_Many_Orders:" + UserID + ";" + sCurrCount + "/" + Common.MaxOrders); return(RI_Result.Too_Many_Orders); } int SellableVolume = Common.stkTrading.GetSellableStockVolume(UserID, StockCode, (TradingSystem.StockMarket)((byte)Market)); if (!Side && (SellableVolume < Volume)) { Common.Debug("Not_Enough_Stock:" + UserID + "/" + StockCode.Trim() + "-" + (byte)Market + ";" + SellableVolume + "/" + Volume); return(RI_Result.Not_Enough_Stock); } if (!Side && (Volume % 100 != 0) && (Volume % 100 != SellableVolume % 100)) { return(RI_Result.Illegal_Volume); } if (Side && !Common.stkTrading.CanBuy(UserID, StockCode, (TradingSystem.StockMarket)((byte)Market), Curr, OrderPrice * Volume * (1 + Common.stkTrading.defaultBuyTax))) { Common.Debug("Speculation_Behavior:" + UserID + "/" + StockCode.Trim() + "-" + (byte)Market + "/" + (OrderPrice * Volume * (1 + Common.stkTrading.defaultBuyTax)).ToString("f2")); return(RI_Result.Speculation_Behavior); } TradingSystem.UserOrders userOrder = new TradingSystem.UserOrders(); userOrder.Initialize(); userOrder.OrderID = Common.stkTrading.nLastOrderID++; userOrder.UserID = UserID; userOrder.StockCode = StockCode.Trim(); userOrder.Market = (TradingSystem.StockMarket)((byte)Market); userOrder.Side = Side; userOrder.OrderVolume = Volume; userOrder.OrderPrice = OrderPrice; userOrder.OrderDate = DateTime.Now; userOrder.ExpiredDate = userOrder.OrderDate.Date.Add(new TimeSpan(ValidDays, Common.EndPMTS.Hours, Common.EndPMTS.Minutes, Common.EndPMTS.Seconds)); userOrder.OrdStatus = TradingSystem.OrderStatus.Waiting; userOrder.OrdType = TradingSystem.OrderType.LimitedOrder; userOrder.Curr = Curr; if (Side) { lock (Common.stkTrading.listNewUserFund) { TradingSystem.UserFund usableFund = new TradingSystem.UserFund(); usableFund.Initialize(); for (int i = 0; i < Common.stkTrading.listNewUserFund.Count; i++) { if (Common.stkTrading.listNewUserFund[i].UserID == UserID && ((stkType == TradingSystem.StockType.SH_B && Common.stkTrading.listNewUserFund[i].Curr == TradingSystem.Currency.USD) || (stkType == TradingSystem.StockType.SZ_B && Common.stkTrading.listNewUserFund[i].Curr == TradingSystem.Currency.HKD) || Common.stkTrading.listNewUserFund[i].Curr == TradingSystem.Currency.RMB)) { usableFund = Common.stkTrading.listNewUserFund[i]; usableFund.UsableCash -= Common.ConvertPrice((userOrder.OrderVolume * userOrder.OrderPrice) * (1 + Common.stkTrading.defaultBuyTax) + 0.0099); if (usableFund.UsableCash < 0) { return(RI_Result.Not_Enough_Cash); } if (!Common.stkTrading.SetUserFund(UserID, usableFund)) { return(RI_Result.Illegal_UserID); } Common.stkTrading.listNewUserFund[i] = usableFund; Common.DBSync.FundUpdate(usableFund, UserID); lock (Common.stkTrading.listNewUserOrders) { Common.stkTrading.listNewUserOrders.Add(userOrder); Common.DBSync.OrderAppended(userOrder, UserID); } Common.Debug("Limited Order Requested [UserID=" + UserID + "; StockCode=" + StockCode.Trim() + "-" + (byte)Market + "]."); OrderID = userOrder.OrderID; return(RI_Result.Success); } } Dictionary <byte, TradingSystem.UserFund> mapUsableFund = new Dictionary <byte, TradingSystem.UserFund>(); if (!Common.stkTrading.GetUserFund(UserID, out mapUsableFund)) { return(RI_Result.Illegal_UserID); } switch (stkType) { case TradingSystem.StockType.SH_B: { if (mapUsableFund.ContainsKey((byte)TradingSystem.Currency.USD)) { usableFund = mapUsableFund[(byte)TradingSystem.Currency.USD]; } else { return(RI_Result.Not_Enough_Cash); } } break; case TradingSystem.StockType.SZ_B: { if (mapUsableFund.ContainsKey((byte)TradingSystem.Currency.HKD)) { usableFund = mapUsableFund[(byte)TradingSystem.Currency.HKD]; } else { return(RI_Result.Not_Enough_Cash); } } break; default: { if (mapUsableFund.ContainsKey((byte)TradingSystem.Currency.RMB)) { usableFund = mapUsableFund[(byte)TradingSystem.Currency.RMB]; } else { return(RI_Result.Not_Enough_Cash); } } break; } usableFund.UsableCash -= Common.ConvertPrice((userOrder.OrderVolume * userOrder.OrderPrice) * (1 + Common.stkTrading.defaultBuyTax) + 0.0099); if (usableFund.UsableCash < 0) { Common.Debug("Not_Enough_Cash:" + UserID + "/" + StockCode.Trim() + "-" + (byte)Market + ";" + (usableFund.UsableCash + Common.ConvertPrice((userOrder.OrderVolume * userOrder.OrderPrice) * (1 + Common.stkTrading.defaultBuyTax))) + "/" + ((userOrder.OrderVolume * userOrder.OrderPrice) * (1 + Common.stkTrading.defaultBuyTax))); return(RI_Result.Not_Enough_Cash); } if (!Common.stkTrading.SetUserFund(UserID, usableFund)) { return(RI_Result.Illegal_UserID); } Common.stkTrading.listNewUserFund.Add(usableFund); Common.DBSync.FundUpdate(usableFund, UserID); } } lock (Common.stkTrading.listNewUserOrders) { Common.stkTrading.listNewUserOrders.Add(userOrder); Common.DBSync.OrderAppended(userOrder, UserID); } Common.Debug("Limited Order Requested [UserID=" + UserID + "; StockCode=" + StockCode.Trim() + "-" + (byte)Market + "]."); OrderID = userOrder.OrderID; return(RI_Result.Success); } catch { return(RI_Result.Internal_Error); } }
/// <summary> /// 更新用户订单 /// </summary> /// <param name="UserID"></param> /// <param name="UserOrder"></param> /// <returns></returns> public bool SetUserOrders(int UserID, RemotingInterface.RI_Order UserOrder) { try { if (UserID <= 0) { return(false); } if (UserOrder.OrderDate.Date != DateTime.Now.Date || DateTime.Now.TimeOfDay > Common.EndPMTS) { return(false); } TradingSystem.StockMarket sMarket = TradingSystem.StockMarket.Unknown; if (UserOrder.StockMarket == RemotingInterface.RI_Market.Shanghai) { sMarket = TradingSystem.StockMarket.Shanghai; } else if (UserOrder.StockMarket == RemotingInterface.RI_Market.Shenzhen) { sMarket = TradingSystem.StockMarket.Shenzhen; } TradingSystem.StockType sType = Common.stkTrading.GetStockType(UserOrder.StockCode, sMarket); switch (sType) { case TradingSystem.StockType.SH_A: case TradingSystem.StockType.SZ_A: case TradingSystem.StockType.SH_Bond: case TradingSystem.StockType.SZ_Bond: { UserOrder.OrderPrice = Common.ConvertPrice(UserOrder.OrderPrice, 2); UserOrder.TradePrice = Common.ConvertPrice(UserOrder.TradePrice, 2); } break; default: { UserOrder.OrderPrice = Common.ConvertPrice(UserOrder.OrderPrice); UserOrder.TradePrice = Common.ConvertPrice(UserOrder.TradePrice); } break; } if (UserOrder.UpdatedDate < UserOrder.OrderDate) { UserOrder.UpdatedDate = UserOrder.OrderDate; } lock (mapRIUserOrders) { if (mapRIUserOrders.ContainsKey(UserID)) { Dictionary <int, RemotingInterface.RI_Order> mapOrders = mapRIUserOrders[UserID]; mapOrders[UserOrder.OrderID] = UserOrder; mapRIUserOrders[UserID] = mapOrders; Common.Debug("SetOrderInfoInBuffer: UserID-" + UserID + "; StockCode-" + UserOrder.StockCode + (byte)UserOrder.StockMarket + "; OrderID-" + UserOrder.OrderID + "; Type-" + UserOrder.OrderType.ToString() + "; Status-" + UserOrder.OrderStatus.ToString()); } else { Dictionary <int, RemotingInterface.RI_Order> mapOrders = new Dictionary <int, RemotingInterface.RI_Order>(); mapOrders[UserOrder.OrderID] = UserOrder; mapRIUserOrders[UserID] = mapOrders; Common.Debug("SetOrderInfoInBuffer: UserID-" + UserID + "; StockCode-" + UserOrder.StockCode + (byte)UserOrder.StockMarket + "; OrderID-" + UserOrder.OrderID + "; Type-" + UserOrder.OrderType.ToString() + "; Status-" + UserOrder.OrderStatus.ToString()); } } return(true); } catch (Exception err) { Common.Log(err); return(false); } }