示例#1
0
        /// <summary>
        /// 例如:MA(C,20)表示20日的平均收盘价。C表示CLOSE。
        ///EMA(X, N)指数平滑移动平均
        ///求X的N日指数平滑移动平均,它真正的公式表达是:当日指数平均值=平滑系数*(当日指数值-昨日指数平均值)+昨日指数平均值;平滑系数=2/(周期单位+1);由以上公式推导开,得到:EMA(C, N)=2*C/(N+1)+(N-1)/(N+1)*昨天的指数收盘平均值;
        ///算法是:若Y=EMA(X,N),则Y=[2*X+(N-1)*Y’]/(N+1),其中Y’表示上一周期的Y值。
        ///EMA引用函数在计算机上使用递归算法很容易实现,但不容易理解。例举分析说明EMA函数。
        ///X是变量,每天的X值都不同,从远到近地标记,它们分别记为X1,X2,X3,….,Xn
        ///如果N = 1,则EMA(X,1)=[2*X1+(1-1)*Y’]/(1+1)=X1
        ///如果N = 2,则EMA(X,2)=[2*X2+(2-1)*Y’]/(2+1)=(2/3)*X2+(1/3)X1
        ///如果N = 3,则EMA(X,3)=[2*X3+(3-1)*Y’]/(3+1)=[2*X3+2*((2/3)*X2+(1/3)*X1)]/4=(1 /2)*X3+(1/3)*X2+(1/6)*X1
        ///如果N = 4,则EMA(X,4)=[2*X4+(4-1)*Y’]/(4+1)=2/5*X4+3/5*((1/2)*X3+(1/3)*X2+(1 /6)*X1)=2/5*X4+3/10*X3+1/5*X2+1/10*X1
        ///如果N = 5,则EMA(X,5)=2/(5+1)*X5+(5-1)/(5+1)(2/5*X4+3/10*X3+3/15*X2+3/30*X1)=(1/3)*X5+(4/15)*X4+(3/15)*X3+(2/15)*X2+(1/15)*X1
        ///任何时候系数之和恒为1。如果X是常量,每天的X值都不变,则EMA(X, N)=MA(X, N).
        ///从以上的例举分析中,我们可以看到时间周期越近的X值它的权重越大,说明EMA函数对近期的X值加强了权重比,更能及时反映近期X值的波动情况。所以EMA比Ma更具参考价值,而ema 也不容易出现死叉和金叉,所以一旦出现要立即作出反映!对周线处理,ema就更加稳定了
        public static TimeSeries <ITimeSeriesItem <double> > EMA(this TimeSeries <ITimeSeriesItem <double> > ts, int num)
        {
            TimeSeries <ITimeSeriesItem <double> > results = new TimeSeries <ITimeSeriesItem <double> >();

            if (ts == null || ts.Count <= 0)
            {
                return(results);
            }
            TimeSeriesItem <double> obj = new TimeSeriesItem <double>()
            {
                Date  = ts[0].Date,
                Value = ts[0].Value
            };

            results.Add(obj);
            double prevValue = obj.Value;

            for (int i = 1; i < ts.Count; i++)
            {
                double value = (2 * ts[i].Value + (num - 1) * prevValue) / (num + 1);
                obj = new TimeSeriesItem <double>()
                {
                    Date  = ts[i].Date,
                    Value = value
                };
                results.Add(obj);
                prevValue = value;
            }
            return(results);
        }
示例#2
0
        /// <summary>
        /// 乘法
        /// </summary>
        /// <param name="ts1"></param>
        /// <param name="v"></param>
        /// <returns></returns>
        public static TimeSeries <ITimeSeriesItem <double> > operator *(TimeSeries <T> ts1, double v)
        {
            TimeSeries <ITimeSeriesItem <double> > results = new TimeSeries <ITimeSeriesItem <double> >();

            ts1.ForEach(t1 => results.Add((t1 as TimeSeriesItem) * v));
            return(results);
        }
示例#3
0
        /// <summary>
        /// MA(X,N)简单算术平均
        /// 求X的N日移动平均值,不分轻重,平均算。算法是:
        /// (X1+X2+X3+…..+Xn)/N
        /// 例如:MA(C,20)表示20日的平均收盘价。C表示CLOSE。
        /// </summary>
        /// <param name="ts"></param>
        /// <param name="num"></param>
        /// <returns></returns>
        public static TimeSeries <ITimeSeriesItem <double> > MA(this TimeSeries <ITimeSeriesItem <double> > ts, int num)
        {
            TimeSeries <ITimeSeriesItem <double> > results = new TimeSeries <ITimeSeriesItem <double> >();

            for (int i = num - 1; i < ts.Count; i++)
            {
                ITimeSeriesItem         t    = ts[i];
                TimeSeriesItem <double> item = new TimeSeriesItem <double>()
                {
                    Date  = t.Date,
                    Value = ts[i - num + 1, i].Sum(x => x.Value) / num
                };
                results.Add(item);
            }
            return(results);
        }
示例#4
0
        /// <summary>
        /// y=a+b*x;
        ///最小平方法求出估计值a,b,代入得估计直线
        ///b1:=∑(x(i)-avr(x,30))* (y(i)-avr(y,30));
        ///b2:=∑(x(i)-avr(x,30))^2;
        ///b:=b1/b2;
        ///a:=avr(y,30)-b*avr(x,30);SLOPE=(X,N)
        /// </summary>
        /// <param name="ts"></param>
        /// <param name="num"></param>
        /// <returns></returns>
        public static TimeSeries <ITimeSeriesItem <double> > SLOPE(this ITimeSeries <ITimeSeriesItem <double> > ts, int num)
        {
            TimeSeries <ITimeSeriesItem <double> > results = new TimeSeries <ITimeSeriesItem <double> >();

            for (int i = num - 1; i < ts.Count; i++)
            {
                List <double> list  = ts[i - num + 1, i].ConvertAll <double>(x => x.Value).ToList();
                double        slope = list.SLOPE();

                TimeSeriesItem <double> item = new TimeSeriesItem <double>()
                {
                    Date  = ts[i].Date,
                    Value = slope
                };

                results.Add(item);
            }
            return(results);
        }
示例#5
0
        /// <summary>
        /// 假设日期:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20.。。。。。。。
        /// 如果在10这个地方统计MA(C,5)=(6+7+8+9+10)/5;这是以10为终点,向前统计法;
        /// 如果在10这个地方统计XMA(C,5)=(8+9+10+11+12)/5;这是以10为中点,从中间向前和向后统计法;
        /// 如果在10这个地方统计MA(C,7)=(4+5+6+7+8+9+10)/7;这是以10为终点,向前统计法;
        /// 如果在10这个地方统计XMA(C,7)=(7+8+9+10+11+12+13)/7;这是以10为中点,从中间向前和向后统计法;
        /// 如果在10这个地方统计MA(C,9)=(2+3+4+5+6+7+8+9+10)/9;这是以10为终点,向前统计法;
        /// 如果在10这个地方统计XMA(C,9)=(6+7+8+9+10+11+12+13+14)/9;这是以10为中点,从中间向前和向后统计法;
        /// 假如今天就是10号收盘,前面的数据已经发生了,但是11号、12、13、14、15、16、17、18、19、20......没有发生,
        /// 没有发生就没数据,但XMA如何给没发生的赋值数据呢?
        /// 原理很简单:假如是XMA(C,7),以10号收盘来统计XMA(C,7),7、8、9、10数据已经有了,
        /// 但11、12、13还没发生,数据没有,怎么办?就是这用7、8、9、10这4天的平均价赋值分别给11、12、13;然后全部求平均。
        /// 如果是N天呢?N天后的没有发生的怎么赋值?那就用N天前的包括N天的((N+1)/2)天的平均价赋值;
        /// 但是有一点,XMA还怪在这里:当今天10号已经过去,11号变成今天,昨天对11号没发生的赋值又会用今天的实际值来取代。
        /// 用11号实际发生的数值取代昨天对今天的赋值;
        /// XMA(C,N)里的一般为奇数,当N设定为偶数时候,它怎么办呢?就是自动采用N+1法自动调整为奇数。
        /// </summary>
        /// <param name="ts"></param>
        /// <param name="num"></param>
        /// <returns></returns>
        public static TimeSeries <ITimeSeriesItem <double> > XMA(this TimeSeries <ITimeSeriesItem <double> > ts, int num)
        {
            if (num % 2 == 0)
            {
                num += 1;
            }
            int len = (num - 1) / 2;

            TimeSeries <ITimeSeriesItem <double> > results = new TimeSeries <ITimeSeriesItem <double> >();

            for (int i = len; i < ts.Count; i++)
            {
                double sum = 0, temp = 0;
                for (int j = i - len; j <= i + len; j++)
                {
                    if (j < ts.Count)
                    {
                        sum += ts[j].Value;
                    }
                    else
                    {
                        if (temp == 0)
                        {
                            temp = sum / (j - i + len);
                        }
                        sum += temp;
                    }
                }


                TimeSeriesItem <double> item = new TimeSeriesItem <double>()
                {
                    Date  = ts[i].Date,
                    Value = sum / num
                };
                results.Add(item);
            }
            return(results);
        }
示例#6
0
        public static TimeSeries <ITimeSeriesItem <double> > LLV(this TimeSeries <ITimeSeriesItem <double> > ts, int num)
        {
            TimeSeries <ITimeSeriesItem <double> > results = new TimeSeries <ITimeSeriesItem <double> >();

            for (int i = num - 1; i < ts.Count; i++)
            {
                double min = double.MaxValue;
                for (int j = i - num + 1; j <= i; j++)
                {
                    if (min > ts[j].Value)
                    {
                        min = ts[j].Value;
                    }
                }
                TimeSeriesItem <double> item = new TimeSeriesItem <double>()
                {
                    Date  = ts[i].Date,
                    Value = min
                };
                results.Add(item);
            }
            return(results);
        }
示例#7
0
        public virtual ITimeSeries Zoomout(TimeUnit tu, DateTime begin, DateTime end)
        {
            Func <List <T>, T> merger = this.getElementMerger();

            if (merger == null)
            {
                return(null);
            }
            if (this.Count <= 0)
            {
                return(null);
            }
            if (begin < this[0].Date)
            {
                begin = this[0].Date;
            }
            if (end > this[this.Count - 1].Date)
            {
                end = this[this.Count - 1].Date;
            }

            List <T>       items  = new List <T>();
            TimeSeries <T> result = (TimeSeries <T>) this.GetType().GetConstructor(new Type[] { typeof(String), typeof(TimeUnit) }).Invoke(new Object[] { code, tu });

            /*
             * DateTime d = begin;
             * KeyValuePair<int, ITimeSeriesItem> kv = this.GetNearest(d);
             * if (kv.Value == null)
             *  return null;
             * int index = kv.Key;
             * while(index < this.Count)
             * {
             *  int n = CalendarUtils.TimeUnitGetSerialNo(this[index].Date,tu);
             *  if (n == 1)
             *      break;
             *  index += 1;
             * }
             *
             * DateTime[] dayRange = null;
             * for (int i=index;i<this.Count;i++)
             * {
             *  d = this[i].Date;
             *  if(dayRange == null)
             *      dayRange = CalendarUtils.TimeUnitRange(d, tu);
             *  if(d<=dayRange[1])
             *  {
             *      items.Add(this[i]);
             *      continue;
             *  }
             *  T newItem = merger(items);
             *  if (newItem != null)
             *      result.Add(newItem);
             *  dayRange = null;
             *
             * }
             */

            DateTime d = begin;

            while (d <= end)
            {
                DateTime[] dayRange = CalendarUtils.TimeUnitRange(d, tu); //找到d所在的周期的第一天
                KeyValuePair <int, ITimeSeriesItem> kvBegin = this.GetNearest(dayRange[0]);
                KeyValuePair <int, ITimeSeriesItem> kvEnd   = this.GetNearest(dayRange[1]);
                items.Clear();
                for (int i = kvBegin.Key; i <= kvEnd.Key; i++)
                {
                    items.Add(this[i]);
                }
                T newItem = merger(items);
                if (newItem != null)
                {
                    result.Add(newItem);
                }
                d = CalendarUtils.TimeUnitNextDate(d, tu);
            }

            return(result);
        }