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 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); }