public bool FindQuotation(string StockCode, out SjshqDBFRecord SZRecord) { SZRecord = new SjshqDBFRecord(); try { SZRecord.Clear(); if (StockCode == null || StockCode.Trim().Length != 6) { return(false); } if (mapSZRates == null) { return(false); } lock (mapSZRates) { if (mapSZRates.ContainsKey(StockCode.Trim())) { SZRecord = mapSZRates[StockCode.Trim()]; return(true); } } return(false); } catch (Exception err) { Loger.Debug(err); SZRecord.Clear(); return(false); } }
/// <summary> /// 获取即时行情 /// </summary> /// <param name="StockCode">股票代码</param> /// <param name="Market">市场</param> /// <param name="SHRecord">上证类股票行情</param> /// <param name="SZRecord">深证类股票行情</param> /// <returns></returns> public bool GetStkRate(string StockCode, TradingSystem.StockMarket Market, out Show2003DBFRecord SHRecord, out SjshqDBFRecord SZRecord) { SHRecord = new Show2003DBFRecord(); SZRecord = new SjshqDBFRecord(); try { SHRecord.Clear(); SZRecord.Clear(); if (StockCode == null || StockCode.Trim().Length <= 0 || Market == TradingSystem.StockMarket.Unknown) { return(false); } //上证类股票 if (Market == TradingSystem.StockMarket.Shanghai) { lock (mapSHSnapShot) { if (mapSHSnapShot == null || mapSHSnapShot.Count <= 0) { return(false); } if (mapSHSnapShot.ContainsKey(StockCode.Trim())) { SHRecord = mapSHSnapShot[StockCode.Trim()]; return(true); } } } //深证类股票 else if (Market == TradingSystem.StockMarket.Shenzhen) { lock (mapSZSnapShot) { if (mapSZSnapShot == null || mapSZSnapShot.Count <= 0) { return(false); } else if (mapSZSnapShot.ContainsKey(StockCode.Trim())) { SZRecord = mapSZSnapShot[StockCode.Trim()]; return(true); } } } return(false); } catch (Exception err) { Common.Log(err); SHRecord.Clear(); SZRecord.Clear(); return(false); } }
public bool FindQuotation(string StockCode, out SjshqDBFRecord SZRecord) { SZRecord = new SjshqDBFRecord(); try { SZRecord.Clear(); if (StockCode == null || StockCode.Trim().Length != 6) return false; if (mapSZRates == null) return false; lock (mapSZRates) { if (mapSZRates.ContainsKey(StockCode.Trim())) { SZRecord = mapSZRates[StockCode.Trim()]; return true; } } return false; } catch (Exception err) { Loger.Debug(err); SZRecord.Clear(); return false; } }
/// <summary> /// ��ȡ��ʱ���� /// </summary> /// <param name="StockCode">��Ʊ����</param> /// <param name="Market">�г�</param> /// <param name="SHRecord">��֤���Ʊ����</param> /// <param name="SZRecord">��֤���Ʊ����</param> /// <returns></returns> public bool GetStkRate(string StockCode, TradingSystem.StockMarket Market, out Show2003DBFRecord SHRecord, out SjshqDBFRecord SZRecord) { SHRecord = new Show2003DBFRecord(); SZRecord = new SjshqDBFRecord(); try { SHRecord.Clear(); SZRecord.Clear(); if (StockCode == null || StockCode.Trim().Length <= 0 || Market == TradingSystem.StockMarket.Unknown) return false; //��֤���Ʊ if (Market == TradingSystem.StockMarket.Shanghai) { lock (mapSHSnapShot) { if (mapSHSnapShot == null || mapSHSnapShot.Count <= 0) return false; if (mapSHSnapShot.ContainsKey(StockCode.Trim())) { SHRecord = mapSHSnapShot[StockCode.Trim()]; return true; } } } //��֤���Ʊ else if (Market == TradingSystem.StockMarket.Shenzhen) { lock (mapSZSnapShot) { if (mapSZSnapShot == null || mapSZSnapShot.Count <= 0) return false; else if (mapSZSnapShot.ContainsKey(StockCode.Trim())) { SZRecord = mapSZSnapShot[StockCode.Trim()]; return true; } } } return false; } catch (Exception err) { Common.Log(err); SHRecord.Clear(); SZRecord.Clear(); 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="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="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="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="UserID"></param> /// <param name="StockCode"></param> /// <param name="Market"></param> /// <param name="Curr"></param> /// <param name="WannaBuy"></param> /// <returns></returns> public bool CanBuy(int UserID, string StockCode, StockMarket Market, Currency Curr, double WannaBuy) { try { if (UserID <= 0 || StockCode == null || StockCode.Trim().Length != 6 || Market == StockMarket.Unknown) return false; if (!mapUserFund.ContainsKey(UserID)) return false; if (!mapUserFund[UserID].ContainsKey((byte)Curr)) return false; double dValue = 0; lock (mapUserOrders) { foreach (object objKey in mapUserOrders.Keys) { if (objKey == null) continue; int nOrderID = Convert.ToInt32(objKey); if (!mapUserOrders.ContainsKey(nOrderID)) continue; if (mapUserOrders[nOrderID].UserID == UserID && string.Compare(StockCode.Trim(), mapUserOrders[nOrderID].StockCode.Trim()) == 0 && Market == mapUserOrders[nOrderID].Market && mapUserOrders[nOrderID].Side && (mapUserOrders[nOrderID].OrdStatus == OrderStatus.Cancelling || mapUserOrders[nOrderID].OrdStatus == OrderStatus.Waiting) && Curr == mapUserOrders[nOrderID].Curr) dValue += (mapUserOrders[nOrderID].OrderPrice * mapUserOrders[nOrderID].OrderVolume * (1 + defaultBuyTax)); } } Show2003DBFRecord SHRate = new Show2003DBFRecord(); SHRate.Clear(); SjshqDBFRecord SZRate = new SjshqDBFRecord(); SZRate.Clear(); double PreClose = 0; if (Common.stkQuotation.GetStkRate(StockCode.Trim(), Market, out SHRate, out SZRate)) { switch (Market) { case StockMarket.Shanghai: PreClose = SHRate.PreClosePrice; break; case StockMarket.Shenzhen: PreClose = SZRate.PreClosePrice; break; } } lock (mapUserStocks) { if (mapUserStocks.ContainsKey(UserID)) { foreach (UserStocks data in mapUserStocks[UserID]) { if (data.UserID == UserID && string.Compare(StockCode.Trim(), data.StockCode.Trim()) == 0 && Market == data.Market && Curr == data.Curr) { if (PreClose >= 0.001) dValue += (PreClose * data.Volume); else dValue += (data.AveragePrice * data.Volume); } } } } double dMax = mapUserFund[UserID][(byte)Curr].Wealth; if (defaultSingleStockRate > 0) dMax *= defaultSingleStockRate; if (dValue + WannaBuy > dMax) return false; else return true; } catch { return false; } }
/// <summary> /// ������ת���� /// </summary> private void Trading() { try { ushort uFlag = 0; List<int> listUserOrdersKeys = new List<int>(); //�ʽ𣬶������ֹɽԲ�Ϊ��ʱ��ϵͳ������� while (bTrading && mapUserFund != null && mapUserOrders != null && mapUserStocks != null) { try { if (!Management.Work || Common.IsWeekend) { Thread.Sleep(30000); continue; } else { //���ڽӿڿ���ʱ�� if (Common.IsInInterfaceQuotationTime) { //ͳ�ƻ����еļ�ʱ�������۶���������������ί���� int ICount = 0, LCount = 0, CCount = 0; if (++uFlag % 500 == 0 && GetTotalWaitingOrdersCount(out ICount, out LCount, out CCount)) { Common.Log("--- Orders in Buffer (Total: " + (ICount + LCount + CCount) + ") ---" + Environment.NewLine + "[ImmediateOrder=" + ICount + "] [LimitedOrder=" + LCount + "] [CancelOrder=" + CCount + "]"); uFlag = 0; } } //���ڽ���ʱ�Σ�����ʱ��ֱ�Ӻ��� if (DateTime.Now.TimeOfDay < Common.BeginAMTS || DateTime.Now.TimeOfDay > Common.EndPMTS.Add(new TimeSpan(0, 5, 0))) { Thread.Sleep(30000); continue; } } //���������Ϣ if (Common.stkQuotation != null && mapUserOrders.Count > 0 && Common.stkQuotation.GetSnapShot()) { int nOrderID = -1; listUserOrdersKeys.Clear(); Show2003DBFRecord SHRate = new Show2003DBFRecord(); SHRate.Clear(); SjshqDBFRecord SZRate = new SjshqDBFRecord(); SZRate.Clear(); foreach (object objKey in mapUserOrders.Keys) { if (objKey == null) continue; nOrderID = Convert.ToInt32(objKey); if (nOrderID < 0 || !mapUserOrders.ContainsKey(nOrderID)) continue; listUserOrdersKeys.Add(nOrderID);//���붩��ID������������� } //�Լ��뵽����������еĶ������д��� foreach (int OrderKey in listUserOrdersKeys) { try { if (!mapUserOrders.ContainsKey(OrderKey)) continue; UserOrders userOrder = mapUserOrders[OrderKey]; if (!mapUserFund.ContainsKey(userOrder.UserID)) continue; Dictionary<byte, UserFund> mapCurrFund = mapUserFund[userOrder.UserID]; if (!mapCurrFund.ContainsKey((byte)userOrder.Curr)) continue; UserFund userFund = mapCurrFund[(byte)userOrder.Curr]; if (userOrder.StockCode == null || userOrder.StockCode.Trim().Length <= 0 || userOrder.Market == StockMarket.Unknown || userOrder.OrdStatus == OrderStatus.Unknown) { mapUserOrders.Remove(OrderKey); } else if (userOrder.OrdStatus != OrderStatus.Waiting && userOrder.OrdStatus != OrderStatus.Cancelling) { continue; } else { if (userOrder.ExpiredDate < DateTime.Now && (userOrder.OrdStatus == OrderStatus.Waiting || userOrder.OrdStatus == OrderStatus.Cancelling)) { #region �ö����ѹ��� userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; Common.DBSync.RecordError(userOrder, "���ڶ�����" + userOrder.ExpiredDate.ToString("yyyy-MM-dd HH:mm:ss").Trim()); if (userOrder.OrdType == TradingSystem.OrderType.LimitedOrder) { userFund.UsableCash += Common.ConvertPrice((userOrder.OrderPrice * userOrder.OrderVolume) * (1 + Common.stkTrading.defaultBuyTax)); if (!Common.DBSync.FundUpdate(userFund, userOrder.UserID)) continue; SetUserFund(userFund.UserID, userFund); } if (Common.DBSync.OrderChanged(mapCurrFund[(byte)userFund.Curr], userOrder, new UserStocks())) { lock (mapUserFund) mapUserFund[userOrder.UserID] = mapCurrFund; lock (mapUserOrders) mapUserOrders[OrderKey] = userOrder; Common.Debug("Order Status Changed [" + userOrder.OrdStatus.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "]."); } #endregion } else if (userOrder.OrdStatus == OrderStatus.Cancelling) { #region ȡ������ if (userOrder.OrdType == OrderType.LimitedOrder) { userOrder.OrdStatus = OrderStatus.Cancelled; userOrder.UpdatedDate = DateTime.Now; if (Common.DBSync.OrderChanged(mapCurrFund[(byte)userFund.Curr], userOrder, new UserStocks())) { mapUserOrders[userOrder.OrderID] = userOrder; if (userOrder.Side) { UserFund usableFund = mapCurrFund[(byte)userFund.Curr]; usableFund.UsableCash += Common.ConvertPrice((userOrder.OrderVolume * userOrder.OrderPrice) * (1 + defaultBuyTax)); SetUserFund(usableFund.UserID, usableFund); Common.DBSync.FundUpdate(usableFund, userOrder.UserID); } Common.Debug("Order Status Changed [" + userOrder.OrdStatus.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "]."); } else { userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; lock (mapUserOrders) mapUserOrders[userOrder.OrderID] = userOrder; Common.DBSync.RecordError(userOrder, "����ʧ�ܣ��û�ID-" + userOrder.UserID + "������ID-" + userOrder.OrderID); } } else { userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; lock (mapUserOrders) mapUserOrders[userOrder.OrderID] = userOrder; Common.DBSync.RecordError(userOrder, "��Ч�������û�ID-" + userOrder.UserID + "������ID-" + userOrder.OrderID); } #endregion } else if (userOrder.OrdStatus == OrderStatus.Waiting && !Common.stkQuotation.GetStkRate(userOrder.StockCode, userOrder.Market, out SHRate, out SZRate)) { #region ��������� userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; Common.DBSync.RecordError(userOrder, "��������飺" + userOrder.StockCode.Trim() + "-" + userOrder.Market.ToString().Trim()); if (userOrder.OrdType == TradingSystem.OrderType.LimitedOrder) { userFund.UsableCash += Common.ConvertPrice((userOrder.OrderPrice * userOrder.OrderVolume) * (1 + Common.stkTrading.defaultBuyTax)); SetUserFund(userFund.UserID, userFund); if (!Common.DBSync.FundUpdate(userFund, userOrder.UserID)) continue; } if (Common.DBSync.OrderChanged(mapCurrFund[(byte)userFund.Curr], userOrder, new UserStocks())) { lock (mapUserFund) mapUserFund[userOrder.UserID] = mapCurrFund; lock (mapUserOrders) mapUserOrders[OrderKey] = userOrder; Common.Debug("Order Status Changed [" + userOrder.OrdStatus.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "]."); } #endregion } else if (userOrder.OrdStatus == OrderStatus.Waiting && (userOrder.Market == StockMarket.Shanghai && (SHRate.LatestPrice < 0.001 || SHRate.OpenPrice < 0.001)) || (userOrder.Market == StockMarket.Shenzhen && (SZRate.LatestPrice < 0.001 || SZRate.OpenPrice < 0.001))) { #region �ù�Ʊͣ�� userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; Common.DBSync.RecordError(userOrder, "ͣ�ƹ�Ʊ��" + userOrder.StockCode.Trim() + "-" + userOrder.Market.ToString().Trim()); if (userOrder.OrdType == TradingSystem.OrderType.LimitedOrder) { userFund.UsableCash += Common.ConvertPrice((userOrder.OrderPrice * userOrder.OrderVolume) * (1 + Common.stkTrading.defaultBuyTax)); SetUserFund(userFund.UserID, userFund); if (!Common.DBSync.FundUpdate(userFund, userOrder.UserID)) continue; } if (Common.DBSync.OrderChanged(mapCurrFund[(byte)userFund.Curr], userOrder, new UserStocks())) { lock (mapUserFund) mapUserFund[userOrder.UserID] = mapCurrFund; lock (mapUserOrders) mapUserOrders[OrderKey] = userOrder; Common.Debug("Order Status Changed [" + userOrder.OrdStatus.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "]."); } #endregion } else { if (userOrder.OrdStatus == OrderStatus.Waiting) { double dBargainAmount = 0; List<UserStocks> listUserStocks = new List<UserStocks>(); if (mapUserStocks.ContainsKey(userOrder.UserID)) listUserStocks = mapUserStocks[userOrder.UserID]; else mapUserStocks[userOrder.UserID] = new List<UserStocks>(); UserStocks userStock = new UserStocks(); userStock.Initialize(); bool bExist = false; for (int i = 0; i < listUserStocks.Count; i++) { if (listUserStocks[i].UserID == userOrder.UserID && string.Compare(userOrder.StockCode.Trim() , listUserStocks[i].StockCode.Trim()) == 0 && userOrder.Market == listUserStocks[i].Market && ((!userOrder.Side && listUserStocks[i].Sellable) || (userOrder.Side && !listUserStocks[i].Sellable))) { bExist = true; userStock = listUserStocks[i]; break; } } if (!bExist) { userStock.UserID = userOrder.UserID; userStock.StockCode = userOrder.StockCode.Trim(); userStock.Market = userOrder.Market; userStock.Sellable = false; } switch (userOrder.OrdType) { #region �м۽��� case OrderType.ImmediateOrder: { Common.Debug("--- [ImmediateOrder] Received. ---"); if (userOrder.Side) { // ���� if (userOrder.Market == StockMarket.Shanghai) { if (SHRate.SellingVal1 < 0.001 || Common.ComparePrice(SHRate.HighestPrice, SHRate.LowestPrice) <= 0) { userOrder.OrderPrice = SHRate.SellingVal1; if (Common.ComparePrice(userFund.UsableCash, (SHRate.SellingVal1 * userOrder.OrderVolume) * (1 + defaultBuyTax)) < 0) { userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; } else { userOrder.OrdType = OrderType.LimitedOrder; Common.DBSync.OrderChanged(userFund, userOrder, new UserStocks()); userFund.UsableCash -= Common.ConvertPrice((userOrder.OrderPrice * userOrder.OrderVolume) * (1 + defaultBuyTax) + 0.0099); Common.DBSync.FundUpdate(userFund, userOrder.UserID); mapCurrFund[(byte)userFund.Curr] = userFund; mapUserFund[userOrder.UserID] = mapCurrFund; mapUserOrders[OrderKey] = userOrder; Common.Debug("Order Type Changed [" + userOrder.OrdType.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "]."); } } else { userOrder.OrderPrice = SHRate.SellingVal1; if (Common.ComparePrice(userFund.UsableCash, (SHRate.SellingVal1 * userOrder.OrderVolume) * (1 + defaultBuyTax)) < 0) { userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; } else if (BuySH(ref SHRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount)) { UpdateUserStock(ref listUserStocks, userStock); userFund.UsableCash -= Common.ConvertPrice((SHRate.SellingVal1 * userOrder.OrderVolume) * (1 + defaultBuyTax) + 0.0099); Common.DBSync.FundUpdate(userFund, userOrder.UserID); } } } else if (userOrder.Market == StockMarket.Shenzhen) { if (SZRate.SellingVal1 < 0.001 || Common.ComparePrice(SZRate.HighestPrice, SZRate.LowestPrice) <= 0) { userOrder.OrderPrice = SZRate.SellingVal1; if (Common.ComparePrice(userFund.UsableCash, (SZRate.SellingVal1 * userOrder.OrderVolume) * (1 + defaultBuyTax)) < 0) { userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; } else { userOrder.OrdType = OrderType.LimitedOrder; Common.DBSync.OrderChanged(userFund, userOrder, new UserStocks()); userFund.UsableCash -= Common.ConvertPrice((userOrder.OrderPrice * userOrder.OrderVolume) * (1 + defaultBuyTax) + 0.0099); Common.DBSync.FundUpdate(userFund, userOrder.UserID); mapCurrFund[(byte)userFund.Curr] = userFund; mapUserFund[userOrder.UserID] = mapCurrFund; mapUserOrders[OrderKey] = userOrder; Common.Debug("Order Type Changed [" + userOrder.OrdType.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "]."); } } else { userOrder.OrderPrice = SHRate.SellingVal1; if (Common.ComparePrice(userFund.UsableCash, (SHRate.SellingVal1 * userOrder.OrderVolume) * (1 + defaultBuyTax)) < 0) { userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; } else if (BuySZ(ref SZRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount)) { UpdateUserStock(ref listUserStocks, userStock); userFund.UsableCash -= Common.ConvertPrice((SZRate.SellingVal1 * userOrder.OrderVolume) * (1 + defaultBuyTax) + 0.0099); Common.DBSync.FundUpdate(userFund, userOrder.UserID); } } } } else { // ��� if (userOrder.Market == StockMarket.Shanghai) { if (SHRate.BuyingVal1 < 0.001 || Common.ComparePrice(SHRate.HighestPrice, SHRate.LowestPrice) <= 0) { userOrder.OrderPrice = SHRate.BuyingVal1; userOrder.OrdType = OrderType.LimitedOrder; Common.DBSync.OrderChanged(userFund, userOrder, new UserStocks()); mapUserOrders[OrderKey] = userOrder; Common.Debug("Order Type Changed [" + userOrder.OrdType.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "]."); } else if (SellSH(ref SHRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount)) { userOrder.OrderPrice = SHRate.BuyingVal1; UpdateUserStock(ref listUserStocks, userStock); Common.DBSync.FundUpdate(userFund, userOrder.UserID); } } else if (userOrder.Market == StockMarket.Shenzhen) { if (SZRate.BuyingVal1 < 0.001 || Common.ComparePrice(SZRate.HighestPrice, SZRate.LowestPrice) <= 0) { userOrder.OrderPrice = SZRate.BuyingVal1; userOrder.OrdType = OrderType.LimitedOrder; Common.DBSync.OrderChanged(userFund, userOrder, new UserStocks()); mapUserOrders[OrderKey] = userOrder; Common.Debug("Order Type Changed [" + userOrder.OrdType.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "]."); } else if (SellSZ(ref SZRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount)) { userOrder.OrderPrice = SZRate.BuyingVal1; UpdateUserStock(ref listUserStocks, userStock); Common.DBSync.FundUpdate(userFund, userOrder.UserID); } } } } break; #endregion #region �۽��� case OrderType.LimitedOrder: { if (userOrder.Side) { // ���� if (userOrder.Market == StockMarket.Shanghai && SHRate.SellingVal1 >= 0.001 && Common.ComparePrice(SHRate.HighestPrice, SHRate.LowestPrice) > 0 && Common.ComparePrice(SHRate.SellingVal1, userOrder.OrderPrice) <= 0) { if (IsOrderValid(ref SHRate, ref userFund, ref userOrder) && BuySH(ref SHRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount)) UpdateUserStock(ref listUserStocks, userStock); Common.DBSync.FundUpdate(userFund, userOrder.UserID); } else if (userOrder.Market == StockMarket.Shenzhen && SZRate.SellingVal1 >= 0.001 && Common.ComparePrice(SZRate.HighestPrice, SZRate.LowestPrice) > 0 && Common.ComparePrice(SZRate.SellingVal1, userOrder.OrderPrice) <= 0) { if (IsOrderValid(ref SZRate, ref userFund, ref userOrder) && BuySZ(ref SZRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount)) UpdateUserStock(ref listUserStocks, userStock); Common.DBSync.FundUpdate(userFund, userOrder.UserID); } } else { // ��� if (userOrder.Market == StockMarket.Shanghai && SHRate.BuyingVal1 >= 0.001 && Common.ComparePrice(SHRate.HighestPrice, SHRate.LowestPrice) > 0 && Common.ComparePrice(SHRate.BuyingVal1, userOrder.OrderPrice) >= 0) { if (IsOrderValid(ref SHRate, ref userFund, ref userOrder) && SellSH(ref SHRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount)) UpdateUserStock(ref listUserStocks, userStock); Common.DBSync.FundUpdate(userFund, userOrder.UserID); } else if (userOrder.Market == StockMarket.Shenzhen && SZRate.BuyingVal1 >= 0.001 && Common.ComparePrice(SZRate.HighestPrice, SZRate.LowestPrice) > 0 && Common.ComparePrice(SZRate.BuyingVal1, userOrder.OrderPrice) >= 0) { if (IsOrderValid(ref SZRate, ref userFund, ref userOrder) && SellSZ(ref SZRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount)) UpdateUserStock(ref listUserStocks, userStock); Common.DBSync.FundUpdate(userFund, userOrder.UserID); } } } break; #endregion default: { userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; Common.DBSync.RecordError(userOrder, "δ֪�Ķ������ͣ�" + userOrder.OrdType.ToString().Trim()); lock (mapUserOrders) mapUserOrders[OrderKey] = userOrder; } break; } if (userOrder.OrdStatus != OrderStatus.Waiting && Common.DBSync.OrderChanged(userFund, userOrder, userStock)) { SetUserFund(userFund.UserID, userFund); lock (mapUserOrders) mapUserOrders[OrderKey] = userOrder; lock (mapUserStocks) mapUserStocks[userOrder.UserID] = listUserStocks; Common.Debug("Order Status Changed [" + userOrder.OrdStatus.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "]."); } } else Common.Log("Illegal Order Status [" + userOrder.OrdStatus.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "]."); } } } catch (Exception err) { Common.Log(err); } } } lock (listNewUserFund) { if (listNewUserFund.Count > 0) { for (int i = 0; i < listNewUserFund.Count; i++) { if (!mapUserFund.ContainsKey(listNewUserFund[i].UserID)) { mapUserFund[listNewUserFund[i].UserID] = new Dictionary<byte, UserFund>(); Dictionary<byte, UserFund> mapCurrFund = mapUserFund[listNewUserFund[i].UserID]; mapCurrFund[(byte)listNewUserFund[i].Curr] = listNewUserFund[i]; mapUserFund[listNewUserFund[i].UserID] = mapCurrFund; } else if (!mapUserFund[listNewUserFund[i].UserID].ContainsKey((byte)listNewUserFund[i].Curr)) { Dictionary<byte, UserFund> mapCurrFund = mapUserFund[listNewUserFund[i].UserID]; mapCurrFund[(byte)listNewUserFund[i].Curr] = listNewUserFund[i]; mapUserFund[listNewUserFund[i].UserID] = mapCurrFund; } } listNewUserFund.Clear(); } } lock (listNewUserOrders) { if (listNewUserOrders.Count > 0) { for (int i = 0; i < listNewUserOrders.Count; i++) { if (!mapUserOrders.ContainsKey(listNewUserOrders[i].OrderID)) mapUserOrders[listNewUserOrders[i].OrderID] = listNewUserOrders[i]; } listNewUserOrders.Clear(); } } } catch (Exception err) { Common.Log(err); } Thread.Sleep(1000); } } catch (Exception err) { Common.Log(err); if (Common.DBSync != null) Common.DBSync.Uninitialize(mapUserFund, mapUserOrders, mapUserStocks); Common.Log("Error: The Trading Thread Has Crashed !"); } }
private void InvokeGetWealth(ref Dictionary<int,UserRank> m_mapDailyRank) { Show2003DBFRecord SHRecord = new Show2003DBFRecord(); SHRecord.Clear(); SjshqDBFRecord SZRecord = new SjshqDBFRecord(); SZRecord.Clear(); Dictionary<int, UserRank> t_mapDailyRank = new Dictionary<int, UserRank>(m_mapDailyRank); foreach (var user in t_mapDailyRank) { UserRank currRank = new UserRank(); currRank = user.Value; int userId = currRank.UserId; zns.ITransactionRemotingProvider cRmt = null; foreach (var s in BaseConfig.mapNotifySrv) { if (currRank.UserDataBase == s.Value.DataBaseChar) { cRmt = znRmtIobj[s.Key]; break; } } //SaveBuffer(cRmt,userId); #region 各币种股票总市值 double StocksWealthRMB = 0; double StocksWealthUSD = 0; double StocksWealthHKD = 0; double tempOneStockWealth = 0; double StocksWealth = 0; //所有币种股票总市值 List<zns.Interface.RI_Stock> listStock = new List<EastMoney.StocksTrader.RemotingProvider.Interface.RI_Stock>(); listStock = cRmt.RequestUserStocks(BaseConfig.RmtUserKey, userId); if (listStock != null) { foreach (zns.Interface.RI_Stock stock in listStock) { tempOneStockWealth = 0; if (stock.StockMarket == zns.Interface.RI_Market.Shanghai) { if (QuoteSvc.FindQuotation(stock.StockCode, out SHRecord)) { if (SHRecord.LatestPrice < 0.001 || SHRecord.OpenPrice < 0.001) tempOneStockWealth = ConvertPrice(SHRecord.PreClosePrice) * stock.Volume; else tempOneStockWealth = ConvertPrice(SHRecord.LatestPrice) * stock.Volume; } } else if (stock.StockMarket == zns.Interface.RI_Market.Shenzhen) { if (QuoteSvc.FindQuotation(stock.StockCode, out SZRecord)) { if (SZRecord.LatestPrice < 0.001 || SZRecord.OpenPrice < 0.001) tempOneStockWealth = ConvertPrice(SZRecord.PreClosePrice) * stock.Volume; else tempOneStockWealth = ConvertPrice(SZRecord.LatestPrice) * stock.Volume; } } switch (stock.Curr) { case zns.Interface.RI_Currency.RMB: StocksWealthRMB += tempOneStockWealth; break; case zns.Interface.RI_Currency.USD: StocksWealthUSD += tempOneStockWealth; break; case zns.Interface.RI_Currency.HKD: StocksWealthHKD += tempOneStockWealth; break; } } StocksWealth = StocksWealthRMB + StocksWealthUSD * BaseConfig.RateUSD + StocksWealthHKD * BaseConfig.RateHKD; } #endregion #region 各币种现金 double CashRMB = 0; double CashUSD = 0; double CashHKD = 0; Dictionary<byte, zns.Interface.RI_Fund> mapUserFund = new Dictionary<byte, EastMoney.StocksTrader.RemotingProvider.Interface.RI_Fund>(); mapUserFund = cRmt.RequestUserFund(BaseConfig.RmtUserKey, userId); if (mapUserFund != null) { foreach (KeyValuePair<byte, zns.Interface.RI_Fund> fund in mapUserFund) { switch ((zns.Interface.RI_Currency)fund.Key) { case zns.Interface.RI_Currency.RMB: CashRMB = fund.Value.Cash; break; case zns.Interface.RI_Currency.USD: CashUSD = fund.Value.Cash; break; case zns.Interface.RI_Currency.HKD: CashHKD = fund.Value.Cash; break; } } } #endregion #region 各币种现有总资产 double WealthRMB = 0; double WealthUSD = 0; double WealthHKD = 0; double Wealth = 0; WealthRMB = StocksWealthRMB + CashRMB; WealthUSD = StocksWealthUSD + CashUSD; WealthHKD = StocksWealthHKD + CashHKD; Wealth = WealthRMB + WealthUSD * BaseConfig.RateUSD + WealthHKD * BaseConfig.RateHKD; #endregion #region 持仓比例 double RatioRMB = 0; double RatioUSD = 0; double RatioHKD = 0; if (WealthRMB > 0) { RatioRMB = 1 - (CashRMB / WealthRMB); if (RatioRMB > 1) RatioRMB = 1; else if (RatioRMB < 0) RatioRMB = 0; } else { RatioRMB = 0; } if (WealthUSD > 0) { RatioUSD = 1 - (CashUSD / WealthUSD); if (RatioUSD > 1) RatioUSD = 1; else if (RatioUSD < 0) RatioUSD = 0; } else { RatioUSD = 0; } if (WealthHKD > 0) { RatioHKD = 1 - (CashHKD / WealthHKD); if (RatioHKD > 1) RatioHKD = 1; else if (RatioHKD < 0) RatioHKD = 0; } else { RatioHKD = 0; } #endregion #region 收益率 double Profit = 0; double InitCash = BaseConfig.InitCashRMB + BaseConfig.InitCashUSD * BaseConfig.RateUSD + BaseConfig.InitCashHKD * BaseConfig.RateHKD; Profit = (Wealth - InitCash) / InitCash * 100; if (Wealth == 0) Profit = 0; #endregion currRank.Wealth = Wealth; currRank.WealthRMB = WealthRMB; currRank.WealthUSD = WealthUSD; currRank.WealthHKD = WealthHKD; currRank.StockWealth = StocksWealth; currRank.RatioRMB = RatioRMB; currRank.RatioUSD = RatioUSD; currRank.RatioHKD = RatioHKD; if (currRank.RatioRMB < BaseConfig.RatioBaseLine) currRank.RatioUnderDays = 1; else currRank.RatioUnderDays = 0; currRank.Profit = Profit; currRank.DailyProfit = Profit; //初始时用当日收益,后面会修正 currRank.RankDate = CurrDay.Date; m_mapDailyRank[userId] = currRank; } }
/// <summary> /// 计算当日资产 /// </summary> /// <returns></returns> public static bool ProcWealth() { bool bInTransaction = false; try { Loger.Debug(">>> Processing [Wealth] Started ! <<<"); if (!Common.QuoteSvc.ReloadQuotation()) { Loger.Debug("--- Reloading Quotation Failed. ---"); return false; } Show2003DBFRecord SHRecord = new Show2003DBFRecord(); SHRecord.Clear(); SjshqDBFRecord SZRecord = new SjshqDBFRecord(); SZRecord.Clear(); Dictionary<int, UserRank> mapUserWealth = new Dictionary<int, UserRank>(); if (sqlConn.State == ConnectionState.Closed) sqlConn.Open(); sqlTrans = sqlConn.BeginTransaction(); bInTransaction = true; //读取指定活动参与交易的用户列表 sqlCmd = new SqlCommand(@"emtradeplay.dbo.GetTradeUserListByPlayId", sqlConn, sqlTrans); sqlCmd.Parameters.Add("@playId", SqlDbType.Int).Value = BaseConfig.PlayId; sqlReader = sqlCmd.ExecuteReader(); int nUser = 0; while (sqlReader.Read()) { int userId = Convert.ToInt32(sqlReader["UserId"]); string userDataBase = sqlReader["UserDataBase"].ToString(); if (userDataBase == null || userDataBase == string.Empty) { Loger.Debug("--- warning : userId = " + userId + " DataBase = null ---"); continue; } zns.RemotingInterface cRmt = null; foreach (KeyValuePair<int, NotifySrv> s in BaseConfig.mapNotifySrv) { if (userDataBase == s.Value.DataBaseChar) { cRmt = Common.znRmtIobj[s.Key]; break; } } #region 各币种股票总市值 double StocksWealthRMB = 0; double StocksWealthUSD = 0; double StocksWealthHKD = 0; double tempOneStockWealth = 0; double StocksWealth = 0; //所有币种股票总市值 List<zns.RemotingInterface.RI_Stock> listStock = new List<Stock_Trading_Simulator_Kernel.RemotingInterface.RI_Stock>(); listStock = cRmt.RequestUserStocks(BaseConfig.RmtUserKey, userId); if (listStock != null) { foreach (zns.RemotingInterface.RI_Stock stock in listStock) { tempOneStockWealth = 0; if (stock.StockMarket == zns.RemotingInterface.RI_Market.Shanghai) { if (Common.QuoteSvc.FindQuotation(stock.StockCode, out SHRecord)) { if (SHRecord.LatestPrice < 0.001 || SHRecord.OpenPrice < 0.001) tempOneStockWealth = ConvertPrice(SHRecord.PreClosePrice) * stock.Volume; else tempOneStockWealth = ConvertPrice(SHRecord.LatestPrice) * stock.Volume; } } else if (stock.StockMarket == zns.RemotingInterface.RI_Market.Shenzhen) { if (Common.QuoteSvc.FindQuotation(stock.StockCode, out SZRecord)) { if (SZRecord.LatestPrice < 0.001 || SZRecord.OpenPrice < 0.001) tempOneStockWealth = ConvertPrice(SZRecord.PreClosePrice) * stock.Volume; else tempOneStockWealth = ConvertPrice(SZRecord.LatestPrice) * stock.Volume; } } switch (stock.Curr) { case zns.RemotingInterface.RI_Currency.RMB: StocksWealthRMB += tempOneStockWealth; break; case zns.RemotingInterface.RI_Currency.USD: StocksWealthUSD += tempOneStockWealth; break; case zns.RemotingInterface.RI_Currency.HKD: StocksWealthHKD += tempOneStockWealth; break; } } StocksWealth = StocksWealthRMB + StocksWealthUSD * BaseConfig.RateUSD + StocksWealthHKD * BaseConfig.RateHKD; } #endregion #region 各币种现金 double CashRMB = 0; double CashUSD = 0; double CashHKD = 0; Dictionary<byte, zns.RemotingInterface.RI_Fund> mapUserFund = new Dictionary<byte, Stock_Trading_Simulator_Kernel.RemotingInterface.RI_Fund>(); mapUserFund = cRmt.RequestUserFund(BaseConfig.RmtUserKey, userId); if (mapUserFund != null) { foreach (KeyValuePair<byte, zns.RemotingInterface.RI_Fund> fund in mapUserFund) { switch ((zns.RemotingInterface.RI_Currency)fund.Key) { case zns.RemotingInterface.RI_Currency.RMB: CashRMB = fund.Value.Cash; break; case zns.RemotingInterface.RI_Currency.USD: CashUSD = fund.Value.Cash; break; case zns.RemotingInterface.RI_Currency.HKD: CashHKD = fund.Value.Cash; break; } } } #endregion #region 各币种现有总资产 double WealthRMB = 0; double WealthUSD = 0; double WealthHKD = 0; double Wealth = 0; WealthRMB = StocksWealthRMB + CashRMB; WealthUSD = StocksWealthUSD + CashUSD; WealthHKD = StocksWealthHKD + CashHKD; Wealth = WealthRMB + WealthUSD * BaseConfig.RateUSD + WealthHKD * BaseConfig.RateHKD; #endregion #region 持仓比例 double RatioRMB = 0; double RatioUSD = 0; double RatioHKD = 0; if (WealthRMB > 0) { RatioRMB = 1 - (CashRMB / WealthRMB); if (RatioRMB > 1) RatioRMB = 1; else if (RatioRMB < 0) RatioRMB = 0; } else { RatioRMB = 0; } if (WealthUSD > 0) { RatioUSD = 1 - (CashUSD / WealthUSD); if (RatioUSD > 1) RatioUSD = 1; else if (RatioUSD < 0) RatioUSD = 0; } else { RatioUSD = 0; } if (WealthHKD > 0) { RatioHKD = 1 - (CashHKD / WealthHKD); if (RatioHKD > 1) RatioHKD = 1; else if (RatioHKD < 0) RatioHKD = 0; } else { RatioHKD = 0; } #endregion #region 收益率 double Profit = 0; double InitCash = BaseConfig.InitCashRMB + BaseConfig.InitCashUSD * BaseConfig.RateUSD + BaseConfig.InitCashHKD * BaseConfig.RateHKD; Profit = (Wealth - InitCash) / InitCash * 100; if (Wealth == 0) Profit = 0; #endregion UserRank data = new UserRank(); data.Initialize(); data.UserId = userId; data.AreaId = (int)sqlReader["AreaId"]; data.UserName = sqlReader["UserName"].ToString(); data.UserDataBase = sqlReader["UserDataBase"].ToString(); data.Wealth = Wealth; data.WealthRMB = WealthRMB; data.WealthUSD = WealthUSD; data.WealthHKD = WealthHKD; data.StockWealth = StocksWealth; data.RatioRMB = RatioRMB; data.RatioUSD = RatioUSD; data.RatioHKD = RatioHKD; data.Profit = Profit; data.RankDate = DateTime.Now.Date; mapUserWealth[userId] = data; nUser++; } //while(sqlReader.Read()) end sqlReader.Close(); Loger.Debug("---calculate [StocksWealth] [Cash] [Wealth] [Ratio] [Profit] finished . UserCount = " + nUser + "---"); #region 根据已更新的资产缓存更新数据库表 int nUserID = 0; sqlCmd = new SqlCommand("DELETE FROM [DailyRank]", sqlConn, sqlTrans); sqlCmd.ExecuteNonQuery(); nUser = 0; foreach (var data in mapUserWealth) { sqlCmd = new SqlCommand("INSERT INTO [DailyRank] (UserID,AreaId,UserName,UserDataBase,Wealth, WealthRMB, WealthUSD, WealthHKD,StockWealth, " + "Profit, DailyProfit, WeeklyProfit, MonthlyProfit, RatioRMB, RatioUSD, RatioHKD, RatioUnderDays, RankDate) " + "VALUES (@UserID,@AreaId,@UserName,@UserDataBase, @Wealth, @WealthRMB, @WealthUSD, @WealthHKD,@StockWealth," + "@Profit, @DailyProfit, @WeeklyProfit, @MonthlyProfit, @RatioRMB, @RatioUSD, @RatioHKD, @RatioUnderDays, @RankDate)", sqlConn, sqlTrans); //用户信息 sqlCmd.Parameters.Add("@UserID", SqlDbType.Int).Value = data.Value.UserId; sqlCmd.Parameters.Add("@AreaId", SqlDbType.Int).Value = data.Value.AreaId; sqlCmd.Parameters.Add("@UserName", SqlDbType.VarChar, 32).Value = data.Value.UserName; sqlCmd.Parameters.Add("@UserDataBase", SqlDbType.VarChar, 16).Value = data.Value.UserDataBase; //资产总值 sqlCmd.Parameters.Add("@Wealth", SqlDbType.Money).Value = data.Value.Wealth; sqlCmd.Parameters.Add("@WealthRMB", SqlDbType.Money).Value = data.Value.WealthRMB; sqlCmd.Parameters.Add("@WealthUSD", SqlDbType.Money).Value = data.Value.WealthUSD; sqlCmd.Parameters.Add("@WealthHKD", SqlDbType.Money).Value = data.Value.WealthHKD; //股票市值 sqlCmd.Parameters.Add("@StockWealth", SqlDbType.Money).Value = data.Value.StockWealth; //收益率 sqlCmd.Parameters.Add("@Profit", SqlDbType.Money).Value = data.Value.Profit; sqlCmd.Parameters.Add("@DailyProfit", SqlDbType.Money).Value = data.Value.DailyProfit; sqlCmd.Parameters.Add("@WeeklyProfit", SqlDbType.Money).Value = data.Value.WeeklyProfit; sqlCmd.Parameters.Add("@MonthlyProfit", SqlDbType.Money).Value = data.Value.MonthlyProfit; //持仓比例 sqlCmd.Parameters.Add("@RatioRMB", SqlDbType.Money).Value = data.Value.RatioRMB; sqlCmd.Parameters.Add("@RatioUSD", SqlDbType.Money).Value = data.Value.RatioUSD; sqlCmd.Parameters.Add("@RatioHKD", SqlDbType.Money).Value = data.Value.RatioHKD; //低于持仓标准的天数 if (mapUserWealth[nUserID].RatioRMB < BaseConfig.RatioBaseLine) //当日持仓未达标则记录 { sqlCmd.Parameters.Add("@RatioUnderDays", SqlDbType.Int).Value = 1; } else { sqlCmd.Parameters.Add("@RatioUnderDays", SqlDbType.Int).Value = 0; } //排名日期 sqlCmd.Parameters.Add("@RankDate", SqlDbType.DateTime).Value = data.Value.RankDate.ToString("yyyy-MM-dd"); sqlCmd.ExecuteNonQuery(); nUser++; } Loger.Debug("---Update table dailyrank finished . userCount = " + nUser + "---"); #endregion #region 当天排名数据备份到单独表 sqlCmd = new SqlCommand("CreateHistoryRankByDate", sqlConn, sqlTrans); sqlCmd.ExecuteNonQuery(); #endregion sqlTrans.Commit(); Loger.Debug("<<< Processing [Wealth] Finished ! >>>"); bWealthDone = true; return true; } catch (Exception err) { Loger.Debug("ProcWealth error :"+err); if (bInTransaction && sqlTrans != null && sqlTrans.Connection != null && sqlTrans.Connection.State == ConnectionState.Open) { if (sqlReader != null && !sqlReader.IsClosed) sqlReader.Close(); sqlTrans.Rollback(); } return false; } finally { if (sqlConn.State != ConnectionState.Closed) sqlConn.Close(); } }
/// <summary> /// 计算当日资产 /// </summary> /// <returns></returns> public static bool ProcWealth() { bool bInTransaction = false; try { Loger.Debug(">>> Processing [Wealth] Started ! <<<"); if (!Common.QuoteSvc.ReloadQuotation()) { Loger.Debug("--- Reloading Quotation Failed. ---"); return(false); } Show2003DBFRecord SHRecord = new Show2003DBFRecord(); SHRecord.Clear(); SjshqDBFRecord SZRecord = new SjshqDBFRecord(); SZRecord.Clear(); Dictionary <int, UserRank> mapUserWealth = new Dictionary <int, UserRank>(); if (sqlConn.State == ConnectionState.Closed) { sqlConn.Open(); } sqlTrans = sqlConn.BeginTransaction(); bInTransaction = true; //读取指定活动参与交易的用户列表 sqlCmd = new SqlCommand(@"emtradeplay.dbo.GetTradeUserListByPlayId", sqlConn, sqlTrans); sqlCmd.Parameters.Add("@playId", SqlDbType.Int).Value = BaseConfig.PlayId; sqlReader = sqlCmd.ExecuteReader(); int nUser = 0; while (sqlReader.Read()) { int userId = Convert.ToInt32(sqlReader["UserId"]); string userDataBase = sqlReader["UserDataBase"].ToString(); if (userDataBase == null || userDataBase == string.Empty) { Loger.Debug("--- warning : userId = " + userId + " DataBase = null ---"); continue; } zns.RemotingInterface cRmt = null; foreach (KeyValuePair <int, NotifySrv> s in BaseConfig.mapNotifySrv) { if (userDataBase == s.Value.DataBaseChar) { cRmt = Common.znRmtIobj[s.Key]; break; } } #region 各币种股票总市值 double StocksWealthRMB = 0; double StocksWealthUSD = 0; double StocksWealthHKD = 0; double tempOneStockWealth = 0; double StocksWealth = 0; //所有币种股票总市值 List <zns.RemotingInterface.RI_Stock> listStock = new List <Stock_Trading_Simulator_Kernel.RemotingInterface.RI_Stock>(); listStock = cRmt.RequestUserStocks(BaseConfig.RmtUserKey, userId); if (listStock != null) { foreach (zns.RemotingInterface.RI_Stock stock in listStock) { tempOneStockWealth = 0; if (stock.StockMarket == zns.RemotingInterface.RI_Market.Shanghai) { if (Common.QuoteSvc.FindQuotation(stock.StockCode, out SHRecord)) { if (SHRecord.LatestPrice < 0.001 || SHRecord.OpenPrice < 0.001) { tempOneStockWealth = ConvertPrice(SHRecord.PreClosePrice) * stock.Volume; } else { tempOneStockWealth = ConvertPrice(SHRecord.LatestPrice) * stock.Volume; } } } else if (stock.StockMarket == zns.RemotingInterface.RI_Market.Shenzhen) { if (Common.QuoteSvc.FindQuotation(stock.StockCode, out SZRecord)) { if (SZRecord.LatestPrice < 0.001 || SZRecord.OpenPrice < 0.001) { tempOneStockWealth = ConvertPrice(SZRecord.PreClosePrice) * stock.Volume; } else { tempOneStockWealth = ConvertPrice(SZRecord.LatestPrice) * stock.Volume; } } } switch (stock.Curr) { case zns.RemotingInterface.RI_Currency.RMB: StocksWealthRMB += tempOneStockWealth; break; case zns.RemotingInterface.RI_Currency.USD: StocksWealthUSD += tempOneStockWealth; break; case zns.RemotingInterface.RI_Currency.HKD: StocksWealthHKD += tempOneStockWealth; break; } } StocksWealth = StocksWealthRMB + StocksWealthUSD * BaseConfig.RateUSD + StocksWealthHKD * BaseConfig.RateHKD; } #endregion #region 各币种现金 double CashRMB = 0; double CashUSD = 0; double CashHKD = 0; Dictionary <byte, zns.RemotingInterface.RI_Fund> mapUserFund = new Dictionary <byte, Stock_Trading_Simulator_Kernel.RemotingInterface.RI_Fund>(); mapUserFund = cRmt.RequestUserFund(BaseConfig.RmtUserKey, userId); if (mapUserFund != null) { foreach (KeyValuePair <byte, zns.RemotingInterface.RI_Fund> fund in mapUserFund) { switch ((zns.RemotingInterface.RI_Currency)fund.Key) { case zns.RemotingInterface.RI_Currency.RMB: CashRMB = fund.Value.Cash; break; case zns.RemotingInterface.RI_Currency.USD: CashUSD = fund.Value.Cash; break; case zns.RemotingInterface.RI_Currency.HKD: CashHKD = fund.Value.Cash; break; } } } #endregion #region 各币种现有总资产 double WealthRMB = 0; double WealthUSD = 0; double WealthHKD = 0; double Wealth = 0; WealthRMB = StocksWealthRMB + CashRMB; WealthUSD = StocksWealthUSD + CashUSD; WealthHKD = StocksWealthHKD + CashHKD; Wealth = WealthRMB + WealthUSD * BaseConfig.RateUSD + WealthHKD * BaseConfig.RateHKD; #endregion #region 持仓比例 double RatioRMB = 0; double RatioUSD = 0; double RatioHKD = 0; if (WealthRMB > 0) { RatioRMB = 1 - (CashRMB / WealthRMB); if (RatioRMB > 1) { RatioRMB = 1; } else if (RatioRMB < 0) { RatioRMB = 0; } } else { RatioRMB = 0; } if (WealthUSD > 0) { RatioUSD = 1 - (CashUSD / WealthUSD); if (RatioUSD > 1) { RatioUSD = 1; } else if (RatioUSD < 0) { RatioUSD = 0; } } else { RatioUSD = 0; } if (WealthHKD > 0) { RatioHKD = 1 - (CashHKD / WealthHKD); if (RatioHKD > 1) { RatioHKD = 1; } else if (RatioHKD < 0) { RatioHKD = 0; } } else { RatioHKD = 0; } #endregion #region 收益率 double Profit = 0; double InitCash = BaseConfig.InitCashRMB + BaseConfig.InitCashUSD * BaseConfig.RateUSD + BaseConfig.InitCashHKD * BaseConfig.RateHKD; Profit = (Wealth - InitCash) / InitCash * 100; if (Wealth == 0) { Profit = 0; } #endregion UserRank data = new UserRank(); data.Initialize(); data.UserId = userId; data.AreaId = (int)sqlReader["AreaId"]; data.UserName = sqlReader["UserName"].ToString(); data.UserDataBase = sqlReader["UserDataBase"].ToString(); data.Wealth = Wealth; data.WealthRMB = WealthRMB; data.WealthUSD = WealthUSD; data.WealthHKD = WealthHKD; data.StockWealth = StocksWealth; data.RatioRMB = RatioRMB; data.RatioUSD = RatioUSD; data.RatioHKD = RatioHKD; data.Profit = Profit; data.RankDate = DateTime.Now.Date; mapUserWealth[userId] = data; nUser++; } //while(sqlReader.Read()) end sqlReader.Close(); Loger.Debug("---calculate [StocksWealth] [Cash] [Wealth] [Ratio] [Profit] finished . UserCount = " + nUser + "---"); #region 根据已更新的资产缓存更新数据库表 int nUserID = 0; sqlCmd = new SqlCommand("DELETE FROM [DailyRank]", sqlConn, sqlTrans); sqlCmd.ExecuteNonQuery(); nUser = 0; foreach (var data in mapUserWealth) { sqlCmd = new SqlCommand("INSERT INTO [DailyRank] (UserID,AreaId,UserName,UserDataBase,Wealth, WealthRMB, WealthUSD, WealthHKD,StockWealth, " + "Profit, DailyProfit, WeeklyProfit, MonthlyProfit, RatioRMB, RatioUSD, RatioHKD, RatioUnderDays, RankDate) " + "VALUES (@UserID,@AreaId,@UserName,@UserDataBase, @Wealth, @WealthRMB, @WealthUSD, @WealthHKD,@StockWealth," + "@Profit, @DailyProfit, @WeeklyProfit, @MonthlyProfit, @RatioRMB, @RatioUSD, @RatioHKD, @RatioUnderDays, @RankDate)", sqlConn, sqlTrans); //用户信息 sqlCmd.Parameters.Add("@UserID", SqlDbType.Int).Value = data.Value.UserId; sqlCmd.Parameters.Add("@AreaId", SqlDbType.Int).Value = data.Value.AreaId; sqlCmd.Parameters.Add("@UserName", SqlDbType.VarChar, 32).Value = data.Value.UserName; sqlCmd.Parameters.Add("@UserDataBase", SqlDbType.VarChar, 16).Value = data.Value.UserDataBase; //资产总值 sqlCmd.Parameters.Add("@Wealth", SqlDbType.Money).Value = data.Value.Wealth; sqlCmd.Parameters.Add("@WealthRMB", SqlDbType.Money).Value = data.Value.WealthRMB; sqlCmd.Parameters.Add("@WealthUSD", SqlDbType.Money).Value = data.Value.WealthUSD; sqlCmd.Parameters.Add("@WealthHKD", SqlDbType.Money).Value = data.Value.WealthHKD; //股票市值 sqlCmd.Parameters.Add("@StockWealth", SqlDbType.Money).Value = data.Value.StockWealth; //收益率 sqlCmd.Parameters.Add("@Profit", SqlDbType.Money).Value = data.Value.Profit; sqlCmd.Parameters.Add("@DailyProfit", SqlDbType.Money).Value = data.Value.DailyProfit; sqlCmd.Parameters.Add("@WeeklyProfit", SqlDbType.Money).Value = data.Value.WeeklyProfit; sqlCmd.Parameters.Add("@MonthlyProfit", SqlDbType.Money).Value = data.Value.MonthlyProfit; //持仓比例 sqlCmd.Parameters.Add("@RatioRMB", SqlDbType.Money).Value = data.Value.RatioRMB; sqlCmd.Parameters.Add("@RatioUSD", SqlDbType.Money).Value = data.Value.RatioUSD; sqlCmd.Parameters.Add("@RatioHKD", SqlDbType.Money).Value = data.Value.RatioHKD; //低于持仓标准的天数 if (mapUserWealth[nUserID].RatioRMB < BaseConfig.RatioBaseLine) //当日持仓未达标则记录 { sqlCmd.Parameters.Add("@RatioUnderDays", SqlDbType.Int).Value = 1; } else { sqlCmd.Parameters.Add("@RatioUnderDays", SqlDbType.Int).Value = 0; } //排名日期 sqlCmd.Parameters.Add("@RankDate", SqlDbType.DateTime).Value = data.Value.RankDate.ToString("yyyy-MM-dd"); sqlCmd.ExecuteNonQuery(); nUser++; } Loger.Debug("---Update table dailyrank finished . userCount = " + nUser + "---"); #endregion #region 当天排名数据备份到单独表 sqlCmd = new SqlCommand("CreateHistoryRankByDate", sqlConn, sqlTrans); sqlCmd.ExecuteNonQuery(); #endregion sqlTrans.Commit(); Loger.Debug("<<< Processing [Wealth] Finished ! >>>"); bWealthDone = true; return(true); } catch (Exception err) { Loger.Debug("ProcWealth error :" + err); if (bInTransaction && sqlTrans != null && sqlTrans.Connection != null && sqlTrans.Connection.State == ConnectionState.Open) { if (sqlReader != null && !sqlReader.IsClosed) { sqlReader.Close(); } sqlTrans.Rollback(); } return(false); } finally { if (sqlConn.State != ConnectionState.Closed) { sqlConn.Close(); } } }