public bool FindQuotation(string StockCode, out Show2003DBFRecord SHRecord) { SHRecord = new Show2003DBFRecord(); try { SHRecord.Clear(); if (StockCode == null || StockCode.Trim().Length != 6) { return(false); } if (mapSHRates == null) { return(false); } lock (mapSHRates) { if (mapSHRates.ContainsKey(StockCode.Trim())) { SHRecord = mapSHRates[StockCode.Trim()]; return(true); } } return(false); } catch (Exception err) { Loger.Debug(err); SHRecord.Clear(); return(false); } }
public bool FindQuotation(string StockCode, out Show2003DBFRecord SHRecord) { SHRecord = new Show2003DBFRecord(); try { SHRecord.Clear(); if (StockCode == null || StockCode.Trim().Length != 6) return false; if (mapSHRates == null) return false; lock (mapSHRates) { if (mapSHRates.ContainsKey(StockCode.Trim())) { SHRecord = mapSHRates[StockCode.Trim()]; return true; } } return false; } catch (Exception err) { Loger.Debug(err); SHRecord.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="SHRate"></param> private void SaveQuotation(Show2003DBFRecord SHRate) { try { if (DateTime.Now.TimeOfDay < Common.BeginAMTS || (DateTime.Now.TimeOfDay > Common.EndAMTS && DateTime.Now.TimeOfDay < Common.BeginPMTS) || DateTime.Now.TimeOfDay > Common.EndPMTS) { return; } //更新最近一次获取的上证类股票行情字典 lock (Common.stkTrading.mapLastSHQuotation) { if (Common.stkTrading.mapLastSHQuotation == null) { Common.stkTrading.mapLastSHQuotation = new Dictionary <string, Show2003DBFRecord>(); } if (Common.stkTrading.mapLastSHQuotation.ContainsKey(SHRate.StockCode.Trim()) && Common.ComparePrice(Common.stkTrading.mapLastSHQuotation[SHRate.StockCode.Trim()].BuyingVal1, SHRate.BuyingVal1) == 0 && Common.ComparePrice(Common.stkTrading.mapLastSHQuotation[SHRate.StockCode.Trim()].SellingVal1, SHRate.SellingVal1) == 0 && Common.ComparePrice(Common.stkTrading.mapLastSHQuotation[SHRate.StockCode.Trim()].LatestPrice, SHRate.LatestPrice) == 0) { return; } Common.stkTrading.mapLastSHQuotation[SHRate.StockCode.Trim()] = SHRate; } if (!Directory.Exists(Common.strQuotationHistory.Trim() + "\\" + DateTime.Now.Date.ToString("yyyyMMdd"))) { Directory.CreateDirectory(Common.strQuotationHistory.Trim() + "\\" + DateTime.Now.Date.ToString("yyyyMMdd")); } using (StreamWriter SW = new StreamWriter(Common.strQuotationHistory.Trim() + "\\" + DateTime.Now.Date.ToString("yyyyMMdd") + "\\SH_" + SHRate.StockCode.Trim() + ".log", true, Encoding.Default)) { //存储买1,卖1,最新价,最高价,最低价 SW.WriteLine(DateTime.Now.ToString("HH:mm:ss") + "," + SHRate.BuyingVal1.ToString("f3") + "," + SHRate.SellingVal1.ToString("f3") + "," + SHRate.LatestPrice.ToString("f3") + "," + SHRate.HighestPrice.ToString("f3") + "," + SHRate.LowestPrice.ToString("f3")); SW.Close(); } } catch (Exception err) { Common.Log(err); } }
/// <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> /// <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> /// <param name="SHRate"></param> /// <param name="userFund"></param> /// <param name="userOrder"></param> /// <returns></returns> private bool IsOrderValid(ref Show2003DBFRecord SHRate, ref UserFund userFund, ref UserOrders userOrder) { try { if (userOrder.OrdType == OrderType.ImmediateOrder) return true; else if (userOrder.ExpiredDate.Date > DateTime.Now.Date) return true; else if (SHRate.StockCode == null || SHRate.StockName == null) return false; else if (GetStockType(SHRate.StockCode.Trim(), StockMarket.Shanghai) != StockType.SH_A) return true; if (userOrder.Side) { if (SHRate.PreClosePrice < 0.01) { userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; userFund.UsableCash += Common.ConvertPrice((userOrder.OrderPrice * userOrder.OrderVolume) * (1 + defaultBuyTax)); return false; } else if (SHRate.StockName.ToUpper().Contains("ST")) { if (Common.ComparePrice(userOrder.OrderPrice, SHRate.PreClosePrice * 0.95) < 0) { userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; userFund.UsableCash += Common.ConvertPrice((userOrder.OrderPrice * userOrder.OrderVolume) * (1 + defaultBuyTax)); return false; } else return true; } else if (!SHRate.StockName.ToUpper().Contains("N")) { if (Common.ComparePrice(userOrder.OrderPrice, SHRate.PreClosePrice * 0.9) < 0) { userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; userFund.UsableCash += Common.ConvertPrice((userOrder.OrderPrice * userOrder.OrderVolume) * (1 + defaultBuyTax)); return false; } else return true; } } else { if (SHRate.PreClosePrice < 0.01) { userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; return false; } else if (SHRate.StockName.ToUpper().Contains("ST")) { if (Common.ComparePrice(userOrder.OrderPrice, SHRate.PreClosePrice * 1.05) > 0) { userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; return false; } else return true; } else if (!SHRate.StockName.ToUpper().Contains("N")) { if (Common.ComparePrice(userOrder.OrderPrice, SHRate.PreClosePrice * 1.1) > 0) { userOrder.OrdStatus = OrderStatus.Failure; userOrder.UpdatedDate = DateTime.Now; return false; } else return true; } } return true; } catch { return false; } }
/// <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> /// <param name="SHRate"></param> /// <param name="userFund"></param> /// <param name="userOrder"></param> /// <param name="userStock"></param> /// <param name="dBoughtAmount"></param> /// <returns></returns> private bool BuySH(ref Show2003DBFRecord SHRate, ref UserFund userFund, ref UserOrders userOrder, ref UserStocks userStock, out double dBoughtAmount) { try { dBoughtAmount = 0; if (userOrder.UserID != userFund.UserID || userStock.UserID != userFund.UserID) return false; else if (!userOrder.Side || userOrder.OrdStatus != OrderStatus.Waiting || userFund.UserID != userOrder.UserID) return false; else if (userOrder.OrderVolume < 0) return false; else if (SHRate.SellingVal1 < 0.001 || SHRate.LatestPrice < 0.001) return false; UserFund tmpFund = userFund; UserOrders tmpOrder = userOrder; UserStocks tmpStock = userStock; dBoughtAmount = Common.ConvertPrice((tmpOrder.OrderVolume * SHRate.SellingVal1) * (1 + defaultBuyTax)); if (Common.ComparePrice(userFund.Cash, dBoughtAmount) >= 0) { tmpFund.UsableCash += Common.ConvertPrice((tmpOrder.OrderVolume * tmpOrder.OrderPrice) * (1 + defaultBuyTax)); tmpFund.UsableCash -= Common.ConvertPrice(dBoughtAmount); Synchronizer.FundHistory fundHistory = new Synchronizer.FundHistory(); fundHistory.Initialize(); fundHistory.UserID = userFund.UserID; fundHistory.OrderID = userOrder.OrderID; fundHistory.OriginalCash = Common.ConvertPrice(userFund.Cash); tmpFund.Cash -= Common.ConvertPrice(dBoughtAmount); fundHistory.ChangedCash = Common.ConvertPrice(tmpFund.Cash - fundHistory.OriginalCash); fundHistory.Curr = tmpOrder.Curr; Common.DBSync.FundChanged(fundHistory, userFund.UserID); if (tmpStock.Volume + tmpOrder.OrderVolume > 0) tmpStock.AveragePrice = Common.ConvertPrice( ((tmpStock.AveragePrice * tmpStock.Volume) + (SHRate.SellingVal1 * tmpOrder.OrderVolume)) / (tmpStock.Volume + tmpOrder.OrderVolume) * (1 + defaultBuyTax)); else tmpStock.AveragePrice = 0; tmpStock.Volume += tmpOrder.OrderVolume; tmpStock.Curr = tmpOrder.Curr; if (GetStockType(tmpOrder.StockCode, StockMarket.Shanghai) == StockType.SH_Warrant) tmpStock.Sellable = true; else tmpStock.Sellable = false; if (tmpFund.UsableCash < 0) tmpFund.UsableCash = 0; } else { tmpOrder.UpdatedDate = DateTime.Now; tmpOrder.OrdStatus = OrderStatus.Failure; Common.DBSync.RecordError(tmpOrder, "(SH)���㣺Currency-" + userFund.Curr.ToString().Trim() + "/Cash-" + tmpFund.Cash.ToString("f3").Trim() + "/Cost-" + dBoughtAmount.ToString("f3").Trim()); } if (tmpOrder.OrdStatus != OrderStatus.Failure) { tmpOrder.TradePrice = SHRate.SellingVal1; if (tmpOrder.OrdType == OrderType.ImmediateOrder) tmpOrder.OrderPrice = 0; tmpOrder.UpdatedDate = DateTime.Now; tmpOrder.OrdStatus = OrderStatus.Finished; userFund = tmpFund; userStock = tmpStock; } userOrder = tmpOrder; if (userOrder.OrdStatus == OrderStatus.Finished) return true; else return false; } catch { dBoughtAmount = 0; 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 !"); } }
/// <summary> /// �����֤���Ʊ /// </summary> /// <param name="SHRate"></param> /// <param name="userFund"></param> /// <param name="userOrder"></param> /// <param name="userStock"></param> /// <param name="dSoldAmount"></param> /// <returns></returns> private bool SellSH(ref Show2003DBFRecord SHRate, ref UserFund userFund, ref UserOrders userOrder, ref UserStocks userStock, out double dSoldAmount) { try { dSoldAmount = 0; if (userOrder.UserID != userFund.UserID || userStock.UserID != userFund.UserID) return false; else if (userOrder.Side || userOrder.OrdStatus != OrderStatus.Waiting || userFund.UserID != userOrder.UserID) return false; else if (userOrder.OrderVolume < 0) return false; else if (SHRate.BuyingVal1 < 0.001 || SHRate.LatestPrice < 0.001) return false; UserFund tmpFund = userFund; UserOrders tmpOrder = userOrder; UserStocks tmpStock = userStock; dSoldAmount = Common.ConvertPrice((tmpOrder.OrderVolume * SHRate.BuyingVal1) * (1 - defaultSellTax)); if (tmpStock.Volume >= tmpOrder.OrderVolume) { tmpStock.Volume -= tmpOrder.OrderVolume; Synchronizer.FundHistory fundHistory = new Synchronizer.FundHistory(); fundHistory.Initialize(); fundHistory.UserID = userFund.UserID; fundHistory.OrderID = userOrder.OrderID; fundHistory.OriginalCash = Common.ConvertPrice(userFund.Cash); tmpFund.Cash += Common.ConvertPrice(dSoldAmount); fundHistory.ChangedCash = Common.ConvertPrice(tmpFund.Cash - fundHistory.OriginalCash); fundHistory.Curr = tmpOrder.Curr; Common.DBSync.FundChanged(fundHistory, userFund.UserID); tmpFund.UsableCash += Common.ConvertPrice(dSoldAmount); if (tmpStock.Volume > 0) tmpStock.AveragePrice = Common.ConvertPrice( ((tmpStock.AveragePrice * tmpStock.Volume) + (SHRate.BuyingVal1 * tmpOrder.OrderVolume)) / (tmpStock.Volume + tmpOrder.OrderVolume) * (1 + defaultSellTax)); else tmpStock.AveragePrice = 0; if (tmpFund.Cash < 0) tmpFund.Cash = 0; if (tmpFund.UsableCash < 0) tmpFund.UsableCash = 0; } else { tmpOrder.UpdatedDate = DateTime.Now; tmpOrder.OrdStatus = OrderStatus.Failure; Common.DBSync.RecordError(tmpOrder, "(SH)��ɲ��㣺Volume-" + tmpStock.Volume.ToString().Trim() + "/Cost-" + tmpOrder.OrderVolume.ToString().Trim()); } if (tmpOrder.OrdStatus != OrderStatus.Failure) { tmpOrder.TradePrice = Common.ConvertPrice(SHRate.BuyingVal1); if (tmpOrder.OrdType == OrderType.ImmediateOrder) tmpOrder.OrderPrice = 0; tmpOrder.UpdatedDate = DateTime.Now; tmpOrder.OrdStatus = OrderStatus.Finished; userFund = tmpFund; userStock = tmpStock; } userOrder = tmpOrder; if (userOrder.OrdStatus == OrderStatus.Finished) return true; else return false; } catch { dSoldAmount = 0; return false; } }
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> /// <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="SHRate"></param> private void SaveQuotation(Show2003DBFRecord SHRate) { try { if (DateTime.Now.TimeOfDay < Common.BeginAMTS || (DateTime.Now.TimeOfDay > Common.EndAMTS && DateTime.Now.TimeOfDay < Common.BeginPMTS) || DateTime.Now.TimeOfDay > Common.EndPMTS) return; //�������һ�λ�ȡ����֤���Ʊ�����ֵ� lock (Common.stkTrading.mapLastSHQuotation) { if (Common.stkTrading.mapLastSHQuotation == null) Common.stkTrading.mapLastSHQuotation = new Dictionary<string, Show2003DBFRecord>(); if (Common.stkTrading.mapLastSHQuotation.ContainsKey(SHRate.StockCode.Trim()) && Common.ComparePrice(Common.stkTrading.mapLastSHQuotation[SHRate.StockCode.Trim()].BuyingVal1, SHRate.BuyingVal1) == 0 && Common.ComparePrice(Common.stkTrading.mapLastSHQuotation[SHRate.StockCode.Trim()].SellingVal1, SHRate.SellingVal1) == 0 && Common.ComparePrice(Common.stkTrading.mapLastSHQuotation[SHRate.StockCode.Trim()].LatestPrice, SHRate.LatestPrice) == 0) return; Common.stkTrading.mapLastSHQuotation[SHRate.StockCode.Trim()] = SHRate; } if (!Directory.Exists(Common.strQuotationHistory.Trim() + "\\" + DateTime.Now.Date.ToString("yyyyMMdd"))) Directory.CreateDirectory(Common.strQuotationHistory.Trim() + "\\" + DateTime.Now.Date.ToString("yyyyMMdd")); using (StreamWriter SW = new StreamWriter(Common.strQuotationHistory.Trim() + "\\" + DateTime.Now.Date.ToString("yyyyMMdd") + "\\SH_" + SHRate.StockCode.Trim() + ".log", true, Encoding.Default)) { //�洢��1,��1,���¼�,���,��ͼ� SW.WriteLine(DateTime.Now.ToString("HH:mm:ss") + "," + SHRate.BuyingVal1.ToString("f3") + "," + SHRate.SellingVal1.ToString("f3") + "," + SHRate.LatestPrice.ToString("f3") + "," + SHRate.HighestPrice.ToString("f3") + "," + SHRate.LowestPrice.ToString("f3")); SW.Close(); } } catch (Exception err) { Common.Log(err); } }
/// <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(); } } }