public void CloseChanceInDBAndExchangeService(DbChanceList <T> NeedClose, bool ForceClose = false) { if (NeedClose == null || NeedClose.Count == 0) { return; } foreach (Int64 id in NeedClose.Keys) { NeedClose[id].IsEnd = 1; if (ForceClose) { NeedClose[id].MatchChips = 0; } ////NeedClose[id].Gained = NeedClose[id].MatchChips * NeedClose[id].Odds * NeedClose[id].UnitCost; ////NeedClose[id].Profit = NeedClose[id].Gained - NeedClose[id].Cost; NeedClose[id].CalcProfit(NeedClose[id].MatchChips); NeedClose[id].UpdateTime = DateTime.Now; } //int ret = NeedClose.Save(null); if (NeedClose != null && NeedClose.Count > 0) { //int ret = new PK10ExpectReader().SaveChances(NeedClose.Values.ToList<ChanceClass<T>>(), null); int ret = DataReaderBuild.CreateReader(DataPoint.DataType, ReadDataTableName, Codes).SaveChances(NeedClose.Values.ToList <ChanceClass <T> >(), null); if (NeedClose.Count > 0) { Log("保存关闭的机会", string.Format("数量:{0}", ret)); } } }
public MainForm() : base() { InitializeComponent(); gobj = new GlobalClass(); dtp = GlobalClass.TypeDataPoints.First().Value; er = DataReaderBuild.CreateReader(dtp.DataType, null, null); Program.optFunc.RefreshMainWindow += refreshData; }
bool CheckFinished() { try { string path = @"c:\inetpub\wwwroot\PK10\InstData\" + DataPoint.DataType; string strExpectNo = "expectNo"; string strResult = "record"; string strForApp = "expertNoForApp"; string strtype = "txt"; this.FinishedThreads++; //if (IsTestBack) return true; //如果是回测,不做处理 //Log("进程结束", string.Format("目标{1},现有{0}",this.FinishedThreads,this.RunThreads)); if (FinishedThreads == RunThreads) { OnFinishedCalc(DataPoint); ThreadPools = new List <Thread>(); if (IsTestBack) { return(true); //如果是回测,不做处理 } Log("写入标志文件", "供web程序读取!"); string expectCode = CurrData.LastData.Expect; DataReader rder = DataReaderBuild.CreateReader(DataPoint.DataType, ReadDataTableName, Codes); string NewExpectNo = DataReader.getNextExpectNo(expectCode, DataPoint); string NewNo = string.Format("{0}|{1}|{2}", NewExpectNo, CurrData.LastData.OpenTime, CurrData.LastData.OpenCode); rder.updateExpectInfo(DataPoint.DataType, NewExpectNo, expectCode); new LogInfo().WriteFile(NewNo, path, strExpectNo, strtype, true, true); //保存策略 GlobalClass.SaveStragList(BaseStragClass <TimeSerialData> .getXmlByObjectList <BaseStragClass <TimeSerialData> >(Program.AllServiceConfig.AllStrags.Values.ToList <BaseStragClass <TimeSerialData> >())); Log("保存策略清单", "保存成功"); } } catch (Exception ce) { } return(true); }
public frm_StragMonitor() { InitializeComponent(); //chart_ForGuide_Paint dtp = GlobalClass.TypeDataPoints.First().Value; exread = DataReaderBuild.CreateReader(dtp.DataType, null, null); PK10DataTimer.Interval = GlobalClass.TypeDataPoints.First().Value.ReceiveSeconds * 1000; PK10DataTimer.AutoReset = true; PK10DataTimer.Elapsed += new ElapsedEventHandler(RefreshPK10Data); PK10DataTimer.Enabled = false; LogTimer.Interval = 3 * 60 * 1000; LogTimer.AutoReset = true; LogTimer.Elapsed += new ElapsedEventHandler(RefreshLogInfo); LogTimer.Enabled = false; //RefreshLogInfo(null,null); //RefreshPK10Data(null, null); //RefreshPK10Data(); //RefreshPK10NoClosedChances(); dg_StragList.ContextMenuStrip = this.contextMenuStrip_OperatePlan; //dg_NoCloseChances.ContextMenuStrip = this.contextMenuStrip_OperatePlan; CheckForIllegalCrossThreadCalls = false; Program.optFunc.RefreshMonitorWindow += refreshSvrData; }
public new void ExecRun(object data) { ExpectList <T> el = data as ExpectList <T>; //2019/4/22日出现错过732497,732496两期记录错过,但是732498却收到的情况,同时,正好在732498多次重复策略正好开出结束,因错过2期导致一直未归零, //一直长时间追号开出近60期 //为避免出现这种情况 //判断是否错过了期数,如果错过期数,将所有追踪策略归零,不再追号,也不再执行选号程序, //是否要连续停几期?执行完后,在接收策略里面发现前10期有不连续的情况,直接跳过,只接收数据不执行选号。 if (el.MissExpectCount() > 1)//期号不连续 { } //Log("计算服务","准备数据", "为每个策略分配数据"); foreach (string key in UseStrags.Keys) { UseStrags[key].SetLastUserData(el); } //准备数据 BaseCollection <T> cc = null; int maxViewCnt = (int)this.UseStrags.Max(t => t.Value.ReviewExpectCnt); //Log("计算服务", "最大回览期数", maxViewCnt.ToString()); cc = new ExpectListProcessBuilder <T>(dtp, el).getProcess().getSerialData(maxViewCnt, this.UseSerial); // cc.orgData = el;//必须指定原始数据? //Log("计算服务", "中间数据长度",cc.Data.Count.ToString()); Dictionary <StragClass, List <ChanceClass> > css = new Dictionary <StragClass, List <ChanceClass> >(); //Log("计算服务", "计算数据", "为每个策略计算最大回顾周期数据"); //遍历每个策略获得机会 DbChanceList <T> OldDbList = new DbChanceList <T>(); Dictionary <string, ChanceClass <T> > OldList = new Dictionary <string, ChanceClass <T> >(); List <ChanceClass <T> > NewList = new List <ChanceClass <T> >(); //Log("计算服务", "遍历所有策略", string.Format("策略数量:{0}",this.UseStrags.Count)); CloseAllExchance(el);//清空所有可视化机会 #region 获取交易机会 for (int i = 0; i < this.UseSPlans.Count; i++) { StragRunPlanClass <T> currPlan = UseSPlans[i]; if (currPlan.PlanStrag == null)//如果计划所执行的策略为空,只在chance上执行tracer { List <ChanceClass <T> > emptycs = CurrExistChanceList.Values.Where(p => p.StragId == null).ToList <ChanceClass <T> >(); for (int c = 0; c < emptycs.Count; c++) { ChanceClass <T> CurrCc = emptycs[c]; TraceChance <T> tcc = CurrCc as TraceChance <T>; CurrCc.UnitCost = tcc.getChipAmount(GlobalClass.DefaultMaxLost, CurrCc, GlobalClass._DefaultHoldAmtSerials.Value); CurrCc.HoldTimeCnt = CurrCc.HoldTimeCnt + 1; CurrCc.Cost += CurrCc.ChipCount * CurrCc.UnitCost; CurrCc.UpdateTime = CurrCc.CreateTime; OldList.Add(CurrCc.GUID, CurrCc); if (!IsBackTest)//非回测需要额外保存数据 { OldDbList.Add(CurrCc.ChanceIndex, CurrCc); } } continue; } BaseStragClass <T> currStrag = UseStrags[currPlan.PlanStrag.GUID]; currStrag.SetLastUserData(el); //必须<T>给策略填充数据 List <ChanceClass <T> > cs = currStrag.getChances(cc, el.LastData); //获取该策略的机会 if (currStrag is TotalStdDevTraceStragClass) //如果是整体标准差类,记录所有的标准差数据 { grpTotolStdDic = (currStrag as TotalStdDevTraceStragClass).getAllStdDev(); } if (cs.Count > 0) { Log("计算服务", string.Format("策略[{0}/{1}]", currStrag.GUID, currStrag.StragScript), string.Format("取得机会数量为:{0}", cs.Count)); } Dictionary <string, ChanceClass <T> > StragChances = CurrExistChanceList.Where(p => p.Value.StragId == currStrag.GUID).ToDictionary(p => p.Value.ChanceCode, p => p.Value); AmoutSerials amts = GlobalClass.getOptSerials(CurrSetting.Odds, currPlan.InitCash, 1); Int64 restAmt = currStrag.CommSetting.GetGlobalSetting().DefMaxLost; //初始资金 #region 遍历各机会 for (int j = 0; j < cs.Count; j++) //对每个机会,检查上期遗留的机会是否包括 { bool NeedUseOldData = false; ChanceClass <T> CurrCc = cs[j]; CurrCc.HoldTimeCnt = 1; CurrCc.AllowMaxHoldTimeCnt = currPlan.AllowMaxHoldTimeCnt; CurrCc.IncrementType = currPlan.IncreamType; if (currPlan.IncreamType == InterestType.CompoundInterest) { CurrCc.FixRate = currPlan.FixRate; } else { CurrCc.FixAmt = currPlan.FixAmt; } //该语句存在机会重复的风险 if (StragChances.ContainsKey(CurrCc.ChanceCode))//未关闭的及机会列表中存在该机会 { ChanceClass <T> OldCc = StragChances[CurrCc.ChanceCode]; //Log("计算服务", "老机会信息", string.Format("idx:{0};holdcnt:{1}", OldCc.ChanceIndex, OldCc.HoldTimeCnt)); //Log("计算服务", "老记录", string.Format("上期相同的机会{0}", CurrCc.ChanceCode)); //Log("计算服务", "判断是否允许重复", currStrag.AllowRepeat.ToString()); if (!currStrag.AllowRepeat)//如果不允许重复 { CurrCc = OldCc; CurrCc.HoldTimeCnt = CurrCc.HoldTimeCnt + 1; NeedUseOldData = true; Log("计算服务", "相同处理", string.Format("出现相同的机会{0},持有次数增1->{1}", CurrCc.ChanceCode, CurrCc.HoldTimeCnt)); } } else { //Log("计算服务", string.Format("上期相同未关闭的机会数{0},{1}", CurrExistChanceList.Count, CurrCc.ChanceCode), "本期未出现"); } if (currPlan.AssetUnitInfo != null) { if (this.UseAssetUnits.ContainsKey(currPlan.AssetUnitInfo.UnitId)) { AssetUnitClass useUnit = UseAssetUnits[currPlan.AssetUnitInfo.UnitId]; if (!useUnit.Running) { useUnit.Run(); } restAmt = (long)useUnit.getCurrExchangeServer().summary; } else { continue; } } //Log("计算服务", "再次检查数据", string.Format("出现相同的机会{0},持有次数增1.->{1}", CurrCc.ChanceCode, CurrCc.HoldTimeCnt)); CurrCc.UnitCost = -1; //先默认为-1 if (currStrag is WolfInv.com.BaseObjectsLib.ISpecAmount) //先从策略级别判断 { WolfInv.com.BaseObjectsLib.ISpecAmount testStrag = (currStrag as WolfInv.com.BaseObjectsLib.ISpecAmount); if (testStrag == null) { //等待下一步按机会级别判断 } else { CurrCc.UnitCost = testStrag.getChipAmount(restAmt, CurrCc, amts); } } if (CurrCc.UnitCost < 0) //如果策略级别未改变值 { if (CurrCc.IsTracer == 1) //如果是自我追踪机会 { Log("计算服务", "自我跟踪机会,当前持有次数", string.Format("HoldTimes:{0}", CurrCc.HoldTimeCnt)); TraceChance <T> useCc = Convert.ChangeType(CurrCc, currStrag.getTheChanceType()) as TraceChance <T>; //Log("计算服务", "使用的机会持有次数", string.Format("HoldTimes:{0}", useCc.HoldTimeCnt)); if (useCc == null) //获得的类型并非跟踪类型 { CurrCc.UnitCost = (currStrag as ChanceTraceStragClass).getChipAmount(restAmt, CurrCc, amts); } else { CurrCc.UnitCost = useCc.getChipAmount <T>(restAmt, CurrCc, amts); } } else//默认为ChanceTraceStragClass,其实是不可能触发的,而且会出错,因为ChanceTraceStragClass本身就是ispaceamount { Log("计算服务", "非跟踪机会,持有次数", string.Format("HoldTimes:{0}", CurrCc.HoldTimeCnt)); CurrCc.UnitCost = (currStrag as ChanceTraceStragClass).getChipAmount(restAmt, CurrCc, amts); } } //Log("计算服务", "再二次检查数据", string.Format("出现相同的机会{0},持有次数增1->{1}", CurrCc.ChanceCode, CurrCc.HoldTimeCnt)); if (NeedUseOldData)//未关闭的及机会列表中存在该机会 { Log("计算服务", "策略不可以出现重复", string.Format("策略编号:{0}", CurrCc.UnitCost)); CurrCc.Cost += CurrCc.UnitCost * CurrCc.ChipCount; CurrCc.UpdateTime = DateTime.Now; OldList.Add(CurrCc.GUID, CurrCc); if (!IsBackTest) { OldDbList.Add(CurrCc.ChanceIndex, CurrCc); } continue; } CurrCc.HoldTimeCnt = 1; CurrCc.Cost = CurrCc.ChipCount * CurrCc.UnitCost; CurrCc.Gained = 0; CurrCc.Profit = 0; CurrCc.ExecDate = DateTime.Today; CurrCc.CreateTime = DateTime.Now; CurrCc.UpdateTime = CurrCc.CreateTime; CurrCc.StragId = currStrag.GUID; CurrCc.ExpectCode = el.LastData.Expect; CurrCc.AllowMaxHoldTimeCnt = currPlan.AllowMaxHoldTimeCnt; CurrCc.ChanceType = currPlan.OutPutType; NewList.Add(CurrCc); } #endregion #region 未关闭的机会需要自我跟踪 foreach (string code in StragChances.Keys) { ChanceClass <T> CurrCc = StragChances[code]; //if (!CurrCc.Tracerable) continue; int cnt = OldList.Values.Where(p => p.ChanceCode.Equals(code)).Count(); if (cnt > 0) { continue; } if (currStrag is WolfInv.com.BaseObjectsLib.ISpecAmount)//先从策略级检查 { WolfInv.com.BaseObjectsLib.ISpecAmount specStrag = currStrag as WolfInv.com.BaseObjectsLib.ISpecAmount; if (specStrag != null)//如果没有方法,再从机会级检查 { CurrCc.HoldTimeCnt++; CurrCc.UnitCost = specStrag.getChipAmount(restAmt, CurrCc, amts); CurrCc.Cost += CurrCc.ChipCount * CurrCc.UnitCost; CurrCc.UpdateTime = DateTime.Now; OldList.Add(CurrCc.GUID, CurrCc); if (!IsBackTest) { OldDbList.Add(CurrCc.ChanceIndex, CurrCc); } continue; } } if (CurrCc.Tracerable)//再检查机会级 { CurrCc.HoldTimeCnt++; TraceChance <T> testCc = (TraceChance <T>)CurrCc; if (testCc == null) { continue; } CurrCc.UnitCost = testCc.getChipAmount <T>(restAmt, CurrCc, amts); CurrCc.Cost += CurrCc.ChipCount * CurrCc.UnitCost; CurrCc.UpdateTime = DateTime.Now; OldList.Add(CurrCc.GUID, CurrCc); if (!IsBackTest) { OldDbList.Add(CurrCc.ChanceIndex, CurrCc); } continue; } else { CurrCc.HoldTimeCnt++; WolfInv.com.BaseObjectsLib.ISpecAmount Strag = (WolfInv.com.BaseObjectsLib.ISpecAmount)currStrag; if (Strag == null) { continue; } CurrCc.UnitCost = Strag.getChipAmount(restAmt, CurrCc, amts); CurrCc.Cost = CurrCc.ChipCount * CurrCc.UnitCost; CurrCc.UpdateTime = DateTime.Now; OldList.Add(CurrCc.GUID, CurrCc); if (!IsBackTest) { OldDbList.Add(CurrCc.ChanceIndex, CurrCc); } } } #endregion } #endregion if (!IsBackTest)//额外保存 { //int savecnt = OldDbList.Save(null); DataReader dr = DataReaderBuild.CreateReader(GlobalClass.DataTypes.First().Key, null, null); //int savecnt = new PK10ExpectReader().SaveChances<T>(OldDbList.Values.ToList<ChanceClass<T>>(), null); int savecnt = dr.SaveChances <T>(OldDbList.Values.ToList <ChanceClass <T> >(), null); if (OldList.Count > 0) { Log("计算服务", "保存已有机会", string.Format("条数:{0};实际条数:{1}", OldList.Count, savecnt)); } savecnt = dr.SaveChances <T>(NewList, null); if (NewList.Count > 0) { Log("计算服务", "保存新增机会", string.Format("条数:{0};实际条数:{1}", NewList.Count, savecnt)); } } //合并到未关闭机会列表中 NewList.ForEach(p => AllNoClosedChances.Add(p.GUID, p)); OldList.Values.ToList <ChanceClass <T> >().ForEach(p => AllNoClosedChances.Add(p.GUID, p)); //就算是老记录未有guid,当ToTable时已经生成了guid ExChange(AllNoClosedChances.Values.ToList <ChanceClass <T> >(), el.LastData.Expect); //执行交易提供可视化 }
public void Run() { //LoopCnt = 0; testIndex = 0; ret = new BackTestReturnClass <T>(); long begNo = BegExpect; //ExpectReader er = new ExpectReader(); DataReader er = DataReaderBuild.CreateReader(dtp.DataType, "", null); ExpectList <T> el = null; long cnt = 0; ret.HoldCntDic = new Dictionary <int, int>(); ret.HoldWinCntDic = new Dictionary <int, int>(); ret.InChipsDic = new Dictionary <int, int>(); ret.WinChipsDic = new Dictionary <int, int>(); ExpectList <T> AllData = new ExpectList <T>(); testIndex = teststrag.ReviewExpectCnt - 1; ExpectList <T> testData = null; Dictionary <string, ChanceClass <T> > NoCloseChances = new Dictionary <string, ChanceClass <T> >(); Dictionary <string, ChanceClass <T> > tmpChances = new Dictionary <string, ChanceClass <T> >(); while (el == null || el.Count > 0) //如果取到的数据长度大于0 { el = er.ReadHistory <T>(begNo, LoopCnt); if (el == null) { ret.LoopCnt = (cnt + 1) * LoopCnt; ret.succ = false; ret.Msg = "读取历史数据错误!"; break; } if (el.Count == 0) { ret.LoopCnt = testIndex; ret.succ = true; ret.Msg = string.Format("成功遍历{0}条记录!共发现机会{1}次!其中,{2}.", testIndex, ret.ChanceList.Count, ret.HoldInfo); break; } AllData = ExpectList <T> .Concat(AllData, el); begNo = el.LastData.LExpectNo + 1; cnt++; //Todo: int pastCnt = 0; while (testIndex < AllData.Count) { ret.LoopCnt = pastCnt + testIndex; if (testData == null) { testData = AllData.getSubArray(0, teststrag.ReviewExpectCnt); } else { if (dtp.DataType == "PK10") { if (AllData[(int)testIndex].ExpectIndex != testData.LastData.ExpectIndex + 1) { throw new Exception(string.Format("{1}第{0}期后出现数据遗漏,请补充数据后继续测试!", testData.LastData.Expect, testData.LastData.OpenTime)); } } testData.RemoveAt(0); testData.Add(AllData[(int)testIndex]); } tmpChances = new Dictionary <string, ChanceClass <T> >(); foreach (string key in NoCloseChances.Keys) { ChanceClass <T> cc = NoCloseChances[key]; if (cc.Closed == false) { int matchcnt = 0; if (teststrag.GetRev) //如果求相反组合 { if (cc.Matched(testData.LastData, out matchcnt, true)) //不关闭 { if (cc.HoldTimeCnt < 0) { cc.HoldTimeCnt = (int)(testData.LastData.ExpectIndex - cc.InputExpect.ExpectIndex); } } } if (dtp.IsXxY == 1) { (cc as iXxYClass).AllNums = dtp.AllNums; (cc as iXxYClass).SelectNums = dtp.SelectNums; (cc as iXxYClass).strAllTypeBaseOdds = dtp.strAllTypeOdds; (cc as iXxYClass).strCombinTypeBaseOdds = dtp.strCombinTypeOdds; (cc as iXxYClass).strPermutTypeBaseOdds = dtp.strPermutTypeOdds; } bool Matched = cc.Matched(testData.LastData, out matchcnt, false); if (cc.NeedConditionEnd) { cc.MatchChips += matchcnt; if (Matched) { int LastMatchId = cc.LastMatchTimesId;//最后一次匹配次序号 int maxHoldCnt = cc.AllowMaxHoldTimeCnt; if (cc.HoldTimeCnt - cc.LastMatchTimesId > maxHoldCnt) { cc.AllowMaxHoldTimeCnt = cc.HoldTimeCnt - cc.LastMatchTimesId; } cc.LastMatchTimesId = cc.HoldTimeCnt; } if (teststrag is ITraceChance) { ITraceChance its = teststrag as ITraceChance; if (its == null) { cc.Closed = cc.OnCheckTheChance(cc, Matched); } else { cc.Closed = its.CheckNeedEndTheChance(cc, Matched); } } else { cc.Closed = cc.OnCheckTheChance(cc, Matched); } if (cc.Closed) { cc.EndExpectNo = testData.LastData.Expect; cc.UpdateTime = testData.LastData.OpenTime; } else { cc.HoldTimeCnt++; tmpChances.Add(key, cc); } } else { if (Matched || (!Matched && cc.HoldTimeCnt > 0 && cc.HoldTimeCnt == cc.AllowMaxHoldTimeCnt))//关闭 { cc.Closed = true; cc.EndExpectNo = testData.LastData.Expect; cc.MatchChips = matchcnt; if (!teststrag.GetRev)//只有不求相反值的情况下,才赋持有是次数 { if (dtp.DataType == "PK10") { cc.HoldTimeCnt = (int)(testData.LastData.ExpectIndex - cc.InputExpect.ExpectIndex); } } else { if (cc.HoldTimeCnt < 0) { cc.HoldTimeCnt = 999; } } cc.UpdateTime = testData.LastData.OpenTime; ret.ChanceList.Add(cc); } else { cc.HoldTimeCnt++; tmpChances.Add(key, cc); } } if (cc.Closed && cc.MatchChips > 0) { int HCnt = 1; if (ret.HoldCntDic.ContainsKey(cc.HoldTimeCnt)) { HCnt = ret.HoldCntDic[cc.HoldTimeCnt]; HCnt++; ret.HoldCntDic[cc.HoldTimeCnt] = HCnt; ret.HoldWinCntDic[cc.HoldTimeCnt] = ret.HoldWinCntDic[cc.HoldTimeCnt] + matchcnt; ret.InChipsDic[cc.HoldTimeCnt] = ret.InChipsDic[cc.HoldTimeCnt] + cc.ChipCount; ret.WinChipsDic[cc.HoldTimeCnt] = ret.WinChipsDic[cc.HoldTimeCnt] + cc.MatchChips; } else { ret.HoldCntDic.Add(cc.HoldTimeCnt, 1); ret.HoldWinCntDic.Add(cc.HoldTimeCnt, matchcnt); ret.InChipsDic.Add(cc.HoldTimeCnt, cc.ChipCount); ret.WinChipsDic.Add(cc.HoldTimeCnt, cc.MatchChips); } } } } BaseCollection <T> sc = new ExpectListProcessBuilder <T>(dtp, testData).getProcess().getSerialData(teststrag.ReviewExpectCnt, teststrag.BySer); if (testData.Count == 0) { break; } teststrag.SetLastUserData(testData); teststrag.setDataTypePoint(dtp); List <ChanceClass <T> > cs = teststrag.getChances(sc, testData.LastData);//获取所有机会 if (ret.ChanceList == null) { ret.ChanceList = new List <ChanceClass <T> >(); } //ret.ChanceList.AddRange(cs); NoCloseChances = new Dictionary <string, ChanceClass <T> >(); foreach (string key in tmpChances.Keys) { ChanceClass <T> cc = tmpChances[key]; cc.AllowMaxHoldTimeCnt = int.MaxValue; NoCloseChances.Add(key, cc); } for (int i = 0; i < cs.Count; i++) { //string key = string.Format("{0}_{1}", cs[i].SignExpectNo, cs[i].ChanceCode); string key = string.Format("{0}", cs[i].ChanceCode); if (NoCloseChances.ContainsKey(key)) { if (teststrag.AllowRepeat) { string test = key; //NoCloseChances.Add(key, cs[i]); } } else { cs[i].AllowMaxHoldTimeCnt = int.MaxValue; NoCloseChances.Add(key, cs[i]); } } testIndex++; } pastCnt += el.Count; } FinishedProcess(); //return ret; }
/// <summary> /// 新逻辑调用服务的计算类,注入策略运行计划清单和数据 /// </summary> /// <param name="es"></param> /// <param name="teststragplans"></param> /// <returns></returns> public BackTestReturnClass <T> VirExchange(ServiceSetting <T> sc, ref ExchangeService es, StragRunPlanClass <T>[] teststragplans) { //LoopCnt = 0; testIndex = 0; //调用计算服务进行计算 if (!teststragplans[0].AssetUnitInfo.Running) //如果资产单元没有启动,启动资产单元 { teststragplans[0].AssetUnitInfo.Run(false); } es = teststragplans[0].AssetUnitInfo.getCurrExchangeServer(); //设置资产单元的模拟交易器 CalcService <T> cs = new CalcService <T>(true, sc, teststragplans.ToDictionary(t => t.GUID, t => t)); cs.DataPoint = dtp; if (dtp.IsSecurityData == 1) { cs.ReadDataTableName = dtp.NewestTable; cs.Codes = null; } cs.IsTestBack = true; long begNo = BegExpect; //ExpectReader er = new ExpectReader(); DataReader er = DataReaderBuild.CreateReader(dtp.DataType, dtp.HistoryTable, dtp.RuntimeInfo.SecurityCodes); //支持所有数据 ExpectList <T> el = null; long cnt = 0; BackTestReturnClass <T> ret = new BackTestReturnClass <T>(); ret.HoldCntDic = new Dictionary <int, int>(); ret.HoldWinCntDic = new Dictionary <int, int>(); ret.InChipsDic = new Dictionary <int, int>(); ret.WinChipsDic = new Dictionary <int, int>(); ExpectList <T> AllData = new ExpectList <T>(); //long testIndex = teststrag.ReviewExpectCnt - 1; BaseStragClass <T>[] teststrags = teststragplans.Select(p => p.PlanStrag).ToArray <BaseStragClass <T> >(); testIndex = teststrags.Max <BaseStragClass <T> >(s => s.ReviewExpectCnt);//取所有策略中回览期最大的开始,之前的数据不看 long InitIndex = testIndex; ExpectList <T> testData = null; ////Dictionary<string, StragChance<T>> NoCloseChances = new Dictionary<string, StragChance<T>>(); ////Dictionary<string, StragChance<T>> tmpChances = new Dictionary<string, StragChance<T>>(); ////Dictionary<Int64, ExchangeChance> NewExchangeRecord = new Dictionary<Int64, ExchangeChance>(); int AllCnt = 0; while (el == null || el.Count > 0) //如果取到的数据长度大于0 { if (dtp.IsSecurityData == 1) { el = er.ReadHistory <T>(begNo, LoopCnt); } else { el = er.ReadHistory <T>(begNo, LoopCnt); } if (el == null) { ret.LoopCnt = cnt * LoopCnt; ret.succ = false; ret.Msg = "读取历史数据错误!"; break; } if (el.Count == 0) { ret.LoopCnt = testIndex; ret.succ = true; //ret.Msg = string.Format("成功遍历{0}条记录!共发现机会{1}次!其中,{2}.", testIndex, ret.ChanceList.Count, ret.HoldInfo); break; } AllData = ExpectList <T> .Concat(AllData, el); if (dtp.IsSecurityData == 0) { //begNo = el.LastData.LExpectNo + 1;//加一期 begNo = long.Parse(DataReader.getNextExpectNo(el.LastData.Expect, dtp)); } else { DateTime dt = new DateTime(el.LastData.LExpectNo); begNo = dt.AddDays(1).Ticks;//加一个周期,如果要回测其他周期,AddDays许更换为其他时间周期 } cnt++; //Todo: while (testIndex < AllData.Count) { int CurrExpectClose = 0; AllCnt++; es.UpdateExpectCnt(AllCnt); if (testData == null) { //testData = AllData.getSubArray(0, teststrag.ReviewExpectCnt); testData = AllData.getSubArray(0, (int)InitIndex + 1); } else { if (dtp.IsSecurityData == 0)//如果非证券,判断两个期号之间是否连续 { ////if (AllData[(int)testIndex].Expect != testData.LastData.ExpectIndex + 1) ////{ //// if (dtp.DataType == "PK10") //// { //// throw new Exception(string.Format("{1}第{0}期后出现数据遗漏,请补充数据后继续测试!", testData.LastData.Expect, testData.LastData.OpenTime)); //// } ////} } testData.RemoveAt(0); testData.Add(AllData[(int)testIndex]); } //只是取数据的逻辑一样,以后均调用CalcService //ToAdd:以下是内容 cs.CurrData = testData; cs.OnFinishedCalc += OnCalcFinished; cs.setGlobalClass(Program.gc); cs.Calc(); while (!cs.CalcFinished) { Thread.Sleep(1 * 100); } this.SystemStdDevs = cs.getSystemStdDevList(); //testIndex++; testIndex++; } } FinishedProcess(); return(ret); }
public Dictionary <string, ChanceClass <T> > CloseTheChances(bool IsTestBack, bool ForceCloseAllData = false) { List <ChanceClass <T> > cl = new List <ChanceClass <T> >(); DateTime currTime = DateTime.Now; Dictionary <string, ChanceClass <T> > CloseList = new Dictionary <string, ChanceClass <T> >(); if (IsTestBack)//如果回测,使用内存数据 { cl = Program.AllServiceConfig.AllNoClosedChanceList.Values.Select(a => a).ToList() as List <ChanceClass <T> >; } else//非回测,使用数据库数据ReadDataTableName { //DbChanceList<T> dcl = new PK10ExpectReader().getNoCloseChances<T>(null); DbChanceList <T> dcl = DataReaderBuild.CreateReader(DataPoint.DataType, ReadDataTableName, Codes).getNoCloseChances <T>(null); //必须强制按数据库中存储的策略id,获取到策略的机会类型 foreach (var dc in dcl.Values) { if (!Program.AllServiceConfig.AllStrags.ContainsKey(dc.StragId))//策略未找到数据库中存储的机会所产生的策略 { continue; } if (DataPoint.DataType == "PK10") { cl.Add(dc); } else { BaseStragClass <TimeSerialData> sc = Program.AllServiceConfig.AllStrags[dc.StragId]; Type ct = sc.getTheChanceType(); object tmp = Activator.CreateInstance(ct); if (DataPoint.IsXxY == 1) { (tmp as iXxYClass).AllNums = DataPoint.AllNums; (tmp as iXxYClass).SelectNums = DataPoint.SelectNums; (tmp as iXxYClass).strAllTypeBaseOdds = DataPoint.strAllTypeOdds; (tmp as iXxYClass).strCombinTypeBaseOdds = DataPoint.strCombinTypeOdds; (tmp as iXxYClass).strPermutTypeBaseOdds = DataPoint.strPermutTypeOdds; } Log("转换前机会类型", string.Format("{0}", tmp.GetType())); dc.FillTo(ref tmp, true); //获取所有属性 ChanceClass <T> cc = tmp as ChanceClass <T>; Log("转换后机会类型", string.Format("{0}:{1}:{2}", cc.GetType(), cc.StragId, cc.ChanceCode)); // cc.ToDetailString())); cl.Add(cc); } //cl = dcl.Values.ToList(); } } Dictionary <string, ChanceClass <T> > rl = new Dictionary <string, ChanceClass <T> >(); if (cl.Count > 0) { Log("未关闭机会列表数量为", string.Format("{0}", cl.Count)); } //2019/4/22日出现错过732497,732496两期记录错过,但是732498却收到的情况,同时,正好在732498多次重复策略正好开出结束,因错过2期导致一直未归零, //一直长时间追号开出近60期 //为避免出现这种情况 //判断是否错过了期数,如果错过期数,将所有追踪策略归零,不再追号,也不再执行选号程序, //是否要连续停几期?执行完后,在接收策略里面发现前10期有不连续的情况,直接跳过,只接收数据不执行选号。 this.CurrData.UseType = this.DataPoint; if (this.CurrData.MissExpectCount() > 1) { if (!IsTestBack) //如果非回测,保存交易记录 { DbChanceList <T> dbsavelist = new DbChanceList <T>(); cl.ForEach(p => dbsavelist.Add(p.ChanceIndex, p)); CloseChanceInDBAndExchangeService(dbsavelist, true);//强制关闭,就算命中也不算其盈利 } return(rl); } for (int i = 0; i < cl.Count; i++) { string sGUId = cl[i].StragId; if (sGUId == null || !Program.AllServiceConfig.AllStrags.ContainsKey(sGUId)) //如果策略已注销,立即关闭机会 { if (cl[i].Tracerable) //如果是自我跟踪机会,不理会,让它自己去跟踪 { } else { CloseList.Add(cl[i].GUID, cl[i]); //cl.Remove(cl[i].ChanceIndex); Log("强制结束机会", string.Format("该机会所属策略已经注销,并且该机会是非跟踪机会!{0}", cl[i].ChanceCode)); continue; } } List <string> AllUsePans = Program.AllServiceConfig.AllRunningPlanGrps.SelectMany(a => a.Value.UseSPlans.Select(t => t.PlanStrag.GUID)).ToList <string>(); if (!AllUsePans.Contains(sGUId))//不在执行的计划内 { if (cl[i].Tracerable) { } else { CloseList.Add(cl[i].GUID, cl[i]); Log("强制结束机会", string.Format("不存在绑定该机会所属策略的计划,并且该机会是非跟踪机会!{0}", cl[i].ChanceCode)); continue; } } //如果策略已经超出时间 List <string> StopedPlans = Program.AllServiceConfig.AllRunningPlanGrps.SelectMany(a => a.Value.UseSPlans.Where(t => (InitServerClass.JudgeInRunTime(currTime, t) == false))).Select(a => a.GUID).ToList <string>(); if (!IsTestBack) { if (StopedPlans.Contains(sGUId))//停止的计划产生的机会 { if (cl[i].Tracerable) { } else { Log("强制结束机会", string.Format("该机会所属策略超出计划运行时间!{0}", cl[i].ChanceCode)); CloseList.Add(cl[i].GUID, cl[i]); continue; } } } StopedPlans = Program.AllServiceConfig.AllRunningPlanGrps.SelectMany(a => a.Value.UseSPlans.Where(t => (t.Running == false))).Select(a => a.GUID).ToList <string>(); if (StopedPlans.Contains(sGUId))//停止的计划产生的机会 { if (cl[i].Tracerable) { } else { Log("强制结束机会", string.Format("该机会所属策略的计划状态为停止!{0}", cl[i].ChanceCode)); CloseList.Add(cl[i].GUID, cl[i]); continue; } } //如果策略已经停止 //获得策略 BaseStragClass <T> sc = Program.AllServiceConfig.AllStrags[sGUId] as BaseStragClass <T>; int mcnt = 0; bool Matched = cl[i].Matched(CurrData, out mcnt); cl[i].MatchChips += mcnt; if (sc is ITraceChance)//优先关闭程序跟踪 { cl[i].Closed = (sc as ITraceChance).CheckNeedEndTheChance(cl[i], Matched); } else { cl[i].Closed = Matched; } if (cl[i].Tracerable && Matched)//如果是策略自我跟踪,无论其策略是否是跟踪策略,先关了。 { cl[i].Closed = true; } //////if (cl[i].MaxHoldTimeCnt > 0 && cl[i].HoldTimeCnt == cl[i].MaxHoldTimeCnt) //////{ ////// cl[i].Closed = true; //////} if (cl[i].Closed)//如果已经关闭 { CloseList.Add(cl[i].GUID, cl[i]); continue; } rl.Add(cl[i].GUID, cl[i]); } //Log("结束机会", "所有非法,以及命中并确认需要结束的机会"); if (!IsTestBack) //如果非回测,保存交易记录 { DbChanceList <T> dbsavelist = new DbChanceList <T>(); CloseList.Values.ToList <ChanceClass <T> >().ForEach(p => { if (p != null) { dbsavelist.Add(p.ChanceIndex, p); } }); CloseChanceInDBAndExchangeService(dbsavelist); } return(rl); }
private void tsmi_getHistoryData_Click(object sender, EventArgs e) { string endPage = Interaction.InputBox("请输入结束页编号", "结束页编辑框", "", 100, 100).Trim(); string[] pages = endPage.Split('-'); int begi = int.Parse(pages[0].Trim()); int endi = int.Parse(pages[1].Trim()); HtmlDataClass rder = HtmlDataClass.CreateInstance(GlobalClass.TypeDataPoints.First().Value); CommExpectReader er = DataReaderBuild.CreateReader(GlobalClass.TypeDataPoints.First().Key, null, null) as CommExpectReader; Application.DoEvents(); ExpectList <TimeSerialData> tmpList = new ExpectList <TimeSerialData>(); for (int i = begi; i <= endi; i++) { ExpectList <TimeSerialData> wlist = new ExpectList <TimeSerialData>(); wlist = rder.getHistoryData <TimeSerialData>(null, i); //取到web ExpectList <TimeSerialData> wtrue = new ExpectList <TimeSerialData>(); wtrue = er.getNewestData(wlist, tmpList); // tmpList = ExpectList <TimeSerialData> .Concat(tmpList, wtrue); this.tssl_Count.Text = string.Format("访问第{1}页,共计获取到{0}条记录", tmpList.Count, i); if (tmpList.Count >= 100) { ExpectList <TimeSerialData> currEl = er.ReadHistory <TimeSerialData>(tmpList.MinExpect, 10000); ExpectList <TimeSerialData> NewEl = er.getNewestData(tmpList, currEl); long res1 = er.SaveHistoryData(NewEl); tmpList = new ExpectList <TimeSerialData>(); this.tssl_Count.Text = string.Format("访问第{1}页,共计成功保存了{0}条记录", res1, i); } Application.DoEvents(); Thread.Sleep(10000); } ExpectList <TimeSerialData> currEl1 = er.ReadHistory <TimeSerialData>(tmpList.MinExpect, 10000); ExpectList <TimeSerialData> NewEl1 = er.getNewestData(tmpList, currEl1); long res = er.SaveHistoryData(NewEl1); if (res > 0) { MessageBox.Show(string.Format("成功获取到{0}条历史记录!", res)); } else { MessageBox.Show(string.Format("保存{0}条历史记录失败!", NewEl1.Count)); } ////string StrBegDate = "2018-08-25"; ////ExpectList<TimeSerialData> el = er.GetMissedData<TimeSerialData>(true, StrBegDate); ////for (int i = 0; i < el.Count; i++) ////{ //// ExpectList<TimeSerialData> tmpList = new ExpectList<TimeSerialData>(); //// DateTime endT = el[i].OpenTime; //// DateTime begT = el[i].OpenTime.AddMinutes(-1 * el[i].MissedCnt - 1); //// DateTime tt = DateTime.Parse(begT.ToShortDateString()); //// DateTime begT0 = tt; //// while (tt <= endT) //// { //// string strTt = tt.ToString("yyyy-MM-dd"); //// for (int j = 1; j <= 29; j++) //// { //// ExpectList<TimeSerialData> wlist = rder .getHistoryData<TimeSerialData>(strTt, j);//取到web //// tmpList = ExpectList<TimeSerialData>.Concat(tmpList, wlist); //// Application.DoEvents(); //// Thread.Sleep(800); //// } //// tt = tt.AddDays(1); //// } //// ExpectList<TimeSerialData> currEl = er.ReadHistory<TimeSerialData>(begT0.ToString(), endT.AddDays(1).ToString()); //// er.SaveHistoryData(er.getNewestData(tmpList, currEl)); ////} }
/* * private void ReceivePK10CData() * { * DataTypePoint dtp = GlobalClass.TypeDataPoints["PK10"]; * Log("接收数据", "准备接收数据"); * DateTime CurrTime = DateTime.Now; * long RepeatMinutes = GlobalClass.TypeDataPoints["PK10"].ReceiveSeconds / 60; * long RepeatSeconds = GlobalClass.TypeDataPoints["PK10"].ReceiveSeconds; * PK10_HtmlDataClass hdc = new PK10_HtmlDataClass(GlobalClass.TypeDataPoints["PK10"]); * ExpectList<T> tmp = hdc.getExpectList<T>(); * if (tmp == null || tmp.Count == 0) * this.Tm_ForPK10.Interval = RepeatSeconds / 20 * 1000; * Log("尝试接收数据", "未接收到数据,数据源错误!",true); * { * return; * } * ExpectList el = new ExpectList(tmp.Table); * ////if(el != null && el.Count>0) * ////{ * //// Log("接收到的最新数据",el.LastData.ToString()); * ////} * if (el == null || el.Count == 0) * { * this.Tm_ForPK10.Interval = RepeatSeconds / 20 * 1000; * Log("尝试接收数据", "未接收到数据,转换数据源错误!",true); * return; * } * * DateTime StartTime = CurrTime.Date.Add(GlobalClass.TypeDataPoints["PK10"].ReceiveStartTime.TimeOfDay); * //Log("当日开始时间", StartTime.ToLongTimeString()); * int PassCnt = (int)Math.Floor(CurrTime.Subtract(StartTime).TotalMinutes / RepeatMinutes); * //Log("经历过的周期", PassCnt.ToString()); * DateTime PassedTime = StartTime.AddMinutes(PassCnt * RepeatMinutes);//正常的上期时间 * //Log("前期时间", PassedTime.ToLongTimeString()); * DateTime FeatureTime = StartTime.AddMinutes((PassCnt + 1) * RepeatMinutes);//正常的下期时间 * //Log("后期时间", FeatureTime.ToLongTimeString()); * DateTime NormalRecievedTime = StartTime.AddSeconds((PassCnt + 1.4) * RepeatSeconds);//正常的接收到时间 * //Log("当期正常接收时间", FeatureTime.ToLongTimeString()); * try * { * PK10ExpectReader rd = new PK10ExpectReader(); * //ExpectList currEl = rd.ReadNewestData(DateTime.Today.AddDays(-1*glb.CheckNewestDataDays));//改为10天,防止春节连续多天不更新数据 * ExpectList<T> currEl = rd.ReadNewestData<T>(DateTime.Today.AddDays(-1 * GlobalClass.TypeDataPoints["PK10"].CheckNewestDataDays)); ;//改从PK10配置中获取 * if ((currEl == null || currEl.Count == 0) || (el.Count > 0 && currEl.Count > 0 && el.LastData.ExpectIndex > currEl.LastData.ExpectIndex))//获取到新数据 * { * Log("接收到数据", string.Format("接收到数据!{0}", el.LastData.OpenCode),true); * //Program.AllServiceConfig.wxlog.Log("接收到数据", string.Format("接收到数据!{0}", el.LastData.ToString())); * PK10_LastSignTime = CurrTime; * long CurrMin = DateTime.Now.Minute % RepeatMinutes; * int CurrSec = DateTime.Now.Second; * //this.Tm_ForPK10.Interval = (CurrMin % RepeatMinutes < 2 ? 2 : 7 - CurrMin) * 60000 - (CurrSec + RepeatMinutes) * 1000;//5分钟以后见,减掉5秒不断收敛时间,防止延迟接收 * this.Tm_ForPK10.Interval = FeatureTime.Subtract(CurrTime).TotalMilliseconds; * if (rd.SaveNewestData(rd.getNewestData<T>(new ExpectList<T>(el.Table), currEl)) > 0) * { * CurrDataList = rd.ReadNewestData<T>(DateTime.Now.AddDays(-1* GlobalClass.TypeDataPoints["PK10"].CheckNewestDataDays));//前十天的数据 尽量的大于reviewcnt,免得需要再取一次数据 * if(CurrDataList == null) * { * this.Tm_ForPK10.Interval = RepeatSeconds / 20 * 1000; * Log("计算最新数据错误", "无法获取最新数据发生错误,请检查数据库是否正常!", true); * return; * } * CurrExpectNo = el.LastData.Expect; * Program.AllServiceConfig.LastDataSector = new ExpectList<TimeSerialData>(CurrDataList.Table) ; * //2019/4/22日出现错过732497,732496两期记录错过,但是732498却收到的情况,同时,正好在732498多次重复策略正好开出结束,因错过2期导致一直未归零, * //一直长时间追号开出近60期 * //为避免出现这种情况 * //判断是否错过了期数,如果错过期数,将所有追踪策略归零,不再追号,也不再执行选号程序, * //是否要连续停几期?执行完后,在接收策略里面发现前10期有不连续的情况,直接跳过,只接收数据不执行选号。 * CurrDataList.UseType = GlobalClass.TypeDataPoints["PK10"]; * if (CurrDataList.MissExpectCount() > 1 || MissExpectEventPassCnt > 0)//如果出现错期 * { * Log("接收到错期数据", string.Format("接收到数据!{0}", el.LastData.ToString()), true); * if (MissExpectEventPassCnt <= MaxMissEventCnt)//超过最大平稳期,置零,下次再计算 * { * MissExpectEventPassCnt = 0; * } * else //继续跳过 * { * MissExpectEventPassCnt++; * } * } * else//第一次及平稳期后进行计算 * { * CalcProcess.DataPoint = dtp; * CalcProcess.ReadDataTableName = null;//为证券计算用 * CalcProcess.Codes = null;//为支持证券计算用 * bool res = AfterReceiveProcess(CalcProcess); * if (res == false) * this.Tm_ForPK10.Interval = RepeatSeconds / 20 * 1000; * CurrDataList.UseType = dtp; * if (CurrDataList.MissExpectCount() > 1)//执行完计算(关闭所有记录)后再标记为已错期 * { * MissExpectEventPassCnt = 1; * } * } * } * else * { * this.Tm_ForPK10.Interval = RepeatSeconds / 20 * 1000; * Log("保存数据错误", "保存数据数量为0!",true); * } * } * else * { * Log("接收到非最新数据",string.Format("id:{0}",el.LastData.Expect),false); * if (CurrTime.Hour < 9)//如果在9点前 * { * //下一个时间点是9:07 //9:30 * DateTime TargetTime = DateTime.Today.AddHours(9).AddMinutes(30); * this.Tm_ForPK10.Interval = TargetTime.Subtract(CurrTime).TotalMilliseconds; * } * else * { * Log("接收数据", "未接收到新数据!"); * //if (NormalRecievedTime > CurrTime) * //{ * // this.Tm_ForPK10.Interval = NormalRecievedTime.AddMinutes(1).Subtract(CurrTime).TotalMilliseconds; * //} * //else * //{ * //this.Tm_ForPK10.Interval = RepeatSeconds / 20 * 1000; * if (CurrTime.Subtract(PK10_LastSignTime).TotalMinutes > RepeatMinutes + RepeatMinutes * 2 / 5)//如果离上期时间超过2/5个周期,说明数据未接收到,那不要再频繁以10秒访问服务器 * { * this.Tm_ForPK10.Interval = RepeatSeconds / 20 * 1000; * } * else //一般未接收到,10秒以后再试,改为50分之一个周期再试 * { * this.Tm_ForPK10.Interval = RepeatSeconds / 20 * 1000; * } * //} * } * } * } * catch (Exception e) * { * Log(e.Message,e.StackTrace,true); * } * //Log("接收数据", string.Format("当前访问时间为:{0},{1}秒后继续访问!",CurrTime.ToString(),this.Tm_ForPK10.Interval/1000),false); * //FillOrgData(listView_TXFFCData, currEl); * } * * private void ReceiveTXFFCData() * { * * int secCnt = DateTime.Now.Second; * TXFFC_HtmlDataClass hdc = new TXFFC_HtmlDataClass(GlobalClass.TypeDataPoints["TXFFC"]); * ExpectList<T> tmp = hdc.getExpectList<T>(); * if (tmp == null || tmp.Count == 0) * { * Tm_ForTXFFC.Interval = 5 * 1000; * return; * } * ExpectList el = new ExpectList(tmp.Table); * if (el == null || el.LastData == null) * { * Tm_ForTXFFC.Interval = 5 * 1000; * return; * } * if (Int64.Parse(el.LastData.Expect) > lastFFCNo) * { * lastFFCNo = Int64.Parse(el.LastData.Expect); * if (secCnt > 10) * { * Tm_ForTXFFC.Interval = (7 + 60 - secCnt) * 1000; * } * else if (secCnt < 7) * { * Tm_ForTXFFC.Interval = (7 - secCnt) * 1000; * } * else * { * Tm_ForTXFFC.Interval = 60 * 1000; * } * } * else * { * Tm_ForTXFFC.Interval = 5 * 1000; * return; * } * //Log("保存分分彩数据", string.Format("期号:{0}",lastFFCNo)); * TXFFCExpectReader rd = new TXFFCExpectReader(); * ExpectList<T> currEl = rd.ReadNewestData<T>(DateTime.Now.AddDays(-1)); * ExpectList<T> SaveData = rd.getNewestData<T>(new ExpectList<T>(el.Table), currEl); * if (SaveData.Count > 0) * { * //Log("Save count!", SaveData.Count.ToString()); * rd.SaveNewestData(SaveData); * } * currEl = rd.ReadNewestData<T>(DateTime.Now.AddDays(-1)); * //FillOrgData(listView_TXFFCData, currEl); * } */ private void ReceiveData(string DataType, Timer useTimer, string strReadTableName, string[] codes, bool NeedCalc = false) { DataReader rd = DataReaderBuild.CreateReader(DataType, strReadTableName, codes); lock (rd) { HtmlDataClass hdc = null; DataTypePoint dtp = GlobalClass.TypeDataPoints[DataType]; Log("接收数据", "准备接收数据"); int DiffHours = 0; int DiffMinutes = 0; if (dtp.DiffHours != 0) { DiffHours = dtp.DiffHours; DiffMinutes = dtp.DiffMinutes; } DateTime CurrTime = DateTime.Now.AddHours(DiffHours).AddMinutes(DiffMinutes); long RepeatMinutes = dtp.ReceiveSeconds / 60; long RepeatSeconds = dtp.ReceiveSeconds; hdc = HtmlDataClass.CreateInstance(dtp); ExpectList <T> tmp = hdc.getExpectList <T>(); if (tmp == null || tmp.Count == 0) { useTimer.Interval = RepeatSeconds / 20 * 1000; Log("尝试接收数据", "未接收到数据,数据源错误!", glb.ExceptNoticeFlag); return; } ExpectList el = new ExpectList(tmp.Table); ////if(el != null && el.Count>0) ////{ //// Log("接收到的最新数据",el.LastData.ToString()); ////} if (el == null || el.Count == 0) { useTimer.Interval = RepeatSeconds / 20 * 1000; Log("尝试接收数据", "未接收到数据,转换数据源错误!", glb.ExceptNoticeFlag); return; } DateTime StartTime = CurrTime.Date.Add(dtp.ReceiveStartTime.TimeOfDay); //Log("当日开始时间", StartTime.ToLongTimeString()); int PassCnt = (int)Math.Floor(CurrTime.Subtract(StartTime).TotalMinutes / RepeatMinutes); //Log("经历过的周期", PassCnt.ToString()); DateTime PassedTime = StartTime.AddMinutes(PassCnt * RepeatMinutes); //正常的上期时间 //Log("前期时间", PassedTime.ToLongTimeString()); DateTime FeatureTime = StartTime.AddMinutes((PassCnt + 1) * RepeatMinutes); //正常的下期时间 //Log("后期时间", FeatureTime.ToLongTimeString()); DateTime NormalRecievedTime = StartTime.AddSeconds((PassCnt + 1.4) * RepeatSeconds); //正常的接收到时间 //Log("当期正常接收时间", FeatureTime.ToLongTimeString()); try { //PK10ExpectReader rd = new PK10ExpectReader(); //ExpectList currEl = rd.ReadNewestData(DateTime.Today.AddDays(-1*glb.CheckNewestDataDays));//改为10天,防止春节连续多天不更新数据 //ExpectList<T> currEl = rd.ReadNewestData<T>(DateTime.Today.AddDays(-1 * dtp.CheckNewestDataDays)); ;//改从PK10配置中获取 //Log("接收第一期数据", el.FirstData.Expect, true); //ExpectList<T> currEl = rd.ReadNewestData<T>(dtp.NewRecCount); ExpectList <T> currEl = rd.ReadNewestData <T>(DateTime.Now.AddDays(-1 * dtp.CheckNewestDataDays)); //前十天的数据 //2020.4.8 尽量的大于reviewcnt, 免得需要再取一次数据, 尽量多取,以防后面策略调用需要上万条数据,还要防止放假中间间隔时间较长 ExpectList <T> NewList = rd.getNewestData <T>(new ExpectList <T>(el.Table), currEl); //新列表是最新的数据在前的,后面使用时要反序用 //if ((currEl == null || currEl.Count == 0) || (el.Count > 0 && currEl.Count > 0 && el.LastData.ExpectIndex > currEl.LastData.ExpectIndex))//获取到新数据 if (NewList.Count > 0) { string lastExpect = currEl?.LastData?.Expect; string newestExpect = el.LastData.Expect; int interExpect = 1;//间隔数量 if (lastExpect != null) { interExpect = (int)DataReader.getInterExpectCnt(lastExpect, newestExpect, dtp); } if (currEl.Count > 0) { Log(string.Format("接收到{0}数据", DataType), string.Format("接收到数据!新数据:[{0},{1}],老数据:[{2},{3}]", el.LastData.Expect, el.LastData.OpenCode, currEl.LastData.Expect, currEl.LastData.OpenCode), glb.NormalNoticeFlag); } //Program.AllServiceConfig.wxlog.Log("接收到数据", string.Format("接收到数据!{0}", el.LastData.ToString())); PK10_LastSignTime = CurrTime; long CurrMin = DateTime.Now.Minute % RepeatMinutes; int CurrSec = DateTime.Now.Second; //useTimer.Interval = (CurrMin % RepeatMinutes < 2 ? 2 : 7 - CurrMin) * 60000 - (CurrSec + RepeatMinutes) * 1000;//5分钟以后见,减掉5秒不断收敛时间,防止延迟接收 useTimer.Interval = FeatureTime.Subtract(CurrTime).TotalMilliseconds; //ExpectList<T> NewList = rd.getNewestData<T>(new ExpectList<T>(el.Table), currEl); string[] expects = NewList.DataList.Select(a => a.Expect).ToArray(); //Log("存在数据",string.Format("共{0}期:[{1}]", currEl.Count,string.Join(",", currEl.DataList.Select(a=>a.Expect).ToArray())),true); if (NewList.Count == 0) { Log("待保存数据数量为0", "无须保存!", glb.ExceptNoticeFlag); useTimer.Interval = RepeatSeconds * 1000; return; } int savecnt = rd.SaveNewestData(NewList); if (savecnt > 0) { Log("保存数据条数", string.Format("{0}条数!", savecnt), glb.NormalNoticeFlag); ////CurrDataList = rd.ReadNewestData<T>(DateTime.Now.AddDays(-1 * dtp.CheckNewestDataDays));//前十天的数据 尽量的大于reviewcnt,免得需要再取一次数据,尽量多取,以防后面策略调用需要上万条数据,还要防止放假中间间隔时间较长 ////if (CurrDataList == null) //只是测试,要不要? ////{ //// useTimer.Interval = RepeatSeconds / 20 * 1000; //// Log("计算最新数据错误", "无法获取最新数据发生错误,请检查数据库是否正常!", glb.ExceptNoticeFlag); //// return; ////} CurrExpectNo = el.LastData.Expect; //Program.AllServiceConfig.LastDataSector = new ExpectList<TimeSerialData>(CurrDataList.Table); //2019/4/22日出现错过732497,732496两期记录错过,但是732498却收到的情况,同时,正好在732498多次重复策略正好开出结束,因错过2期导致一直未归零, //一直长时间追号开出近60期 //为避免出现这种情况 //判断是否错过了期数,如果错过期数,将所有追踪策略归零,不再追号,也不再执行选号程序, //是否要连续停几期?执行完后,在接收策略里面发现前10期有不连续的情况,直接跳过,只接收数据不执行选号。 //CurrDataList.UseType = dtp; if (interExpect - NewList.Count > 0 || MissExpectEventPassCnt > 0) //错期特征,当前期和上期的差大于新收到数据条数,表示老数据和新数据中有缺失数据,这样的特征出现后连续10期不计算,等稳定后再说,错期后如果中间期补进来,在10期内标志仍然是真,不需要特别对其处理。 { if (interExpect > 1) //如果是发生错期 { Log(string.Format("{1}接收到错期数据,其中缺失理论数据条数为{2}条,此后{0}期将不计算,期间该彩种所有信号均无效,之后自动恢复!", MaxMissEventCnt, dtp.DataType, interExpect - NewList.Count), string.Format("接收到数据!{0}", el.LastData.ToString()), true); } if (interExpect <= 0) { Log(string.Format("{0}接收到后补的错期数据!", dtp.DataType), string.Format("接收到数据!{0}", el.LastData.ToString()), true); } if (MissExpectEventPassCnt <= MaxMissEventCnt)//超过最大平稳期,置零,下次再计算 { MissExpectEventPassCnt = 0; } else //继续跳过 { MissExpectEventPassCnt++; } } else//第一次及平稳期后进行计算 { if (interExpect < 0) //补充进来的错期数据 { Log(string.Format("经过{0}期最大平稳期后接收到补充进来的错期数据,如果是关键期,仍然对平稳期后的信号有影响,请及时检查!", MaxMissEventCnt), string.Format("接收到数据!{0}", el.LastData.ToString()), true);//只保存数据,不做处理 return; } bool res = false; if (NeedCalc) { CurrData = currEl; //开始的记录以老记录为基础 //2020.4.8 为保证择时处理准确,增加对新增基础数据进行分解计算,务必保证每一条合法的记录都经过计算。错期的不在此范围内,因为本来就是错的,计算也是错误 for (int i = NewList.Count - 1; i >= 0; i--)//新序列是反序,要反着用 { CurrData.Add(NewList[i]); if (NewList.Count > 1) { Log("一次接收到多期数据", string.Format("最后记录{3};当前执行!{0};{1};{2}", NewList[i].Expect, NewList[i].OpenCode, NewList[i].OpenTime, CurrData.LastData.Expect), true);//只保存数据,不做处理 } CurrData.UseType = dtp; //Program.AllServiceConfig.LastDataSector = new ExpectList<TimeSerialData>(CurrDataList.Table); if (CalcProcess == null) { CalcProcess = new CalcService <T>(); } CalcProcess.DataPoint = dtp; CalcProcess.ReadDataTableName = strReadTableName; CalcProcess.Codes = codes; res = AfterReceiveProcess(CalcProcess); if (res == false) { useTimer.Interval = RepeatSeconds / 20 * 1000; } else { Program.AllServiceConfig.haveReceiveData = true;//每次成功接收后都将已接收到数据标志置为true,当外部调用访问后将该标志置回为false } /*if (CurrData.MissExpectCount() > 1)//执行完计算(关闭所有记录)后再标记为已错期 * { * MissExpectEventPassCnt = 1; * }*/ } } } } else//保存失败 { Log("待保存数据!", string.Format("总共{0}期数据:[{1}]", NewList.Count, string.Join(";", expects)), glb.ExceptNoticeFlag); useTimer.Interval = RepeatSeconds / (savecnt == 0 ? 1 : 20) * 1000;//如果为0,只是没保存,不管它,只是提示,如果保存为负,继续获取。 //Log("保存数据错误", string.Format("保存数据数量为{0},间隔时间为{1}秒!", savecnt, useTimer.Interval), glb.ExceptNoticeFlag); } } else { //Log("接收到非最新数据", string.Format("id:{0}", el.LastData.Expect), false); if (CurrTime.Hour < StartTime.Hour)//如果在9点前 { //下一个时间点是9:07 //9:30 DateTime TargetTime = DateTime.Today.AddHours(StartTime.Hour).AddMinutes(StartTime.Minute); useTimer.Interval = TargetTime.Subtract(CurrTime).TotalMilliseconds; DateTime realTime = DateTime.Now.Add(TargetTime.Subtract(CurrTime)); Log("休息时间,下一个大周期时间", realTime.ToString()); } else { Log(string.Format("接收到{0}数据", DataType), string.Format("未接收到数据!{0}", CurrTime.ToString())); //if (NormalRecievedTime > CurrTime) //{ // useTimer.Interval = NormalRecievedTime.AddMinutes(1).Subtract(CurrTime).TotalMilliseconds; //} //else //{ //useTimer.Interval = RepeatSeconds / 20 * 1000; if (CurrTime.Subtract(PK10_LastSignTime).TotalMinutes > RepeatMinutes + RepeatMinutes * 2 / 5)//如果离上期时间超过2/5个周期,说明数据未接收到,那不要再频繁以10秒访问服务器 { useTimer.Interval = RepeatSeconds / 5 * 1000; } else //一般未接收到,10秒以后再试,改为50分之一个周期再试 { useTimer.Interval = RepeatSeconds / 20 * 1000; } //} } } } catch (Exception e) { Log(e.Message, e.StackTrace, true); } //Log("接收数据", string.Format("当前访问时间为:{0},{1}秒后继续访问!",CurrTime.ToString(),useTimer.Interval/1000),false); //FillOrgData(listView_TXFFCData, currEl); } }