asxinyu/Stock

历史数据分析
董斌辉 authored at 2018-02-13 16:14:38
96945d8
Tree
1 Parent(s) 35202e1
Summary: 7 changed files with 432 additions and 4 deletions.
Modified +1 -0
Modified +6 -1
Added +114 -0
Added +276 -0
Modified +32 -2
Modified +1 -1
Modified +2 -0
Modified +1 -0
diff --git a/.gitignore b/.gitignore
index bb23abf..69900b2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -228,3 +228,4 @@ ModelManifest.xml
 /Doc/stock_day.db
 /Doc/板块信息.txt
 /Doc
+/StockData/Analysis/Config
Modified +6 -1
diff --git a/StockData/Analysis/Analysis.xml b/StockData/Analysis/Analysis.xml
index f81ad91..fd23ca6 100644
--- a/StockData/Analysis/Analysis.xml
+++ b/StockData/Analysis/Analysis.xml
@@ -1,9 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Tables Version="9.6.6445.23431" Output="Entity" NameSpace="StockData.Analysis.Entity" ConnName="stock_Analysis" BaseClass="Entity">
+<Tables Version="9.6.6445.23431" Output="Entity" NameSpace="StockData.Analysis.Entity" ConnName="Analysis" BaseClass="Entity">
   <Table Name="StockElementInfo" Description="股票分析元数据" ConnName="stock_analysis">
     <Columns>
       <Column Name="Code" DataType="String" PrimaryKey="True" Description="股票编码" />
       <Column Name="Name" DataType="String" Master="True" Description="名称" />
+      <Column Name="Price" DataType="Double" Description="当前价格" />
+      <Column Name="Rate" DataType="Double" Description="当前倍数" />
       <Column Name="MaxPrice" DataType="Double" Description="历史最高价格" />
       <Column Name="MinPrice" DataType="Double" Description="历史最低价格" />
       <Column Name="MaxRate" DataType="Double" Description="历史倍数" />
@@ -13,4 +15,7 @@
       <Column Name="UpdateDate" DataType="DateTime" Description="更新日期" />
     </Columns>
   </Table>
+  <Indexes>
+    <Index Columns="Code" />
+  </Indexes>
 </Tables>
\ No newline at end of file
Added +114 -0
diff --git "a/StockData/Analysis/Entity/\350\202\241\347\245\250\345\210\206\346\236\220\345\205\203\346\225\260\346\215\256.Biz.cs" "b/StockData/Analysis/Entity/\350\202\241\347\245\250\345\210\206\346\236\220\345\205\203\346\225\260\346\215\256.Biz.cs"
new file mode 100644
index 0000000..fbc228d
--- /dev/null
+++ "b/StockData/Analysis/Entity/\350\202\241\347\245\250\345\210\206\346\236\220\345\205\203\346\225\260\346\215\256.Biz.cs"
@@ -0,0 +1,114 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web;
+using System.Xml.Serialization;
+using NewLife;
+using NewLife.Data;
+using NewLife.Log;
+using NewLife.Model;
+using NewLife.Reflection;
+using NewLife.Threading;
+using NewLife.Web;
+using XCode;
+using XCode.Cache;
+using XCode.Configuration;
+using XCode.DataAccessLayer;
+using XCode.Membership;
+
+namespace StockData.Analysis.Entity
+{
+    /// <summary>股票分析元数据</summary>
+    public partial class StockElementInfo : Entity<StockElementInfo>
+    {
+        #region 对象操作
+        static StockElementInfo()
+        {
+            // 累加字段
+            //Meta.Factory.AdditionalFields.Add(__.Logins);
+
+            // 过滤器 UserModule、TimeModule、IPModule
+        }
+
+        /// <summary>验证数据,通过抛出异常的方式提示验证失败。</summary>
+        /// <param name="isNew">是否插入</param>
+        public override void Valid(Boolean isNew)
+        {
+            // 如果没有脏数据,则不需要进行任何处理
+            if (!HasDirty) return;
+
+            // 在新插入数据或者修改了指定字段时进行修正
+        }
+
+        ///// <summary>首次连接数据库时初始化数据,仅用于实体类重载,用户不应该调用该方法</summary>
+        //[EditorBrowsable(EditorBrowsableState.Never)]
+        //protected override void InitData()
+        //{
+        //    // InitData一般用于当数据表没有数据时添加一些默认数据,该实体类的任何第一次数据库操作都会触发该方法,默认异步调用
+        //    if (Meta.Count > 0) return;
+
+        //    if (XTrace.Debug) XTrace.WriteLine("开始初始化StockElementInfo[股票分析元数据]数据……");
+
+        //    var entity = new StockElementInfo();
+        //    entity.Code = "abc";
+        //    entity.Name = "abc";
+        //    entity.MaxPrice = 0.0;
+        //    entity.MinPrice = 0.0;
+        //    entity.MaxRate = 0.0;
+        //    entity.Max5year = 0.0;
+        //    entity.Min5year = 0.0;
+        //    entity.Max5Rate = 0.0;
+        //    entity.UpdateDate = DateTime.Now;
+        //    entity.Insert();
+
+        //    if (XTrace.Debug) XTrace.WriteLine("完成初始化StockElementInfo[股票分析元数据]数据!"
+        //}
+
+        ///// <summary>已重载。基类先调用Valid(true)验证数据,然后在事务保护内调用OnInsert</summary>
+        ///// <returns></returns>
+        //public override Int32 Insert()
+        //{
+        //    return base.Insert();
+        //}
+
+        ///// <summary>已重载。在事务保护范围内处理业务,位于Valid之后</summary>
+        ///// <returns></returns>
+        //protected override Int32 OnDelete()
+        //{
+        //    return base.OnDelete();
+        //}
+        #endregion
+
+        #region 扩展属性
+        #endregion
+
+        #region 扩展查询
+        /// <summary>根据股票编码查找</summary>
+        /// <param name="code">股票编码</param>
+        /// <returns>实体对象</returns>
+        public static StockElementInfo FindByCode(String code)
+        {
+            if (code.IsNullOrEmpty()) return null;
+
+            // 实体缓存
+            if (Meta.Count < 1000) return Meta.Cache.Entities.FirstOrDefault(e => e.Code == code);
+
+            // 单对象缓存
+            //return Meta.SingleCache[code];
+
+            return Find(_.Code == code);
+        }
+        #endregion
+
+        #region 高级查询
+        #endregion
+
+        #region 业务操作
+        #endregion
+    }
+}
\ No newline at end of file
Added +276 -0
diff --git "a/StockData/Analysis/Entity/\350\202\241\347\245\250\345\210\206\346\236\220\345\205\203\346\225\260\346\215\256.cs" "b/StockData/Analysis/Entity/\350\202\241\347\245\250\345\210\206\346\236\220\345\205\203\346\225\260\346\215\256.cs"
new file mode 100644
index 0000000..d750ddf
--- /dev/null
+++ "b/StockData/Analysis/Entity/\350\202\241\347\245\250\345\210\206\346\236\220\345\205\203\346\225\260\346\215\256.cs"
@@ -0,0 +1,276 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using XCode;
+using XCode.Configuration;
+using XCode.DataAccessLayer;
+
+namespace StockData.Analysis.Entity
+{
+    /// <summary>股票分析元数据</summary>
+    [Serializable]
+    [DataObject]
+    [Description("股票分析元数据")]
+    [BindTable("StockElementInfo", Description = "股票分析元数据", ConnName = "stock_analysis", DbType = DatabaseType.None)]
+    public partial class StockElementInfo : IStockElementInfo
+    {
+        #region 属性
+        private String _Code;
+        /// <summary>股票编码</summary>
+        [DisplayName("股票编码")]
+        [Description("股票编码")]
+        [DataObjectField(true, false, true, 50)]
+        [BindColumn("Code", "股票编码", "")]
+        public String Code { get { return _Code; } set { if (OnPropertyChanging(__.Code, value)) { _Code = value; OnPropertyChanged(__.Code); } } }
+
+        private String _Name;
+        /// <summary>名称</summary>
+        [DisplayName("名称")]
+        [Description("名称")]
+        [DataObjectField(false, false, true, 50)]
+        [BindColumn("Name", "名称", "", Master = true)]
+        public String Name { get { return _Name; } set { if (OnPropertyChanging(__.Name, value)) { _Name = value; OnPropertyChanged(__.Name); } } }
+
+        private Double _Price;
+        /// <summary>当前价格</summary>
+        [DisplayName("当前价格")]
+        [Description("当前价格")]
+        [DataObjectField(false, false, false, 0)]
+        [BindColumn("Price", "当前价格", "")]
+        public Double Price { get { return _Price; } set { if (OnPropertyChanging(__.Price, value)) { _Price = value; OnPropertyChanged(__.Price); } } }
+
+        private Double _Rate;
+        /// <summary>当前倍数</summary>
+        [DisplayName("当前倍数")]
+        [Description("当前倍数")]
+        [DataObjectField(false, false, false, 0)]
+        [BindColumn("Rate", "当前倍数", "")]
+        public Double Rate { get { return _Rate; } set { if (OnPropertyChanging(__.Rate, value)) { _Rate = value; OnPropertyChanged(__.Rate); } } }
+
+        private Double _MaxPrice;
+        /// <summary>历史最高价格</summary>
+        [DisplayName("历史最高价格")]
+        [Description("历史最高价格")]
+        [DataObjectField(false, false, false, 0)]
+        [BindColumn("MaxPrice", "历史最高价格", "")]
+        public Double MaxPrice { get { return _MaxPrice; } set { if (OnPropertyChanging(__.MaxPrice, value)) { _MaxPrice = value; OnPropertyChanged(__.MaxPrice); } } }
+
+        private Double _MinPrice;
+        /// <summary>历史最低价格</summary>
+        [DisplayName("历史最低价格")]
+        [Description("历史最低价格")]
+        [DataObjectField(false, false, false, 0)]
+        [BindColumn("MinPrice", "历史最低价格", "")]
+        public Double MinPrice { get { return _MinPrice; } set { if (OnPropertyChanging(__.MinPrice, value)) { _MinPrice = value; OnPropertyChanged(__.MinPrice); } } }
+
+        private Double _MaxRate;
+        /// <summary>历史倍数</summary>
+        [DisplayName("历史倍数")]
+        [Description("历史倍数")]
+        [DataObjectField(false, false, false, 0)]
+        [BindColumn("MaxRate", "历史倍数", "")]
+        public Double MaxRate { get { return _MaxRate; } set { if (OnPropertyChanging(__.MaxRate, value)) { _MaxRate = value; OnPropertyChanged(__.MaxRate); } } }
+
+        private Double _Max5year;
+        /// <summary>近5年最高</summary>
+        [DisplayName("近5年最高")]
+        [Description("近5年最高")]
+        [DataObjectField(false, false, false, 0)]
+        [BindColumn("Max5year", "近5年最高", "")]
+        public Double Max5year { get { return _Max5year; } set { if (OnPropertyChanging(__.Max5year, value)) { _Max5year = value; OnPropertyChanged(__.Max5year); } } }
+
+        private Double _Min5year;
+        /// <summary>近5年最低</summary>
+        [DisplayName("近5年最低")]
+        [Description("近5年最低")]
+        [DataObjectField(false, false, false, 0)]
+        [BindColumn("Min5year", "近5年最低", "")]
+        public Double Min5year { get { return _Min5year; } set { if (OnPropertyChanging(__.Min5year, value)) { _Min5year = value; OnPropertyChanged(__.Min5year); } } }
+
+        private Double _Max5Rate;
+        /// <summary>近5年倍数</summary>
+        [DisplayName("近5年倍数")]
+        [Description("近5年倍数")]
+        [DataObjectField(false, false, false, 0)]
+        [BindColumn("Max5Rate", "近5年倍数", "")]
+        public Double Max5Rate { get { return _Max5Rate; } set { if (OnPropertyChanging(__.Max5Rate, value)) { _Max5Rate = value; OnPropertyChanged(__.Max5Rate); } } }
+
+        private DateTime _UpdateDate;
+        /// <summary>更新日期</summary>
+        [DisplayName("更新日期")]
+        [Description("更新日期")]
+        [DataObjectField(false, false, true, 0)]
+        [BindColumn("UpdateDate", "更新日期", "")]
+        public DateTime UpdateDate { get { return _UpdateDate; } set { if (OnPropertyChanging(__.UpdateDate, value)) { _UpdateDate = value; OnPropertyChanged(__.UpdateDate); } } }
+        #endregion
+
+        #region 获取/设置 字段值
+        /// <summary>获取/设置 字段值</summary>
+        /// <param name="name">字段名</param>
+        /// <returns></returns>
+        public override Object this[String name]
+        {
+            get
+            {
+                switch (name)
+                {
+                    case __.Code : return _Code;
+                    case __.Name : return _Name;
+                    case __.Price : return _Price;
+                    case __.Rate : return _Rate;
+                    case __.MaxPrice : return _MaxPrice;
+                    case __.MinPrice : return _MinPrice;
+                    case __.MaxRate : return _MaxRate;
+                    case __.Max5year : return _Max5year;
+                    case __.Min5year : return _Min5year;
+                    case __.Max5Rate : return _Max5Rate;
+                    case __.UpdateDate : return _UpdateDate;
+                    default: return base[name];
+                }
+            }
+            set
+            {
+                switch (name)
+                {
+                    case __.Code : _Code = Convert.ToString(value); break;
+                    case __.Name : _Name = Convert.ToString(value); break;
+                    case __.Price : _Price = Convert.ToDouble(value); break;
+                    case __.Rate : _Rate = Convert.ToDouble(value); break;
+                    case __.MaxPrice : _MaxPrice = Convert.ToDouble(value); break;
+                    case __.MinPrice : _MinPrice = Convert.ToDouble(value); break;
+                    case __.MaxRate : _MaxRate = Convert.ToDouble(value); break;
+                    case __.Max5year : _Max5year = Convert.ToDouble(value); break;
+                    case __.Min5year : _Min5year = Convert.ToDouble(value); break;
+                    case __.Max5Rate : _Max5Rate = Convert.ToDouble(value); break;
+                    case __.UpdateDate : _UpdateDate = Convert.ToDateTime(value); break;
+                    default: base[name] = value; break;
+                }
+            }
+        }
+        #endregion
+
+        #region 字段名
+        /// <summary>取得股票分析元数据字段信息的快捷方式</summary>
+        public partial class _
+        {
+            /// <summary>股票编码</summary>
+            public static readonly Field Code = FindByName(__.Code);
+
+            /// <summary>名称</summary>
+            public static readonly Field Name = FindByName(__.Name);
+
+            /// <summary>当前价格</summary>
+            public static readonly Field Price = FindByName(__.Price);
+
+            /// <summary>当前倍数</summary>
+            public static readonly Field Rate = FindByName(__.Rate);
+
+            /// <summary>历史最高价格</summary>
+            public static readonly Field MaxPrice = FindByName(__.MaxPrice);
+
+            /// <summary>历史最低价格</summary>
+            public static readonly Field MinPrice = FindByName(__.MinPrice);
+
+            /// <summary>历史倍数</summary>
+            public static readonly Field MaxRate = FindByName(__.MaxRate);
+
+            /// <summary>近5年最高</summary>
+            public static readonly Field Max5year = FindByName(__.Max5year);
+
+            /// <summary>近5年最低</summary>
+            public static readonly Field Min5year = FindByName(__.Min5year);
+
+            /// <summary>近5年倍数</summary>
+            public static readonly Field Max5Rate = FindByName(__.Max5Rate);
+
+            /// <summary>更新日期</summary>
+            public static readonly Field UpdateDate = FindByName(__.UpdateDate);
+
+            static Field FindByName(String name) { return Meta.Table.FindByName(name); }
+        }
+
+        /// <summary>取得股票分析元数据字段名称的快捷方式</summary>
+        public partial class __
+        {
+            /// <summary>股票编码</summary>
+            public const String Code = "Code";
+
+            /// <summary>名称</summary>
+            public const String Name = "Name";
+
+            /// <summary>当前价格</summary>
+            public const String Price = "Price";
+
+            /// <summary>当前倍数</summary>
+            public const String Rate = "Rate";
+
+            /// <summary>历史最高价格</summary>
+            public const String MaxPrice = "MaxPrice";
+
+            /// <summary>历史最低价格</summary>
+            public const String MinPrice = "MinPrice";
+
+            /// <summary>历史倍数</summary>
+            public const String MaxRate = "MaxRate";
+
+            /// <summary>近5年最高</summary>
+            public const String Max5year = "Max5year";
+
+            /// <summary>近5年最低</summary>
+            public const String Min5year = "Min5year";
+
+            /// <summary>近5年倍数</summary>
+            public const String Max5Rate = "Max5Rate";
+
+            /// <summary>更新日期</summary>
+            public const String UpdateDate = "UpdateDate";
+        }
+        #endregion
+    }
+
+    /// <summary>股票分析元数据接口</summary>
+    public partial interface IStockElementInfo
+    {
+        #region 属性
+        /// <summary>股票编码</summary>
+        String Code { get; set; }
+
+        /// <summary>名称</summary>
+        String Name { get; set; }
+
+        /// <summary>当前价格</summary>
+        Double Price { get; set; }
+
+        /// <summary>当前倍数</summary>
+        Double Rate { get; set; }
+
+        /// <summary>历史最高价格</summary>
+        Double MaxPrice { get; set; }
+
+        /// <summary>历史最低价格</summary>
+        Double MinPrice { get; set; }
+
+        /// <summary>历史倍数</summary>
+        Double MaxRate { get; set; }
+
+        /// <summary>近5年最高</summary>
+        Double Max5year { get; set; }
+
+        /// <summary>近5年最低</summary>
+        Double Min5year { get; set; }
+
+        /// <summary>近5年倍数</summary>
+        Double Max5Rate { get; set; }
+
+        /// <summary>更新日期</summary>
+        DateTime UpdateDate { get; set; }
+        #endregion
+
+        #region 获取/设置 字段值
+        /// <summary>获取/设置 字段值</summary>
+        /// <param name="name">字段名</param>
+        /// <returns></returns>
+        Object this[String name] { get; set; }
+        #endregion
+    }
+}
\ No newline at end of file
Modified +32 -2
diff --git a/StockData/Analysis/StockHelper.cs b/StockData/Analysis/StockHelper.cs
index 2adb38f..6b81174 100644
--- a/StockData/Analysis/StockHelper.cs
+++ b/StockData/Analysis/StockHelper.cs
@@ -9,6 +9,7 @@ using System.Threading.Tasks;
 using NewLife.Serialization;
 using StockData.Entity;
 using XCode;
+using StockData.Analysis.Entity;
 
 namespace StockData
 {
@@ -59,7 +60,6 @@ namespace StockData
                 index++;
                 if(item.Kind == 1)
                 {
-
                     StockDayData.Meta.ConnName = "stock_day";
                     var data = StockDayData.FindAll(StockDayData._.Code, item.Code);
                     StockDayData.Meta.ConnName = "stock_"+item.Code;
@@ -81,6 +81,7 @@ namespace StockData
             foreach (var item in all)
             {
                 XTrace.WriteLine("进度:{0}/{1}",index ++,all.Count);
+                //"stock_"+item.Code;
                 //if (item.StartDate > new DateTime(2000, 1, 2)) continue;
                 if (index < 2095) continue;
                 var entity = StockDayData.FindAll(StockDayData._.Code == item.Code,
@@ -100,7 +101,36 @@ namespace StockData
         }
         #endregion
 
-        #region 
+        #region 10年数据初步分析
+        public static void AnalysisFirst()
+        {
+            DateTime year5 = new DateTime(2013, 1, 1);
+            var all = StockBaseInfo.FindAll(StockBaseInfo._.Kind, 1);
+            int index = 1;
+            Parallel.For(0, all.Count, new ParallelOptions() { MaxDegreeOfParallelism = 8 }, i =>
+            {
+                XTrace.WriteLine("进度:{0}/{1}", index++, all.Count);
+                StockDayData.Meta.ConnName = "stock_" + all[i].Code;
+                var list = StockDayData.FindAll(StockDayData._.Code == all[i].Code,
+                                                StockDayData._.StatDate.Asc(), null, 0, 0);
+                if (list != null && list.Count > 0)
+                {
+                    StockElementInfo et = new StockElementInfo();
+                    et.Code = all[i].Code;
+                    et.Name = all[i].Name;
+                    et.Price = list.Last().EndPrice;
+                    et.MaxPrice = list.Max(n => n.EndPrice);
+                    et.MinPrice = list.Min(n => n.EndPrice);
+                    et.MaxRate = et.MaxPrice / et.MinPrice;
+                    et.Max5year = list.Where(n => n.StatDate > year5).Max(n => n.EndPrice);
+                    et.Min5year = list.Where(n => n.StatDate > year5).Min(n => n.EndPrice);
+                    et.Max5Rate = et.Max5year / et.Min5year;
+                    et.Rate = et.Max5year / et.Price;
+                    et.UpdateDate = DateTime.Now;
+                    et.Save();
+                }
+            });
+        }
         #endregion
     }
 }
Modified +1 -1
diff --git a/StockData/Program.cs b/StockData/Program.cs
index 070eed2..acf6528 100644
--- a/StockData/Program.cs
+++ b/StockData/Program.cs
@@ -12,7 +12,7 @@ namespace StockData
         static void Main(string[] args)
         {
             XTrace.UseConsole();
-            StockHisText.PraseHistoryDataV2();
+            StockHelper.AnalysisFirst();
             //StockHelper.SpliteDB();
             //GroupKind.ParseGroupInfo();
             //StockHisText.PraseHistoryData();
Modified +2 -0
diff --git a/StockData/StockData.csproj b/StockData/StockData.csproj
index 5920cb7..3e82f40 100644
--- a/StockData/StockData.csproj
+++ b/StockData/StockData.csproj
@@ -62,6 +62,8 @@
     </Reference>
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Analysis\Entity\股票分析元数据.Biz.cs" />
+    <Compile Include="Analysis\Entity\股票分析元数据.cs" />
     <Compile Include="Analysis\StockHelper.cs" />
     <Compile Include="Entity\指数信息.Biz.cs" />
     <Compile Include="Entity\指数信息.cs" />