public override void exec() { log.Info("**********START**********"); var cache = new Dictionary <string, kdata>(); var db = new Db.db(); var kdatadb = new kdatadb(); var sectors = db.sectors(); var i = 0; var count = sectors.Count(); foreach (var sector in sectors) { Interlocked.Increment(ref i); log.InfoFormat("{0}/{1} calc sector {2}", i, count, sector); var codes = db.codes(sector); if (!codes.Any()) { log.WarnFormat("empty data set for sector {0}", sector); continue; } new kdatadb().save(sum(sector, kdata(db, cache, codes, "5")), "5"); kdatadb.save(sum(sector, kdata(db, cache, codes, "15")), "15"); kdatadb.save(sum(sector, kdata(db, cache, codes, "30")), "30"); kdatadb.save(sum(sector, kdata(db, cache, codes, "60")), "60"); kdatadb.save(sum(sector, kdata(db, cache, codes, "D")), "D"); kdatadb.save(sum(sector, kdata(db, cache, codes, "W")), "W"); kdatadb.save(sum(sector, kdata(db, cache, codes, "M")), "M"); } log.Info("**********DONE**********"); }
IEnumerable <kdata> kdata(Db.db db, Dictionary <string, kdata> cache, IEnumerable <string> codes, string ktype) { var list = new List <kdata>(); var notincache = new List <string>(); foreach (var code in codes) { var key = code + ktype; if (cache.ContainsKey(key)) { list.Add(cache[key]); } else { notincache.Add(code); } } var data = new kdatadb().kdata(notincache, ktype); foreach (var d in data) { var key = d.Code + ktype; cache[key] = d; } return(list.Concat(data).ToArray()); }
public static KeyPrice[] keyprice(string code, string ktype) { var d = new kdatadb().kdata(code, ktype); var peak_h = new PEAK(d, PEAK_TYPE.high); var peak_l = new PEAK(d, PEAK_TYPE.low); //var peak_h_volume = new PEAK(d, k => k.volume, PEAK_TYPE.high); //var peak_l_volume = new PEAK(d, k => k.volume, PEAK_TYPE.low); var keyprices = d.Select(p => { var h = peak_h[p.date]; var l = peak_l[p.date]; //var h_volume = peak_h_volume[p.date]; //var l_volume = peak_l_volume[p.date]; //if (h > 0 && h_volume > 0) return KeyPrice.high(code, p.date, h, true); //else if (l > 0 && l_volume > 0) return KeyPrice.low(code, p.date, l, true); if (h > 0) { return(KeyPrice.high(code, p.date, h, true)); } else if (l > 0) { return(KeyPrice.low(code, p.date, l, true)); } return(null); }) .Where(p => p != null) .ToArray(); return(keyprices); }
public chart Get(string id, string ktype) { var kdata = new kdatadb().kdata(id, ktype); var basic = new Trade.Db.db().basics(id); var since = Trade.Cfg.Configuration.data.bearcrossbull; var k = kdata.Where(p => p.date >= since).ToArray(); var macd = new MACD(kdata.close()).Where(p => p.Date >= since).ToArray(); var macdvol = new MACD(kdata.volume(100)).Where(p => p.Date >= since).ToArray(); var ma5 = new MA(kdata.close(), 5).Range(since); var ma30 = new MA(kdata.close(), 30).Range(since); var ma60 = new MA(kdata.close(), 60).Range(since); var ma120 = new MA(kdata.close(), 120).Range(since); var chg = new CHG(kdata.close()).Range(since); var bottom = new BOTTOM(kdata).Range(since); return(new chart { data = k.Select(p => new object[] { p.date, p.open, p.high, p.low, p.close, chg[p.date] }).ToArray(), volume = k.Select(p => new object[] { p.date, p.volume / 100 }).ToArray(), macd = macd.Select(p => new object[] { p.Date, p.MACD }).ToArray(), dif = macd.Select(p => new object[] { p.Date, p.DIF }).ToArray(), dea = macd.Select(p => new object[] { p.Date, p.DEA }).ToArray(), macdvol = macdvol.Select(p => new object[] { p.Date, p.MACD }).ToArray(), difvol = macdvol.Select(p => new object[] { p.Date, p.DIF }).ToArray(), deavol = macdvol.Select(p => new object[] { p.Date, p.DEA }).ToArray(), ma5 = ma5.Select(p => new object[] { p.Date, p.Value }).ToArray(), ma30 = ma30.Select(p => new object[] { p.Date, p.Value }).ToArray(), ma60 = ma60.Select(p => new object[] { p.Date, p.Value }).ToArray(), ma120 = ma120.Select(p => new object[] { p.Date, p.Value }).ToArray(), code = kdata.Code, name = basic.name, bottom = bottom.Select(p => new object[] { p.Date, p.Value }).ToArray(), keyprices = keyprice(k, id, ktype) }); }
public override universe Pass(IEnumerable <string> stocks) { var client = new kdatadb(); log.Info("query k60"); var k60 = stocks .AsParallel() .Select(code => client.kdata(code, "60")) .Where(p => p != null && p.Any()) .ToArray(); log.InfoFormat("k60 total {0}", k60.Count()); var codes = k60 .Where(p => { var macd = (macd) new MACD(p.close()); return(macd != null && macd.MACD > 0 && macd.DIF <= 0.01 && macd.Date.Date == DateTime.Today); }) .Select(p => p.Code) .Distinct() .ToArray(); if (codes.Any()) { log.Info("query k15"); var k15 = codes .AsParallel() .Select(code => client.kdata(code, "15")) .Where(p => p != null && p.Any()) .ToArray(); log.InfoFormat("k15 total {0}", k15.Count()); codes = k15 .Where(p => { var close = p.close(); var macd = (macd) new MACD(close); var deviation = (deviation) new DEVIATION(close, deviationtype.底背离); return(macd != null && macd.MACD > 0 && macd.Date.Date == DateTime.Today && deviation != null && deviation.d2.Date == DateTime.Today); }) .Select(p => p.Code) .Distinct() .ToArray(); } log.InfoFormat("selected {0}", codes.Count()); return(new universe("macd60", codes)); }
public override universe Pass(IEnumerable <string> stocks) { var client = new kdatadb(); log.Info("query market data"); var data = stocks .AsParallel() .Select(code => client.kdata(code, "D")) .Where(p => p != null) .ToArray(); log.InfoFormat("total {0}", data.Count()); log.Info("query fundamentals"); var basics = new db().basics(data.Select(p => p.Code).Distinct().ToArray()); var stat = data .Select(series => new factorset(series.Code) { 收阳百分比 = new close_up_percent(series, TimeSpan.FromDays(180)).value, 均线多头 = new jun_xian_dou_tout(series).value, 低点反弹高度 = new low_to_historical_lowest(series, new DateTime(2015, 5, 1)).value }) .ToArray(); if (junxianduotou) { stat = stat.Where(p => p.均线多头).ToArray(); } stat = stat .Where(p => p.低点反弹高度 < benchmark * beta) .OrderBy(p => p.低点反弹高度) .ToArray(); var q = from s in stat join b in basics on s.代码 equals b.code join d in data on s.代码 equals d.Code select new Stock(s.代码, new { s.代码, b.name, s.收阳百分比, s.低点反弹高度, s.均线多头, b.pe, b.totalAssets, b.industry, b.liquidAssets }); return(new universe("lowbeta", q.Select(p => p.Code).Distinct().ToArray())); }
private IEnumerable <string> deviations(string code, DateTime date, deviationtype type) { var ktypes = new[] { "D", "60", "30", "15", "5" }; foreach (var ktype in ktypes) { var k = new kdatadb().kdata(code, ktype); if (k == null || !k.Any()) { continue; } var deviation = (deviation) new DEVIATION(k.close(), type); if (deviation != null && deviation.d2.Date == date.Date) { yield return(ktype); } } }
public override void Run(Account account) { var client = new kdatadb(); log.InfoFormat("total {0}", account.universe.Count); foreach (var stock in account.universe.AsParallel()) { log.InfoFormat("run {0}", stock.Code); var k = client.kdata(stock.Code, "15"); var kdj = new MACD(k.close()); var crossup = kdj.cross_gold(); var crossdown = kdj.cross_dead(); if (crossup.Any()) { var s = crossup.Last(); if (s.Date == k.Last().date&& s.Date.Date == DateTime.Today) { Buy(account, stock.Code, s.Date); continue; } } if (crossdown.Any()) { var s = crossdown.Last(); if (s.Date == k.Last().date&& s.Date.Date == DateTime.Today) { Sell(account, stock.Code, s.Date); continue; } } log.InfoFormat("no signal {0}", stock.Code); } }
public override universe Pass(IEnumerable <string> stocks) { var client = new kdatadb(); log.Info("query D"); var D = stocks .AsParallel() .Select(code => client.kdata(code, "D")) .Where(p => p != null && p.Any()) .ToArray(); log.InfoFormat("D total {0}", D.Count()); var codes = D .Where(p => { if (!p.Any()) { return(false); } var close = p.close(); var cross = new MACD(p.volume()).cross(); return(cross.Any() && cross.Last().type == Interface.Data.crosstype.gold && cross.Last().value.Date.Date == DateTime.Today); }) .Select(p => p.Code) .Distinct() .ToArray(); log.InfoFormat("selected {0}", codes.Count()); return(new universe("volume", codes)); }
public override void exec() { //var a = analytic.hitkeyprices(); //log.Info(a.ToCsv()); //return; log.Info("run strategy " + param.name.ToLower()); log.Info("get codes"); universe universe; if (param.astock) { var codes = param.universe.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries); universe = new universe(param.universe, codes); } else if (param.asector) { universe = new universe(param.universe, new Trade.Db.db().codes(param.universe).ToArray()); } else { universe = getUniverse(param.universe); } log.Info("total " + universe.codes.Length); log.Info("get run"); var pool = new StockPool(universe.codes); var orders = !param.backtest ? new IOrder[] { new dbOrder(), new smsOrder() } : new IOrder[] { new dbOrder() }; var portflio = (param.portflio ?? param.name.ToLower()) + (param.backtest ? "-backtest" : ""); var account = new Account(portflio, pool, orders, param.backtest); switch (param.name.ToLower()) { case "macd15min": new strategies.macd15minstrategy().Run(account); break; } if (param.backtest) { log.Info("run back test"); var client = new kdatadb(); log.InfoFormat("total {0}", account.universe.Count); var pnls = new List <pnl>(); foreach (var stock in account.universe.AsParallel()) { log.InfoFormat("run {0}", stock.Code); var k = client.kdata(stock.Code, "D"); if (k == null && !k.Any()) { log.WarnFormat("empty data set for {0}", stock.Code); continue; } var trades = account.Trades .Where(p => p.code == stock.Code) //.Where(p=>p.Date >= new DateTime(2016,9,1)) .OrderBy(p => p.date) .ToArray(); var backtest = new backtesting(stock.Code, k.close(), trades); if (backtest.pnl != null) { pnls.Add(backtest.pnl); } } var format = "{0,-15}{1,-20}{2,10:N0}{3,10:N0}{4,10:N1}"; log.InfoFormat(format, "code", "date", "value", "capital", "ratio%"); foreach (var pnl in pnls) { log.InfoFormat(format, pnl.code, pnl.date, pnl.value, pnl.capital, pnl.ratio); } } log.Info("**********DONE**********"); }
public override void exec() { log.Info("**********START**********"); var cache = new Dictionary <string, kdata>(); var db = new Db.db(); var codes = db.codes(); var i = 0; var count = codes.Count(); var ktypes = new[] { "5", "15", "30", "60", "D", "W", "M" }; foreach (var code in codes.AsParallel()) { Interlocked.Increment(ref i); log.InfoFormat("{0}/{1} calc {2}", i, count, code); foreach (var ktype in ktypes) { try { var kdata = new kdatadb().kdata(code, ktype); if (kdata != null && kdata.Any()) { var date = kdata.Last().date; var close = kdata.close(); var macd = new MACD(close); var macdvol = new MACD(kdata.volume(100)); var ma5 = new MA(close, 5); var ma10 = new MA(close, 10); var ma20 = new MA(close, 20); var ma30 = new MA(close, 30); var ma60 = new MA(close, 60); var ma120 = new MA(close, 120); var chg = new CHG(close); var ka = new kanalytic() { code = code, date = date, ktype = ktype, close = kdata.Last().close.ZeroNaN(), open = kdata.Last().open.ZeroNaN(), high = kdata.Last().high.ZeroNaN(), low = kdata.Last().low.ZeroNaN(), volume = kdata.Last().volume.ZeroNaN(), chg = chg.Last().Value.ZeroNaN(), ma5 = ma5.Last().Value.ZeroNaN(), ma10 = ma10.Last().Value.ZeroNaN(), ma20 = ma20.Last().Value.ZeroNaN(), ma30 = ma30.Last().Value.ZeroNaN(), ma60 = ma60.Last().Value.ZeroNaN(), ma120 = ma120.Last().Value.ZeroNaN(), dea = macd.Last().DEA.ZeroNaN(), macd = macd.Last().MACD.ZeroNaN(), dif = macd.Last().DIF.ZeroNaN(), deavol = macdvol.Last().DEA.ZeroNaN(), macdvol = macdvol.Last().MACD.ZeroNaN(), difvol = macdvol.Last().DIF.ZeroNaN() }; db.save(new[] { ka }); } } catch (Exception e) { log.Warn("ex @ calc " + code + " for " + ktype, e); } } } log.Info("**********DONE**********"); }
public analytic Get(string id, string ktype) { var result = new analytic(); var k = new kdatadb().kdata(id, ktype); var basic = new db().basics(id); result.istock = basic.assettype == assettypes.stock; result.sectors = basic.getsectors(); result.indexes = new db().basicnames(basic.getindexes()).ToArray(); result.stocks = basic.assettype == assettypes.sector ? new db().basicnamesinsector(id).ToArray() : new basicname[0]; result.code = basic.code; result.name = basic.name; result.PE = basic.pe; if (k != null && k.Any()) { var cur = k.Last(); var prev = k.Count > 1 ? k[k.Count - 2] : null; result.date = cur.date.ToString("yyyy-MM-dd"); result.high = cur.high; result.low = cur.close; result.open = cur.open; result.close = cur.close; result.change = prev == null ? (double?)null : ((cur.close - prev.close) / prev.close) * 100; var q = (quotation) new QUOTATION(k); if (q != null) { result.state = q.state.ToString(); result.position = q.position; result.strategy = q.strategy; } var devs_up = deviations(id, cur.date.Date, deviationtype.底背离); if (devs_up.Any()) { result.deviation_up = string.Join(",", devs_up); } var devs_down = deviations(id, cur.date.Date, deviationtype.顶背离); if (devs_down.Any()) { result.deviation_down = string.Join(",", devs_down); } var ma = new List <string>(); var close = k.close(); var ma5 = (double?)new MA(close, 5); var ma30 = (double?)new MA(close, 30); var ma55 = (double?)new MA(close, 55); var ma120 = (double?)new MA(close, 120); if (ma5 >= ma30 && ma30 >= ma55 && ma55 >= ma120) { ma.Add("多头"); } if (cur.close < ma5) { ma.Add("↓↓5日线"); } //if (cur.close < ma30) // ma.Add("破30日生命线"); //if (cur.close < ma55) // ma.Add("破55日生命线"); if (cur.close < ma120) { ma.Add("↓↓半年线"); } else { ma.Add("半年线↑↑"); } if (ma.Any()) { result.ma = string.Join(",", ma); } var cross = new MACD(k.volume()).cross(); if (cross.Any()) { if (cross.Last().type == Interface.Data.crosstype.gold) { result.buyorsell = cross.Last().value.Date.Date == DateTime.Today ? "买入" : "持有"; } else if (cross.Last().type == Interface.Data.crosstype.dead) { result.buyorsell = "卖出"; } } } var mainindex = basic.mainindex(); if (!string.IsNullOrEmpty(mainindex)) { var dindex = new kdatadb().kdata(mainindex, ktype); result.beta = new BETA( new kdata(id, k.Where(p => p.date >= Trade.Cfg.Configuration.data.bearcrossbull).ToArray()), new kdata(id, dindex.Where(p => p.date >= Trade.Cfg.Configuration.data.bearcrossbull).ToArray())).beta; } return(result); }
public static dynamic[] hitkeyprices() { var db = new Db.db(); var keyprices = db.keyprices("D"); var todayquotes = new kdatadb().ktoday(); keyprices = keyprices .OrderBy(p => p.Code) .ThenByDescending(p => p.Date) .Where(p => p.Flag == KeyPrice.Flags.lower) .GroupBy(p => p.Code) .Select(p => p.First()) .ToArray(); var q = (from k in keyprices join t in todayquotes on k.Code equals t.code where k.Flag == KeyPrice.Flags.lower && Math.Abs((t.low / k.Price - 1) * 100d) <= 0.8 && t.changepercent >= 0.01 && t.changepercent <= 1.0 && Math.Abs((k.Date - DateTime.Today).TotalDays) >= 8 select new { k, t } ) .ToArray() .Where(p => { var code = (string)p.t.code; var k = new kdatadb().kdata(code, "D"); if (k == null) { return(false); } var low = (double)p.t.low; var N = 8; for (var i = k.Count - 1; i > k.Count - N; --i) { if (k[i].low < low) { return(false); } } return(true); }) .Select(_ => { var k = _.k; var t = _.t; dynamic d = new ExpandoObject(); d.date = k.Date; d.cross = Math.Abs((k.Date - DateTime.Today).TotalDays); d.price = k.Price; d.distpercent = (t.low / k.Price - 1) * 100; d.pe = t.pe; d.code = t.code; d.name = t.name; d.trade = t.trade; d.high = t.high; d.low = t.low; d.open = t.open; d.close = t.close; d.volume = t.volume; d.changepercent = t.changepercent; d.turnoverratio = t.turnoverratio; d.pb = t.pb; d.amount = t.amount; d.mktcap = t.mktcap; d.ts = t.ts; return(d); }); var r = q .OrderBy(p => p.code) .ThenByDescending(p => p.date) .GroupBy(p => new { p.code }) .Select(p => p.First()) .OrderBy(p => p.cross) .ThenByDescending(p => p.changepercent) .ToArray(); return(r); }
public static dynamic[] macd60() { var kas = new db().kanalytics("60") .Where(p => { return(p.macd > 0 && p.dif <= 0.01); }) .ToArray(); if (!kas.Any()) { return(new dynamic[0]); } kas = new db().kanalytic(kas.Select(p => p.code).Distinct().ToArray(), "15") .Where(p => { return(p.macd > 0); }) .ToArray(); if (!kas.Any()) { return(new dynamic[0]); } kas = kas .AsParallel() .Where(p => { var k = new kdatadb().kdata(p.code, "15"); if (k == null || !k.Any()) { return(false); } var deviation = (deviation) new DEVIATION(k.close(), deviationtype.底背离); return(deviation != null && deviation.d2.Date.Date >= p.date.Date); }) .ToArray(); if (!kas.Any()) { return(new dynamic[0]); } var codes = kas.Select(p => p.code).Distinct().ToArray(); var basics = new db().basics(codes); var ka = new db().kanalytic(codes, "D"); var q = (from k in ka join t in basics on k.code equals t.code where t.assettype == assettypes.stock && !t.terminated && !t.suspended && !t.st select new { k, t } ) .Select(_ => { var k = _.k; var t = _.t; dynamic d = new ExpandoObject(); d.date = k.date; d.pe = t.pe; d.code = t.code; d.name = t.name; d.high = k.high; d.low = k.low; d.open = k.open; d.close = k.close; d.volume = k.volume; d.chg = k.chg; d.pb = t.pb; d.pe = t.pe; return(d); }); var r = q .OrderBy(p => p.code) .ThenByDescending(p => p.date) .GroupBy(p => new { p.code }) .Select(p => p.First()) .ToArray(); return(r); }