//获取主账户最大可下单数量 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 void Order(Order order) { string request_id = FuncHelper.GetUniqueID().ToString(); order.account_id = account_id; order.name = StockInfoBiz.GetStock(order.code).name; order.time_dt = DateTime.Now; OrderRA.Add(order, "O_" + request_id + "_T_" + order.trade_no + "_U_" + order.unit_id + "_F"); JY.Order(new JY.Order(order.code, order.type, order.count, order.price, request_id)); MonitorRA.Increment("account_" + account_id, "order_count"); }
public static void Close() { TradeBiz.Stop(); HQBiz.Save(); SaveOrder(); Dictionary <int, decimal[]> dic = new Dictionary <int, decimal[]>(); SaveDeal(ref dic); SavePosition(); SaveAccountCapital(); SaveUnitCapital(dic); StockInfoBiz.RefreshBlockList(); }
//检查系统和用户是否满足下单条件 public static ApiResultEnum CheckStatus(Order model) { StatusOrderEnum status_order = (StatusOrderEnum)int.Parse(UserRA.Get(model.user_id.ToString(), "status_order")); if (status_order == StatusOrderEnum.Forbidden) { return(ApiResultEnum.Order_User_Forbidden_Order); } if (model.type_enum == OrderTypeEnum.Buy && status_order == StatusOrderEnum.NoBuying) { return(ApiResultEnum.Order_User_NoBuying_Order); } StatusTradeEnum status_trade = (StatusTradeEnum)MonitorRA.GetStatusTrade(); if (status_trade == StatusTradeEnum.Closed) { return(ApiResultEnum.Order_Closed); } else if (status_trade == StatusTradeEnum.Pause) { return(ApiResultEnum.Order_Paused); } BlockInfo block = StockInfoBiz.GetBlock(model.code); if (block == null) { return(ApiResultEnum.Order_Code_Error); } if (model.price == 0) { return(ApiResultEnum.Order_Price_Error); } if (model.count == 0) { return(ApiResultEnum.Order_Count_Error); } return(ApiResultEnum.Success); }
public static void AdjustPosition(Position position, Deal deal, decimal order_price, int type) { string key_unit = "U_" + deal.unit_id; string key_position = "P_" + deal.code + "_A_" + deal.account_id + "_U_" + deal.unit_id; //更新单元余额和冻结 if (deal.type_enum == OrderTypeEnum.Buy) { UnitRA.UpdateCapitalDealBuy(order_price * deal.count, type == 0, key_unit); } else if (deal.type_enum == OrderTypeEnum.Sell) { UnitRA.UpdateCapitalDealSell(deal.price * deal.count, key_unit); } //更新持仓 decimal amount = deal.money + deal.commission; if (position != null) { if (deal.type == 0) { position.price_cost = Math.Round((position.price_cost * position.count + amount) / (deal.count + position.count), 6); position.count = position.count + deal.count; if (type == 0 || type == 1) { position.price_cost_today_buy = Math.Round((amount + position.price_cost_today_buy * position.count_today_buy) / (deal.count + position.count_today_buy), 6); position.count_today_buy = deal.count + position.count_today_buy; } PositionRA.UpdateBuy(position, key_position); } else { position.count = position.count - deal.count; if (type == 0 || type == 1) { position.price_cost_today_sell = Math.Round((amount + position.price_cost_today_sell * position.count_today_sell) / (deal.count + position.count_today_sell), 6); position.count_today_sell = deal.count + position.count_today_sell; } PositionRA.UpdateSell(position, key_position); } } else { HQItem hq = HQService.Get(deal.code); BlockInfo block = StockInfoBiz.GetBlock(deal.code); if (block == null) { return; } position = new Position() { code = deal.code, name = deal.name, unit_id = deal.unit_id, account_id = deal.account_id, block_enum = block.block_type_enum, price_latest = hq != null ? hq.Last : 0 }; if (deal.type == 0) { position.price_cost = Math.Round(amount / deal.count, 6); position.count = deal.count; if (type == 0 || type == 1) { position.price_cost_today_buy = position.price_cost; position.count_today_buy = position.count; } else if (type == 2) { position.count_sellable = position.count; } } else { position.price_cost = Math.Round(amount / deal.count, 6); position.count = position.count_sellable = -deal.count; if (type == 0 || type == 1) { position.price_cost_today_sell = position.price_cost; position.count_today_sell = deal.count; } } PositionRA.Add(position, key_position); } RunCalculateValue(); }
public static ApiResultEnum Order(Order order) { ApiResultEnum result = LimitBiz.CheckStatus(order); if (result != ApiResultEnum.Success) { return(result); } result = LimitBiz.CheckUnit(order); if (result != ApiResultEnum.Success) { return(result); } Dictionary <int, int> order_items; if (order.account_id == 0) { order_items = LimitBiz.GetOrderAccount(order); } else { order_items = new Dictionary <int, int>() { { order.account_id, order.count } } }; if (order_items.Count == 0) { return(ApiResultEnum.Order_Unit_No_Account); } if (order_items.Sum(i => i.Value) == 0) { return(ApiResultEnum.Order_Group_Negative_Amount); } int order_count = 0; order.trade_no = FuncHelper.GetUniqueID().ToString(); order.trade_count = order.count; foreach (var kvp in order_items) { if (kvp.Value == 0) { continue; } order.account_id = kvp.Key; order.count = kvp.Value; result = LimitBiz.CheckAccount(order); if (result != ApiResultEnum.Success) { continue; } BlockInfo block = StockInfoBiz.GetBlock(order.code); order.price = Math.Round(order.price, block.@decimal); jybizs[order.account_id].Order(order); order_count += order.count; } if (order_count == 0) { return(result); } if (order_count < order.count) { return(ApiResultEnum.Success_Portion); } 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)); } }
//检查主账户是否满足下单条件 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); }