public static void DoOpen() { LogHelper.WriteInfo("执行期货开市动作DoOpen"); DoBaseData(); try { //还没到开市,不处理 if (CanDoOpen()) { if (ScheduleManager.CanEndCache()) { MemoryDataManager.End(); } DoFutureDayCheck(); } } catch (Exception ex) { LogHelper.WriteError("期货开市DoOpen处理异常", ex); } //add 2010-03-16 添加对期货的清算判断,如果发现前一日没有清算完成则设置期货是否清算异常系统暂停交易,使用期台不能下单 string errMsg = ""; DateTime ReckoningDateTime; bool isReckoning = false; isReckoning = StatusTableChecker.IsFutureReckoningFaultRecovery(out ReckoningDateTime, out errMsg); if (isReckoning) { IList <CM_BreedClass> list = MCService.CommonPara.GetAllBreedClass(); foreach (var item in list) { if (item.BreedClassTypeID.Value == (int)GTA.VTS.Common.CommonObject.Types.BreedClassTypeEnum.CommodityFuture || item.BreedClassTypeID.Value == (int)GTA.VTS.Common.CommonObject.Types.BreedClassTypeEnum.StockIndexFuture) { ScheduleManager.IsFutureReckoningErrorStopTrade = true; break; } } } //else //{ // ScheduleManager.IsFutureReckoningErrorStopTrade = false; //} //================== ScheduleManager.HasDoneFutureOpen = true; ScheduleManager.HasDoneOpenNotify(); }
/// <summary> /// 用于故障恢复清算 /// </summary> /// <param name="recktime">要清算的日期</param> public static void DoFaultRecoveryClose(string recktime) { //add 2010-03-16 //2.可以清算时,先初始化所有的今日结算价 //3.检查当前持仓表中所有持仓合约都能获取得到结算价时再执行清算 //2. MCService.IniFutureTodayPreSettlementPriceRecovery(); //3. QH_HoldAccountTableDal dal = new QH_HoldAccountTableDal(); List <QH_HoldAccountTableInfo> models = dal.GetAllListArray(); decimal price; foreach (var item in models) { //如果持仓量有就要获取,如果都已经没有了持仓量证明已经清算完毕不再再清算 if (item.HistoryFreezeAmount + item.HistoryHoldAmount + item.TodayFreezeAmount + item.TodayHoldAmount > 0) { if (!MCService.GetFutureTodayPreSettlementPriceByCache(item.Contract, out price)) { LogHelper.WriteError("故障恢复期货清算获取今日结算价无法获取:" + item.Contract, new Exception("清算中止")); return; } } } //把是否正在做故障恢复清算状态修改回来为true,正在进行 ScheduleManager.IsFaultRecoveryFutureReckoning = true; ScheduleManager.CurrentFaultRecoveryFutureReckoningDate = DateTime.Parse(recktime); InternalDoClose(); //现货也设置清算完成,为了后面能提交现货的相关数据内存表中的数据 ScheduleManager.HasDoneStockReckoning = true; ScheduleManager.HasDoneFutureReckoning = true; ScheduleManager.ReckoningDoneNotify(); //证明已经故障恢复清算已经成功那么更新清算记录表记录 if (ScheduleManager.IsFutureReckoningErrorStopTrade == false) { //故障恢复清算完成修改清算日期标志,因为内部之前 的方法直接修改为当前的了,这里要修改回当招提交的数据日期 recktime = DateTime.Parse(recktime).ToShortDateString() + " " + DateTime.Now.ToString("HH:mm:ss"); StatusTableChecker.UpdateFutureReckoningDate(recktime, null); } //清空当前所有的缓存当前清算时添加的缓存数据 MCService.ClearFuterTodayPreSettlemmentPrice(); //把是否正在做故障恢复清算状态修改回来为false ScheduleManager.IsFaultRecoveryFutureReckoning = false; }
/// <summary> /// 期货盘后清算 /// </summary> public static bool DoReckoning() { if (StatusTableChecker.HasDoneFutureReckoning(DateTime.Now)) { return(true); } LogHelper.WriteInfo("------------开始期货收市处理-DoReckoning[期货盘后清算]"); bool result = false; try { result = ReckoningService.ProcessFuture(); if (!result) { LogHelper.WriteInfo("***期货收市处理-DoReckoning[期货盘后清算]第1次失败!进行第2次处理"); result = ReckoningService.ProcessFuture(); } if (!result) { LogHelper.WriteInfo("***期货收市处理-DoReckoning[期货盘后清算]第2次失败!进行第3次处理"); result = ReckoningService.ProcessFuture(); } if (!result) { LogHelper.WriteInfo("***期货收市处理-DoReckoning[期货盘后清算]第3次失败!!退出"); } else { LogHelper.WriteInfo("------------完成期货收市处理-DoReckoning[期货盘后清算]"); } LogHelper.WriteInfo("------------完成期货收市处理-DoReckoning[期货盘后清算]"); } catch (Exception ex) { LogHelper.WriteError(ex.ToString(), ex); LogHelper.WriteInfo("------------期货收市处理失败-DoReckoning[期货盘后清算]"); } return(result); }
/// <summary> /// 港股盘后清算 /// </summary> private static bool DoHKReckoning() { if (StatusTableChecker.HasDoneHKReckoning(DateTime.Now)) { return(true); } LogHelper.WriteInfo("------------开始港股收市处理-DoHKReckoning[港股盘后清算]"); bool result = false; try { result = ReckoningService.ProcessHK(); if (!result) { LogHelper.WriteInfo("***港股收市处理-DoHKReckoning[港股盘后清算]第1次失败!进行第2次处理"); result = ReckoningService.ProcessHK(); } if (!result) { LogHelper.WriteInfo("***港股收市处理-DoHKReckoning[港股盘后清算]第2次失败!进行第3次处理"); result = ReckoningService.ProcessHK(); } if (!result) { LogHelper.WriteInfo("***港股收市处理-DoHKReckoning[港股盘后清算]第3次失败!!退出"); } else { LogHelper.WriteInfo("------------完成港股收市处理-DoHKReckoning[港股盘后清算]"); } } catch (Exception ex) { LogHelper.WriteError(ex.ToString(), ex); LogHelper.WriteInfo("------------证券收市处理失败-DoHKReckoning[证券盘后清算]"); } return(result); }
/// <summary> /// 分红处理 /// </summary> public static bool DoMelonCutting() { if (StatusTableChecker.HasDoneMelonCut(DateTime.Now)) { return(true); } bool result = false; LogHelper.WriteInfo("------------开始证券收市处理-DoMelonCutting[分红处理]"); try { result = MelonCutService.Process(); if (!result) { LogHelper.WriteInfo("***证券收市处理-DoMelonCutting[分红处理]第1次失败!进行第2次处理"); result = MelonCutService.Process(); } if (!result) { LogHelper.WriteInfo("***证券收市处理-DoMelonCutting[分红处理]第2次失败!进行第3次处理"); result = MelonCutService.Process(); } if (!result) { LogHelper.WriteInfo("***证券收市处理-DoMelonCutting[分红处理]第3次失败!退出"); } else { LogHelper.WriteInfo("------------完成证券收市处理-DoMelonCutting[分红处理]"); } } catch (Exception ex) { LogHelper.WriteError(ex.ToString(), ex); LogHelper.WriteInfo("------------证券收市处理失败-DoMelonCutting[分红处理]"); } return(result); }
/// <summary> /// 港股历史数据处理 /// </summary> private static void DoHKHistoryDataProcess() { if (StatusTableChecker.HasDoneHKHistoryDataProcess(DateTime.Now)) { return; } LogHelper.WriteInfo("------------开始港股收市处理-DoHKHistoryDataProcess[历史数据处理]"); try { HistoryDataService.ProcessHK(); LogHelper.WriteInfo("------------完成港股收市处理-DoHKHistoryDataProcess[历史数据处理]"); } catch (Exception ex) { LogHelper.WriteError(ex.ToString(), ex); LogHelper.WriteInfo("------------港股收市处理失败-DoHKHistoryDataProcess[历史数据处理]"); } }
/// <summary> /// 进行期货每日开盘检查 /// </summary> private static void DoFutureDayCheck() { if (StatusTableChecker.HasDoneFutureDayCheck(DateTime.Now)) { return; } LogHelper.WriteInfo("------------期货开市处理-DoFutureDayCheck[进行期货每日开盘检查]"); try { FutureDayChecker checker = new FutureDayChecker(); checker.Process(); LogHelper.WriteInfo("------------完成期货开市处理-DoFutureDayCheck[进行期货每日开盘检查]"); } catch (Exception ex) { LogHelper.WriteError(ex.ToString(), ex); LogHelper.WriteInfo("------------期货开市处理失败-DoFutureDayCheck[进行期货每日开盘检查]"); } }
/// <summary> /// 历史数据处理 /// </summary> public static void DoHistoryDataProcess() { if (StatusTableChecker.HasDoneFutureHistoryDataProcess(DateTime.Now)) { return; } LogHelper.WriteInfo("------------开始期货收市处理-DoHistoryDataProcess[历史数据处理]"); try { HistoryDataService.ProcessFuture(); HistoryDataService.ProcessUnReckonedTable(); LogHelper.WriteInfo("------------完成期货收市处理-DoHistoryDataProcess[历史数据处理]"); } catch (Exception ex) { LogHelper.WriteError(ex.ToString(), ex); LogHelper.WriteInfo("------------期货收市处理失败-DoHistoryDataProcess[历史数据处理]"); } }
/// <summary> /// 今日期货是否可以执行清算(内部即检查当前时间与记录比较前一日是否请算完成) /// </summary> /// <param name="faultRecoveryTime">能够清算的时间</param> /// <param name="errMsg">查询返回异常或者提示信息</param> /// <returns></returns> public static bool IsFutureTodayReckoning(out DateTime faultRecoveryTime, out string errMsg) { errMsg = ""; //要执行清算的日期 faultRecoveryTime = DateTime.Now; string dateTime = StatusTableChecker.GetFutureReckoningHasDone(); if (string.IsNullOrEmpty(dateTime)) { errMsg = "清算状态表无记录,可以执行清算!"; return(true); } DateTime lastDate = DateTime.Parse(dateTime); if (lastDate.Day == DateTime.Now.Day) { errMsg = "今日已经执行清算完成!"; return(false); } else if (lastDate.Date.AddDays(1).Date == DateTime.Now.Date) { //DateTime nowDate = DateTime.Now; //DateTime firstBeginTime = new DateTime(nowDate.Year, nowDate.Month, nowDate.Day, ScheduleManager.FirstBeginTime.Hour, ScheduleManager.FirstBeginTime.Minute, ScheduleManager.FirstBeginTime.Second); //DateTime lastEndTime = new DateTime(nowDate.Year, nowDate.Month, nowDate.Day, ScheduleManager.LastEndTime.Hour, ScheduleManager.LastEndTime.Minute, ScheduleManager.LastEndTime.Second); //if (nowDate >= firstBeginTime && nowDate <= lastEndTime) //{ // errMsg = "今日还没有到清算的时间,请稍后再试!"; // return false; //} return(true); } faultRecoveryTime = lastDate; bool isTradeDate = false; while (!isTradeDate) { //判断是否是星期六星期日,如果是向后推清算日期 for (int i = 1; i <= 3; i++) { faultRecoveryTime = faultRecoveryTime.AddDays(i); if (faultRecoveryTime.DayOfWeek == DayOfWeek.Sunday || faultRecoveryTime.DayOfWeek == DayOfWeek.Saturday) { continue; } else { break; } } //获取到要清算的日期再判断是否是非交易日期,如果是再向后推(while) //获取 所有期货的交易所的ID //IList<CM_BourseType> cm_bourseList = MCService.CommonPara.GetAllBourseType(); List <int> cm_bourseList = new List <int>(); //获取所有品种类别 IList <CM_BreedClass> cm_breedClass = MCService.CommonPara.GetAllBreedClass(); //过期不是期货的不用判断 foreach (var item in cm_breedClass) { switch ((Types.BreedClassTypeEnum)item.BreedClassTypeID) { case Types.BreedClassTypeEnum.Stock: break; case Types.BreedClassTypeEnum.CommodityFuture: case Types.BreedClassTypeEnum.StockIndexFuture: if (!cm_bourseList.Contains(item.BourseTypeID.Value)) { cm_bourseList.Add(item.BourseTypeID.Value); } break; case Types.BreedClassTypeEnum.HKStock: break; default: break; } } //要所有交易所都为非交易日时才可以清算 foreach (var item in cm_bourseList) { isTradeDate = MCService.CommonPara.IsTradeDate(item, faultRecoveryTime); if (isTradeDate) { break; } } } if (faultRecoveryTime.Date == DateTime.Now.Date) { return(true); } return(false); }
/// <summary> /// 期货是否要执行期货清算故障恢复 /// </summary> /// <param name="faultRecoveryTime">要执行故障恢复清算的日期</param> /// <param name="errMsg">查询返回异常或者提示信息</param> /// <returns></returns> public static bool IsFutureReckoningFaultRecovery(out DateTime faultRecoveryTime, out string errMsg) { errMsg = ""; //要执行清算的日期 faultRecoveryTime = DateTime.Now; try { string dateTime = StatusTableChecker.GetFutureReckoningHasDone(); if (string.IsNullOrEmpty(dateTime)) { errMsg = "清算状态表记录无法获取,有异常请检查!"; return(false); } DateTime lastDate = DateTime.Parse(dateTime); if (lastDate.Day == DateTime.Now.Day) { errMsg = "今日已经执行清算完成!"; return(false); } else if (lastDate.Date.AddDays(1).Date == DateTime.Now.Date) { DateTime nowDate = DateTime.Now; DateTime firstBeginTime = new DateTime(nowDate.Year, nowDate.Month, nowDate.Day, ScheduleManager.FirstBeginTime.Hour, ScheduleManager.FirstBeginTime.Minute, ScheduleManager.FirstBeginTime.Second); DateTime lastEndTime = new DateTime(nowDate.Year, nowDate.Month, nowDate.Day, ScheduleManager.LastEndTime.Hour, ScheduleManager.LastEndTime.Minute, ScheduleManager.LastEndTime.Second); if (nowDate >= firstBeginTime && nowDate <= lastEndTime) { errMsg = "今日还没有到清算的时间,请稍后再试!"; return(false); } //如果当前时间是零晨到开市之前的也应该不用执行清算 if (nowDate >= DateTime.Now.Date && nowDate <= firstBeginTime) { errMsg = "今日还没有到清算的时间,请稍后再试!"; return(false); } //如果不在交易时间内了,还没有清算完成那么返回要执行清算 //这里判断已经保证是在当前了 //这里再加二十分钟是因为清算时要时间(设置二十分钟因为测试过有一万用户的时间期货清算大约要五分钟) if (nowDate > lastEndTime.AddMinutes(20)) { return(true); } } //处理星期五清算不成功,然后星期一处理的手动执行清算后 #region update 2010-03-17 old code //bool isTradeDate = false; //while (!isTradeDate) //{ // //判断是否是星期六星期日,如果是向后推清算日期 // for (int i = 1; i <= 3; i++) // { // faultRecoveryTime = lastDate.AddDays(i); // if (faultRecoveryTime.DayOfWeek == DayOfWeek.Sunday || faultRecoveryTime.DayOfWeek == DayOfWeek.Saturday) // { // continue; // } // else // { // break; // } // } // //获取到要清算的日期再判断是否是非交易日期,如果是再向后推 // IList<CM_BourseType> cm_bourseList = MCService.CommonPara.GetAllBourseType(); // foreach (var item in cm_bourseList) // { // isTradeDate = MCService.CommonPara.IsTradeDate(item.BourseTypeID, faultRecoveryTime); // if (!isTradeDate) // { // break; // } // } //} #endregion #region 2010-03-17 new //这里返回的,我们只要补完当前日期的前一天的记录即可 bool isTradeDate = false; while (!isTradeDate) { #region 判断是否是星期六星期日,如果是向后推清算日期 //判断是否是星期六星期日,如果是向后推清算日期 for (int i = 1; i <= 3; i++) { faultRecoveryTime = faultRecoveryTime.AddDays(-1); //向前推日期,如果是星期六星期日再向前推 if (faultRecoveryTime.DayOfWeek == DayOfWeek.Sunday || faultRecoveryTime.DayOfWeek == DayOfWeek.Saturday) { continue; } else { break; } } #endregion //如果向前推到最后还是和原来的清算日期相等那么就不用再清算 if (faultRecoveryTime.ToShortDateString() == lastDate.ToShortDateString()) { errMsg = "今日向前再推算日期与之前正常清算的日期相符,不用再清算!"; return(false); } #region 过期不是期货的不用判断 //获取到要清算的日期再判断是否是非交易日期,如果是再向后推(while) //获取 所有期货的交易所的ID //IList<CM_BourseType> cm_bourseList = MCService.CommonPara.GetAllBourseType(); List <int> cm_bourseList = new List <int>(); //获取所有品种类别 IList <CM_BreedClass> cm_breedClass = MCService.CommonPara.GetAllBreedClass(); //过期不是期货的不用判断 foreach (var item in cm_breedClass) { switch ((Types.BreedClassTypeEnum)item.BreedClassTypeID) { case Types.BreedClassTypeEnum.Stock: break; case Types.BreedClassTypeEnum.CommodityFuture: case Types.BreedClassTypeEnum.StockIndexFuture: if (!cm_bourseList.Contains(item.BourseTypeID.Value)) { cm_bourseList.Add(item.BourseTypeID.Value); } break; case Types.BreedClassTypeEnum.HKStock: break; default: break; } } #endregion //要每个交易所都是非交易时间才可以进行清算故障恢复 foreach (var item in cm_bourseList) { isTradeDate = MCService.CommonPara.IsTradeDate(item, faultRecoveryTime); if (isTradeDate) { #region 再处理向前推日期,解决星期五清算不成功,星期一进行清算时再获取清算的日志返回故障恢复清算错误,即把日期再返回未清算紧跟的非交易日后 DateTime requestDate = faultRecoveryTime; //只处理星期六星期日 for (int i = 1; i <= 3; i++) { requestDate = requestDate.AddDays(1); if (requestDate.DayOfWeek == DayOfWeek.Sunday || requestDate.DayOfWeek == DayOfWeek.Saturday) { faultRecoveryTime = requestDate; //如果当前时间是星期六那么就直接退出用星期六即可 if (requestDate.Date == DateTime.Now.Date) { break; } continue; } else { break; } } #endregion return(true); } } } #endregion } catch (Exception ex) { LogHelper.WriteError(ex.Message, ex); } return(true); }
public static void DoClose() { //还没到收市,不处理 if (DateTime.Now.Hour < ScheduleManager.LastEndTime.Hour) { return; } if (DateTime.Now.Hour == ScheduleManager.LastEndTime.Hour) { if (DateTime.Now.Minute < ScheduleManager.LastEndTime.Minute) { return; } } LogHelper.WriteInfo("执行期货收市动作DoClose"); //===update 李健华 2009-12-14 //这里已经在现货清算中提交过,也再得新加载过,在清算完成后会统一再提交一次 //先关闭内存管理器 // MemoryDataManager.End(); //========== MCService.DoMarketCloseJob(); //add 2010-03-16 //1.发现前一日没有清算完成今日也不能清算 (这个不用了,系统自动清算只要把当日或者前一日的清算完成即可,系统只要保证没有清算完成不可下单操作即可) //2.可以清算时,先初始化所有的今日结算价 //3.检查当前持仓表中所有持仓合约都能获取得到结算价时再执行清算 //=============== //1. string errMsg = ""; bool isReck = false; DateTime recktime; isReck = StatusTableChecker.IsFutureTodayReckoning(out recktime, out errMsg); //if (!isReck) //{ // LogHelper.WriteError("今日期货清算不能执行清算,时间获取为:" + recktime, new Exception(errMsg)); // return; //} //2. //3. QH_HoldAccountTableDal dal = new QH_HoldAccountTableDal(); List <QH_HoldAccountTableInfo> models = dal.GetAllListArray(); decimal price; foreach (var item in models) { //如果持仓量有就要获取,如果都已经没有了持仓量证明已经清算完毕不再再清算 if (item.HistoryFreezeAmount + item.HistoryHoldAmount + item.TodayFreezeAmount + item.TodayHoldAmount > 0) { if (!MCService.GetFutureTodayPreSettlementPriceByCache(item.Contract, out price)) { //如果代码还是可以交易的代码则中止清算,已经过期忽略不理,内部清算的时候获取不到会不会修改持仓均价相关的内容 if (!MCService.IsExpireLastedTradeDate(item.Contract)) { //但当代码当日为非交易日时也可以放过 //如果发现前一日没有清算完成今日获取不到价格不能放过 if (!isReck || MCService.CommonPara.IsTradeDate(item.Contract, DateTime.Now)) { //为了防止每日重启程序时时间已经过了收市时间即到了清算时间所作的每次清算而已经清算成功的再设置为不清算成功 //如:20100402的五点时重启程序,这时已经四点半已经清算成功,那些这里再清算而又获取不到行情就会设置错误,而这里应该不设置,放过 //因为内部还会检查是否清算成功过 if (!StatusTableChecker.HasDoneFutureReckoning(DateTime.Now)) { LogHelper.WriteError("今日期货清算获取今日结算价无法获取:" + item.Contract, new Exception("清算中止")); //暂停交易 ScheduleManager.IsFutureReckoningErrorStopTrade = true; return; } } ////如果发现前一日没有清算完成今日获取不到价格不能放过 //else if (!isReck) //{ // LogHelper.WriteError("今日期货清算获取今日结算价无法获取:" + item.Contract, new Exception("前一日清算异常,今日清算中止")); // //暂停交易 // ScheduleManager.IsFutureReckoningErrorStopTrade = true; // return; //} } } } } //清算之前把所有柜台缓存的清算撮合ID的数据清除 QHCounterCache.Instance.ResetDictionary(); InternalDoClose(); ScheduleManager.HasDoneFutureReckoning = true; ScheduleManager.ReckoningDoneNotify(); ////过了收市时间,开始处理,延时5分钟,等现货做完后再做 //timer = new Timer(); //timer.Interval = 1*60*1000; //timer.Elapsed += delegate // { // timer.Enabled = false; // LogHelper.WriteInfo("执行期货收市动作DoClose"); // InternalDoClose(); // InternalDoClose(); // InternalDoClose(); // }; //timer.Enabled = true; //期货清算完成后把资金管理的相关账号清除,释放内存 AccountManager.Instance.Reset(); }