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 RunOrderAuto() { List <OrderAuto> orders = OrderAutoRA.List4Undone(); foreach (OrderAuto orderAuto in orders) { if (orderAuto.status_enum != StatusAutoOrderEnum.Run) { continue; } if (orderAuto.time_next_dt > DateTime.Now) { continue; } string key = "S_" + orderAuto.id + "_U_" + orderAuto.unit_id + "_D_0"; Random random = new Random(); Order order = new Order() { code = orderAuto.code, type = orderAuto.type, unit_id = orderAuto.unit_id, account_id = orderAuto.account_id, user_id = orderAuto.user_id, platform = orderAuto.platform }; order.count = orderAuto.count_total - orderAuto.order_count; orderAuto.time_next_dt = DateTime.MinValue; if (order.count > orderAuto.count_max) { order.count = random.Next(orderAuto.count_min / 100, orderAuto.count_max / 100) * 100; orderAuto.time_next_dt = DateTime.Now.AddSeconds(random.Next(orderAuto.time_min, orderAuto.time_max)); } if (orderAuto.time_next_dt >= time_pause && orderAuto.time_next_dt <= time_recovery) { orderAuto.time_next_dt = orderAuto.time_next_dt.AddMinutes(90); } if (orderAuto.time_next_dt >= time_close) { OrderAutoRA.UpdateStatus(StatusAutoOrderEnum.Stop, 1, key); continue; } order.price = DataBiz.GetPriceByPriceType(orderAuto.code, orderAuto.price_type_enum); if (order.price < orderAuto.price_min) { order.price = orderAuto.price_min; } else if (order.price > orderAuto.price_max) { order.price = orderAuto.price_max; } ApiResultEnum result = Order(order.Clone() as Order); orderAuto.result_prev = new Model.Return.Return(result).Message; orderAuto.order_times++; orderAuto.order_count += order.count; orderAuto.time_prev_dt = DateTime.Now; OrderAutoRA.UpdateExecuted(orderAuto, order, key); } }
//检查单元是否满足下单条件 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); }