public Result PositionTransfer(PositionTransfer model) { if (model.from_unit_id > 0 && model.to_unit_id > 0) { HQItem hq = HQService.Get(model.code); decimal price_latest = hq != null ? hq.Last : 0; List <Position> list = new List <Position>(); string[] keys = TradeRA.KeySearch("P_" + model.code + "_*_U_" + model.from_unit_id); foreach (var key in keys) { list.Add(PositionRA.Get(key)); } if (model.count > list.Sum(p => p.count_sellable)) { int transfer_total = 0; foreach (Position position in list) { int transfer = Math.Min(model.count, position.count_sellable); PositionRA.UpdateTransfer(model.from_unit_id, model.to_unit_id, position.account_id, (model.to_account_id == 0 ? position.account_id : model.to_account_id), model.code, transfer, price_latest); transfer_total += transfer; if (transfer_total == model.count) { break; } } return(Result(ApiResultEnum.Success)); } } return(Result(ApiResultEnum.Failed)); }
public static void SavePosition() { string[] keys = TradeRA.KeySearch("P_*"); foreach (string key in keys) { Position position = PositionRA.Get(key); if (position.count == 0) { if (position.id > 0) { PositionDA.Delete(position.id); } } else { position.price_latest = HQService.Get(position.code).Last; if (position.id > 0) { PositionDA.Update(position); } else { PositionDA.Add(position); } } } }
private void JY_OrderCanceled(object sender, OrderItem e) { string[] keys = TradeRA.KeySearch("O_" + e.order_no + "_*"); if (keys.Length == 0 || keys[0].EndsWith("U_0") || keys[0].EndsWith("_F")) { return; } Order model = new Order() { order_no = e.order_no, deal_count = (int)decimal.Parse(e.deal_count), cancel_count = (int)decimal.Parse(e.cancel_count), status = e.status, }; OrderRA.UpdateStatus(model, keys[0]); //撤单成功取消冻结 Order order = OrderRA.Get(keys[0]); MessageBiz.Send(order.user_id.ToString(), MessageTypeEnum.Order_Canceled, "[" + order.code + "]" + order.name + "撤单成功,撤单数量:" + model.cancel_count); if (e.type == "0") { string key_unit = "U_" + order.unit_id; UnitRA.UpdateCapitalOrderBuy(-order.price * model.cancel_count, key_unit); } else if (e.type == "1") { string key_position = "P_" + order.code + "_A_" + order.account_id + "_U_" + order.unit_id; PositionRA.UpdateSellableOrderSell(order.cancel_count, key_position); } MonitorRA.Increment("account_" + account_id, "cancel_count"); }
public Result UpdateUnits(UserUnits model) { ApiResultEnum result = UnitDA.UpdateUserID(model); if (result == ApiResultEnum.Success && MonitorRA.GetStatusTrade() != 0) { string[] keys = TradeRA.KeySearch("U_*"); foreach (string key in keys) { string _user_id = TradeRA.Get(key, "user_id"); if (model.unit_ids.Contains(int.Parse(key.Substring(2)))) { if (model.id != _user_id) { UnitRA.UpdateUserID(model.id, key); } } else { if (model.id == _user_id) { UnitRA.UpdateUserID("0", key); } } } } return(Result(result)); }
public static void SaveAccountCapital() { string[] keys = TradeRA.KeySearch("A_*"); foreach (string key in keys) { Account account = AccountRA.Get(key); AccountDA.UpdateCapital(account); } }
//获取主账户最大可下单数量 public static int GetAccountCount(Order order) { Account account = AccountRA.Get("A_" + order.account_id); if (order.type_enum == OrderTypeEnum.Buy && !string.IsNullOrWhiteSpace(account.limit_no_buying) && account.limit_no_buying.Contains(order.code)) { return(0); } if (account.status_enum == StatusEnum.Forbidden) { return(0); } if (account.status_order_enum == StatusOrderEnum.Forbidden) { return(0); } if (order.type_enum == OrderTypeEnum.Buy && account.status_order_enum == StatusOrderEnum.NoBuying) { return(0); } if (order.type_enum == OrderTypeEnum.Buy) { decimal count = account.capital_initial / order.price; if (account.limit_ratio_single > 0) { count = Math.Min(count, account.capital_initial * account.limit_ratio_single / order.price); } BlockInfo block = StockInfoBiz.GetBlock(order.code); if (block.block_type_enum == BlockEnum.gem) { if (account.limit_ratio_gem_single > 0) { count = Math.Min(count, account.capital_initial * account.limit_ratio_gem_single / order.price); } if (account.limit_ratio_gem_total > 0) { count = Math.Min(count, (account.capital_initial * account.limit_ratio_gem_total - account.capital_stock_value_gem) / order.price); } } string[] keys = TradeRA.KeySearch("G_*_U_" + order.unit_id + "_A_" + order.account_id); AccountGroupItem item = AccountGroupRA.Get(keys[0]); if (item.capital_available > 0) { count = Math.Min(count, (item.capital_available - item.capital_stock_value) / order.price); } return((int)Math.Ceiling(count / 100) * 100); } else { return(PositionRA.GetSellable(order.unit_id, order.code, order.account_id)); } }
public static void RunUnitCapitalMonitor() { string[] keys = TradeRA.KeySearch("U_*"); foreach (string key in keys) { Unit unit = UnitRA.Get(key); if (unit.user_id > 0 && unit.ratio_warning > 0) { if (unit.capital_total < unit.ratio_warning * unit.capital_scale && unit.status_order_enum == StatusOrderEnum.Allowed) { StatusOrder model = new StatusOrder(unit.id, StatusOrderEnum.NoBuying); UnitDA.UpdateStatusOrder(model); UnitRA.UpdateStatusOrder(model.status, "U_" + model.id); UserDA.ListParents(unit.user_id).ForEach(user_id => { MessageBiz.Send(user_id.ToString(), MessageTypeEnum.Unit_Warning, "单元[" + unit.code + "]资产已低于预警线,被禁止买入"); }); NLog.Info(string.Format("单元[{0}]资产已低于预警线,被禁止买入。总资产:{1}", unit.code, unit.capital_total)); } else if (unit.capital_total > unit.ratio_warning * unit.capital_scale && unit.status_order_enum == StatusOrderEnum.NoBuying) { StatusOrder model = new StatusOrder(unit.id, StatusOrderEnum.Allowed); UnitDA.UpdateStatusOrder(model); UnitRA.UpdateStatusOrder(model.status, "U_" + model.id); MessageBiz.Send(unit.user_id.ToString(), MessageTypeEnum.Unit_Recovery, "单元[" + unit.code + "]资产已高于预警线,恢复交易"); } } if (unit.user_id > 0 && unit.ratio_close_position > 0 && unit.capital_total < unit.ratio_close_position * unit.capital_scale) { List <Position> list = PositionRA.List4Unit(unit.id).Where(p => p.count_sellable > 0).ToList(); if (list.Count > 0) { list.ForEach(p => { Order order = new Order() { code = p.code, count = p.count_sellable, type_enum = OrderTypeEnum.Sell, unit_id = unit.id, price = DataBiz.GetPriceByPriceType(p.code, OrderPriceEnum.Buy5), user_id = 1, platform = 1 }; Order(order); }); UserDA.ListParents(unit.user_id).ForEach(user_id => { MessageBiz.Send(unit.id.ToString(), MessageTypeEnum.Unit_Close_Position, "单元[" + unit.code + "]资产已低于平仓线,被强制平仓"); }); NLog.Info(string.Format("单元[{0}]资产已低于平仓线,被强制平仓。总资产:{1}", unit.code, unit.capital_total)); } } } }
public static void SaveOrder() { string[] keys = TradeRA.KeySearch("O_*"); foreach (string key in keys) { Order order = OrderRA.Get(key); if (order.state_enum == OrderStatusEnum.Submitted) { order.state_enum = OrderStatusEnum.Abnormal; } OrderDA.Add(order); } }
private void JY_NewOrder(object sender, OrderItem e) { Order order; string[] keys = TradeRA.KeySearch("O_" + e.order_no + "_*"); //处理系统中是否存在未能正常收到回报但已成功的委托(通常由于下单超时导致) if (keys.Length == 0 && !string.IsNullOrWhiteSpace(e.request_id) && e.request_id != "0") { JY_Order_Done(null, new OrderResult(true, e.order_no, "", e.request_id)); keys = TradeRA.KeySearch("O_" + e.order_no + "_*"); } if (keys.Length > 0) { order = OrderRA.Get(keys[0]); if (order.cancel_count != (int)decimal.Parse(e.cancel_count)) { JY_OrderCanceled(null, e); return; } } else { order = new Order(); } order.deal_count = (int)decimal.Parse(e.deal_count); order.cancel_count = (int)decimal.Parse(e.cancel_count); order.status = e.status; order.time_dt = DateTime.Parse(e.date.ToDate() + " " + e.time.ToTime()); if (keys.Length > 0) { OrderRA.UpdateNew(order, keys[0]); } else { string key = "O_" + e.order_no + "_T_0_U_0"; order.trade_no = "0"; order.order_no = e.order_no; order.name = e.name; order.code = e.code; order.price = decimal.Parse(e.price); order.count = order.trade_count = (int)decimal.Parse(e.count); order.type = int.Parse(e.type); order.account_id = account_id; order.state_enum = OrderStatusEnum.Success; OrderRA.Add(order, key); } }
private void JY_OrderChanged(object sender, OrderItem e) { string[] keys = TradeRA.KeySearch("O_" + e.order_no + "_*"); if (keys.Length > 0) { Order model = new Order() { order_no = e.order_no, deal_count = (int)decimal.Parse(e.deal_count), cancel_count = (int)decimal.Parse(e.cancel_count), status = e.status }; OrderRA.UpdateStatus(model, keys[0]); } }
private void JY_NewDeal(object sender, DealItem e) { Order order = null; int unit_id = 0; string[] keys = TradeRA.KeySearch("O_" + e.order_no + "_*"); if (keys.Length > 0) { order = OrderRA.Get(keys[0]); unit_id = order.unit_id; } string key = "D_" + e.deal_no + "_O_" + e.order_no + "_U_" + unit_id; if (TradeRA.KeyExists(key)) { return; } Deal deal = new Deal() { code = e.code, name = e.name, type = int.Parse(e.type), count = (int)decimal.Parse(e.count), money = decimal.Parse(e.money), time_dt = DateTime.Parse(e.date.ToDate() + " " + e.time.ToTime()), deal_no = e.deal_no, order_no = e.order_no, price = decimal.Parse(e.price), unit_id = unit_id, account_id = account_id, transferred = unit_id > 0 ? 0 : 1, }; DealRA.Add(deal, key); //更新成交均价 DealAveragePrice(deal); //系统内成交 if (unit_id > 0) { MessageBiz.Send(order.user_id.ToString(), MessageTypeEnum.Order_Dealt, "[" + deal.code + "]" + deal.name + "已成交,成交数量:" + deal.count); TradeBiz.NewDeal(deal, order.price); MonitorRA.Increment("account_" + account_id, "deal_count"); } }
public static void RunAccountCapitalMonitor() { string[] keys = TradeRA.KeySearch("A_*"); foreach (string key in keys) { Account account = AccountRA.Get(key); if (account.ratio_capital_warning > 0 && account.capital_total > 0 && account.capital_total < account.ratio_capital_warning * account.capital_initial) { UserDA.ListParents(account.created_by).ForEach(user_id => { MessageBiz.Send(user_id.ToString(), MessageTypeEnum.Account_Warning, "主账户[" + account.code + "]资产已低于预警线"); }); NLog.Info(string.Format("主账户[{0}]资产已低于预警线。总资产:{1}", account.code, account.capital_total)); } } }
public Result OrderAutoUpdateStatus(StatusAutoOrder model) { if (model.status != StatusAutoOrderEnum.Run && model.status != StatusAutoOrderEnum.Pause) { return(Result(ApiResultEnum.Parameter_Error)); } string[] keys = TradeRA.KeySearch("S_" + model.id + "_*_D_0"); if (keys.Length == 0) { return(Result(ApiResultEnum.NO_Action)); } OrderAutoRA.UpdateStatus(model.status, user_id, keys[0]); return(Result(ApiResultEnum.Success)); }
//更新成交均价 private void DealAveragePrice(Deal deal) { string[] keys = TradeRA.KeySearch("D_*_O_" + deal.order_no + "_U_*"); decimal money = 0; int count = 0; foreach (string key in keys) { Deal dl = DealRA.Get(key); money += dl.price * dl.count; count += dl.count; } string[] keys_order = TradeRA.KeySearch("O_" + deal.order_no + "_*_U_" + deal.unit_id); if (keys_order.Length > 0) { decimal deal_average_price = (money + deal.price * deal.count) / (count + deal.count); OrderRA.UpdateAverageOrice(Math.Round(deal_average_price, 3), keys_order[0]); } }
public static void SaveUnitCapital(Dictionary <int, decimal[]> dic) { string[] keys = TradeRA.KeySearch("U_*"); foreach (string key in keys) { Unit unit = UnitRA.Get(key); UnitDA.UpdateCapital(unit); Statement statement = new Statement() { unit_id = unit.id, capital_total = unit.capital_total, capital_stock_value = unit.capital_stock_value, capital_inout = unit.capital_inout, fee = dic.ContainsKey(unit.id) ? dic[unit.id][0] : 0, profit = dic.ContainsKey(unit.id) ? dic[unit.id][1] : 0, }; StatementDA.Add(statement); } }
private void JY_Order_Done(object sender, OrderResult e) { string[] keys = TradeRA.KeySearch("O_" + e.request_id + "_*"); if (keys.Length == 0) { return; } Order order = OrderRA.Get(keys[0]); if (order.state_enum != OrderStatusEnum.Submitted) { return; } //委托失败解除冻结 if (!e.result) { if (order.type_enum == OrderTypeEnum.Buy) { string key_unit = "U_" + order.unit_id; UnitRA.UpdateCapitalOrderBuy(-order.price * order.count, key_unit); } else if (order.type_enum == OrderTypeEnum.Sell) { string key_position = "P_" + order.code + "_A_" + order.account_id + "_U_" + order.unit_id; PositionRA.UpdateSellableOrderSell(order.count, key_position); } OrderRA.UpdateOrderFailed(keys[0], e.message); MessageBiz.Send(order.user_id.ToString(), MessageTypeEnum.Order_Failed, "[" + order.code + "]" + order.name + "委托失败。" + e.message); MonitorRA.Increment("account_" + account_id, "failed_count"); } else { OrderRA.UpdateOrderSuccess(keys[0], order.unit_id, order.trade_no, e.order_no); MonitorRA.Increment("account_" + account_id, "success_count"); } }
public Result Transfer(Transfer model) { string[] keys = TradeRA.KeySearch("D_" + model.deal_no + "_*_U_0"); if (keys.Length > 0 && TradeRA.KeyExists("U_" + model.unit_id)) { Deal deal = DealRA.Get(keys[0]); if (deal.type_enum == OrderTypeEnum.Sell) { int sellable_count = PositionRA.GetSellable(model.unit_id, deal.code, deal.account_id); if (deal.count > sellable_count) { return(Result(ApiResultEnum.Order_Account_Negative_Position)); } } deal.unit_id = model.unit_id; DealRA.UpdateUnit(model.unit_id, keys[0]); TradeRA.KeyRename(keys[0], keys[0].Substring(0, keys[0].Length - 1) + model.unit_id); TradeBiz.NewDeal(deal, deal.price, 1); return(Result(ApiResultEnum.Success)); } return(Result(ApiResultEnum.Failed)); }
public static void SaveDeal(ref Dictionary <int, decimal[]> dic) { string[] keys = TradeRA.KeySearch("D_*"); foreach (string key in keys) { Deal deal = DealRA.Get(key); DealDA.Add(deal); if (deal.unit_id > 0) { if (dic.ContainsKey(deal.unit_id)) { dic[deal.unit_id][0] = dic[deal.unit_id][0] + deal.commission; dic[deal.unit_id][1] = dic[deal.unit_id][1] + deal.profit; } else { dic.Add(deal.unit_id, new decimal[2] { deal.commission, deal.profit }); } } } }
public Result <List <AccountPosition> > ListAccountPosition(int account_id) { List <AccountPosition> list = new List <AccountPosition>(); List <Position> list_in = (account_id == 0) ? PositionRA.List() : PositionRA.List4Account(account_id); list_in.ForEach(p => { list.Add(new AccountPosition() { account_id = p.account_id, account_name = p.account_name, code = p.code, name = p.name, count = 0, count_in = p.count }); }); List <Tuple <int, JY.PositionItem> > list_sys = new List <Tuple <int, JY.PositionItem> >(); if (account_id > 0) { TradeBiz.QueryPosition(account_id).ForEach(p => { list_sys.Add(new Tuple <int, JY.PositionItem>(account_id, p)); }); } else { string[] keys = TradeRA.KeySearch("A_*"); foreach (var key in keys) { int id = int.Parse(key.Substring(2)); TradeBiz.QueryPosition(id).ForEach(p => { list_sys.Add(new Tuple <int, JY.PositionItem>(id, p)); }); } } foreach (var t in list_sys) { AccountPosition ap = list.Find(p => p.account_id == t.Item1 && p.code == t.Item2.code); if (ap == null) { list.Add(new AccountPosition() { account_id = t.Item1, account_name = AccountRA.GetName(t.Item1), code = t.Item2.code, name = t.Item2.name, count = (int)decimal.Parse(t.Item2.count), count_in = 0 }); } else { ap.count = (int)decimal.Parse(t.Item2.count); } } return(Result(list)); }
public static void RunCalculateValue() { //单元的市值 Dictionary <int, decimal[]> dic_unit = new Dictionary <int, decimal[]>(); //主账户的市值 Dictionary <int, decimal> dic_account = new Dictionary <int, decimal>(); //单元下主账户组中的主账户市值 Dictionary <string, decimal> dic_account_group = new Dictionary <string, decimal>(); string[] keys = TradeRA.KeySearch("P_*"); foreach (string key in keys) { Position position = PositionRA.Get(key); HQItem hq = HQService.Get(position.code); decimal price = hq == null ? position.price_latest : hq.Last; decimal value = price * position.count; decimal profit = (price - position.price_cost) * position.count; if (dic_unit.ContainsKey(position.unit_id)) { dic_unit[position.unit_id][position.block] += value; dic_unit[position.unit_id][4] += value; dic_unit[position.unit_id][5] += profit; } else { decimal[] values = new decimal[6] { 0, 0, 0, 0, value, profit }; values[position.block] = value; dic_unit.Add(position.unit_id, values); } //主账户市值暂只计算创业板 if (position.block_enum == BlockEnum.gem) { if (dic_account.ContainsKey(position.account_id)) { dic_account[position.account_id] += value; } else { dic_account.Add(position.account_id, value); } } string ua = "U_" + position.unit_id + "_A_" + position.account_id; if (dic_account_group.ContainsKey(ua)) { dic_account_group[ua] += value; } else { dic_account_group.Add(ua, value); } } foreach (var kvp in dic_unit) { UnitRA.UpdateCapitalStockValue(kvp.Value, "U_" + kvp.Key); } foreach (var kvp in dic_account) { AccountRA.UpdateCapitalStockValue(kvp.Value, "A_" + kvp.Key); } foreach (var kvp in dic_account_group) { AccountGroupRA.UpdateCapitalStockValue(kvp.Key, kvp.Value); } }
//检查主账户是否满足下单条件 public static ApiResultEnum CheckAccount(Order order) { Account account = AccountRA.Get("A_" + order.account_id); if (order.type_enum == OrderTypeEnum.Buy && !string.IsNullOrWhiteSpace(account.limit_no_buying) && account.limit_no_buying.Contains(order.code)) { return(ApiResultEnum.Order_Account_NoBuying_Code); } if (account.status_enum == StatusEnum.Forbidden) { return(ApiResultEnum.Order_Account_Forbidden); } if (account.status_order_enum == StatusOrderEnum.Forbidden) { return(ApiResultEnum.Order_Account_Forbidden_Order); } if (order.type_enum == OrderTypeEnum.Buy && account.status_order_enum == StatusOrderEnum.NoBuying) { return(ApiResultEnum.Order_Account_NoBuying_Order); } if (order.type_enum == OrderTypeEnum.Buy) { if (account.limit_ratio_single > 0 && order.price * order.count > account.capital_initial * account.limit_ratio_single) { return(ApiResultEnum.Order_Account_Limit_Single); } BlockInfo block = StockInfoBiz.GetBlock(order.code); if (block.block_type_enum == BlockEnum.gem) { if (account.limit_ratio_gem_single > 0 && order.price * order.count > account.capital_initial * account.limit_ratio_gem_single) { return(ApiResultEnum.Order_Account_Limit_GEM_Single); } if (account.limit_ratio_gem_total > 0 && order.price * order.count + account.capital_stock_value_gem > account.capital_initial * account.limit_ratio_gem_total) { return(ApiResultEnum.Order_Account_Limit_GEM_Total); } } string[] keys = TradeRA.KeySearch("G_*_U_" + order.unit_id + "_A_" + order.account_id); AccountGroupItem item = AccountGroupRA.Get(keys[0]); if (item.capital_available > 0 && item.capital_available < order.price * order.count + item.capital_stock_value) { return(ApiResultEnum.Order_Account_Negative_Amount); } } else { if (PositionRA.GetSellable(order.unit_id, order.code, order.account_id) < order.count) { return(ApiResultEnum.Order_Account_Negative_Position); } } //风控通过进行冻结 if (order.type_enum == OrderTypeEnum.Buy) { string key_unit = "U_" + order.unit_id; UnitRA.UpdateCapitalOrderBuy(order.price * order.count, key_unit); } else if (order.type_enum == OrderTypeEnum.Sell) { string key_position = "P_" + order.code + "_A_" + order.account_id + "_U_" + order.unit_id; PositionRA.UpdateSellableOrderSell(-order.count, key_position); } return(ApiResultEnum.Success); }
//检查单元是否满足下单条件 public static ApiResultEnum CheckUnit(Order order) { Unit unit = UnitRA.Get("U_" + order.unit_id); if (unit == null || unit.user_id != order.user_id) { return(ApiResultEnum.Order_Unit_Null); } if (order.type_enum == OrderTypeEnum.Buy && !string.IsNullOrWhiteSpace(unit.limit_no_buying) && unit.limit_no_buying.Contains(order.code)) { return(ApiResultEnum.Order_Unit_NoBuying_Code); } if (unit.status_enum == StatusEnum.Forbidden) { return(ApiResultEnum.Order_Unit_Forbidden); } if (unit.status_order_enum == StatusOrderEnum.Forbidden) { return(ApiResultEnum.Order_Unit_Forbidden_Order); } if (order.type_enum == OrderTypeEnum.Buy && unit.status_order_enum == StatusOrderEnum.NoBuying) { return(ApiResultEnum.Order_Unit_NoBuying_Order); } string[] keys = TradeRA.KeySearch("P_" + order.code + "_A_*_U_" + order.unit_id); if (unit.limit_stock_count > 0) { if (PositionRA.GetCodeCount(order.unit_id, order.code) > unit.limit_stock_count) { return(ApiResultEnum.Order_Unit_Limit_Count); } } if (unit.limit_order_price_enum == OrderPriceLimitEnum.In5LeverPrice) { decimal price_min = DataBiz.GetPriceByPriceType(order.code, OrderPriceEnum.Buy5); decimal price_max = DataBiz.GetPriceByPriceType(order.code, OrderPriceEnum.Sell5); if (order.price < price_min || order.price > price_max) { return(ApiResultEnum.Order_Unit_Limit_Price); } } if (order.type_enum == OrderTypeEnum.Buy) { if (unit.capital_available < order.price * order.count) { return(ApiResultEnum.Order_Unit_Negative_Amount); } BlockInfo block = StockInfoBiz.GetBlock(order.code); if (block.block_type_enum == BlockEnum.mbm) { if (unit.limit_ratio_mbm_single > 0 && order.price * order.count > unit.capital_scale * unit.limit_ratio_mbm_single) { return(ApiResultEnum.Order_Unit_Limit_MBM_Single); } } else if (block.block_type_enum == BlockEnum.gem) { if (unit.limit_ratio_gem_single > 0 && order.price * order.count > unit.capital_scale * unit.limit_ratio_gem_single) { return(ApiResultEnum.Order_Unit_Limit_GEM_Single); } if (unit.limit_ratio_gem_total > 0 && order.price * order.count + unit.capital_stock_value_gem > unit.capital_scale * unit.limit_ratio_gem_total) { return(ApiResultEnum.Order_Unit_Limit_GEM_Total); } } else if (block.block_type_enum == BlockEnum.sme) { if (unit.limit_ratio_sme_single > 0 && order.price * order.count > unit.capital_scale * unit.limit_ratio_sme_single) { return(ApiResultEnum.Order_Unit_Limit_SME_Single); } if (unit.limit_ratio_sme_total > 0 && order.price * order.count + unit.capital_stock_value_sme > unit.capital_scale * unit.limit_ratio_sme_total) { return(ApiResultEnum.Order_Unit_Limit_SME_Total); } } else if (block.block_type_enum == BlockEnum.star) { if (unit.limit_ratio_star_single > 0 && order.price * order.count > unit.capital_scale * unit.limit_ratio_star_single) { return(ApiResultEnum.Order_Unit_Limit_STAR_Single); } if (unit.limit_ratio_star_total > 0 && order.price * order.count + unit.capital_stock_value_star > unit.capital_scale * unit.limit_ratio_star_total) { return(ApiResultEnum.Order_Unit_Limit_STAR_Total); } } if (block.block_type_enum == BlockEnum.sme || block.block_type_enum == BlockEnum.gem) { if (unit.limit_ratio_smg_total > 0 && order.price * order.count + unit.capital_stock_value_sme + unit.capital_stock_value_gem > unit.capital_scale * unit.limit_ratio_smg_total) { return(ApiResultEnum.Order_Unit_Limit_SMG_Total); } } } else { if (PositionRA.GetSellable(order.unit_id, order.code) < order.count) { return(ApiResultEnum.Order_Unit_Negative_Position); } } return(ApiResultEnum.Success); }
//获取单元最大可下单数量 public static int GetUnitCount(Order order) { Unit unit = UnitRA.Get("U_" + order.unit_id); if (unit == null) { return(0); } if (order.type_enum == OrderTypeEnum.Buy && !string.IsNullOrWhiteSpace(unit.limit_no_buying) && unit.limit_no_buying.Contains(order.code)) { return(0); } if (unit.status_enum == StatusEnum.Forbidden) { return(0); } if (unit.status_order_enum == StatusOrderEnum.Forbidden) { return(0); } if (order.type_enum == OrderTypeEnum.Buy && unit.status_order_enum == StatusOrderEnum.NoBuying) { return(0); } string[] keys = TradeRA.KeySearch("P_" + order.code + "_A_*_U_" + order.unit_id); if (unit.limit_stock_count > 0) { if (PositionRA.GetCodeCount(order.unit_id, order.code) > unit.limit_stock_count) { return(0); } } if (order.type_enum == OrderTypeEnum.Buy) { decimal count = unit.capital_available / order.price; BlockInfo block = StockInfoBiz.GetBlock(order.code); if (block.block_type_enum == BlockEnum.mbm) { if (unit.limit_ratio_mbm_single > 0) { count = Math.Min(count, unit.capital_scale * unit.limit_ratio_mbm_single / order.price); } } else if (block.block_type_enum == BlockEnum.gem) { if (unit.limit_ratio_gem_single > 0) { count = Math.Min(count, unit.capital_scale * unit.limit_ratio_gem_single / order.price); } if (unit.limit_ratio_gem_total > 0) { count = Math.Min(count, (unit.capital_scale * unit.limit_ratio_gem_total - unit.capital_stock_value_gem) / order.price); } } else if (block.block_type_enum == BlockEnum.sme) { if (unit.limit_ratio_sme_single > 0) { count = Math.Min(count, unit.capital_scale * unit.limit_ratio_sme_single / order.price); } if (unit.limit_ratio_sme_total > 0) { count = Math.Min(count, (unit.capital_scale * unit.limit_ratio_sme_total - unit.capital_stock_value_sme) / order.price); } } else if (block.block_type_enum == BlockEnum.star) { if (unit.limit_ratio_star_single > 0) { count = Math.Min(count, unit.capital_scale * unit.limit_ratio_star_single / order.price); } if (unit.limit_ratio_star_total > 0) { count = Math.Min(count, (unit.capital_scale * unit.limit_ratio_star_total - unit.capital_stock_value_star) / order.price); } } if (block.block_type_enum == BlockEnum.sme || block.block_type_enum == BlockEnum.gem) { if (unit.limit_ratio_smg_total > 0) { count = Math.Min(count, (unit.capital_scale * unit.limit_ratio_smg_total - unit.capital_stock_value_sme - unit.capital_stock_value_gem) / order.price); } } return((int)Math.Ceiling(count / 100) * 100); } else { return(PositionRA.GetSellable(order.unit_id, order.code)); } }