.NET 夏普比率,波动率的公式讲解和代码实现运算

.NET中实现金融股票的一些简单算法(精简处理)(波动率,收益率,年化,夏普比率等算法简化)

最近接手一个关于股票的系统,显示端需要显示一些庞大且可分析性的比率数据,其中就用到了一些简单且实用的算法(标题中的各个公式,不论是书上还是其他朋友总结出来总会有一些出入,这里只参考工作日情况**非自然日算式方式 **)

这个算法普伦是夏普或者波动都和不同的场景有一些出入,根据个人的实际情况,可以进行适当修改

首先,公式中有用到西格玛(∑,σ)前者大写,后者小写,和sqrt
不了解西格玛的同学可以先了解一下这个的基本知识

σ:小写σ是希腊字母,英文表达sigma,汉语译音为“西格玛”。术语σ用来描述任一过zhi程参数的平均值的分布dao或离散程度;σ(n)表示整数n的所有正因数的和。

对商务或制造过程而言,σ值可以测量过程完成无缺陷作业的能力,是指示过程作业状况良好程度的标尺。σ值越低,则过程状况越好

:大写∑用于数学上的总和符号du,比如:∑Pi,其中i=1,2,…,T,即为求P1 + P2 + … + PT的和。zhi

求和符号∑是希腊dao字母西格玛的大写,表示将它右边的所有数,这里是1/n2,加在一起。∑下面的“n=1”表示我们从n=1开始加起,而根据惯例,n是依次增加的正整数。

项目中用到的正是∑的含义:动态上下标和access数值的迭代产生的结果;通俗理解(有限迭代算法)

下面展示用到的原公式(我把公式拆成一个个小部分来封装,更便于理解和阅读,其实是存在嵌套关系的):

年化利率(工作日为基准)
年化利率
最大回撤率
最大回撤率
夏普比率(与波动率紧连)
夏普比率
波动率
波动率
下面展示本人封装的方法和简化后的计算方法(实际数据测试ed)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Pro_Tools
{
    public class Data_Algorithm
    {
        public int Round { get; set; }
        public Data_Algorithm()
        {
            Round = 0;
        }
        /// <summary>
        /// 声明一个∑西格玛计算委托
        /// </summary>
        /// <param name="up">上标</param>
        /// <param name="down">下标</param>
        /// <param name="access">待处理的基数</param>
        /// <returns></returns>
        public delegate decimal DoMath(int up, int down, decimal access);

        /// <summary>
        /// 声明一等待执行委托
        /// </summary>
        /// <param name="function">方法名称</param>
        /// <param name="up">上标</param>
        /// <param name="down">下标</param>
        /// <param name="access">待处理的基数</param>
        /// <returns></returns>
        public decimal DoMaths(DoMath function, int up, int down, decimal access) => function(up, down, access);

        /// <summary>
        /// 计算收益
        /// </summary>
        /// <param name="SellUnitPrice">卖出单价</param>
        /// <param name="SellCount">卖出数量</param>
        /// <param name="BuyUnitPrice">买入单价</param>
        /// <param name="BuyCount">买入数量</param>
        /// <returns></returns>
        public decimal Profit(decimal SellUnitPrice, decimal SellCount, decimal BuyUnitPrice, decimal BuyCount)
        {
            decimal end = SellUnitPrice * SellCount;//最终总价值
            decimal start = BuyCount * BuyUnitPrice;//最初总价值
            decimal result = end - start;
            return result;
        }

        /// <summary>
        /// 计算收益率
        /// </summary>
        /// <param name="SellUnitPrice">卖出单价</param>
        /// <param name="SellCount">卖出数量</param>
        /// <param name="BuyUnitPrice">买入单价</param>
        /// <param name="BuyCount">买入数量</param>
        /// <returns></returns>
        public decimal Yield(decimal SellUnitPrice, decimal SellCount, decimal BuyUnitPrice, decimal BuyCount)
        {
            decimal end = SellUnitPrice * SellCount;//最终总价值
            decimal start = BuyCount * BuyUnitPrice;//最初总价值
            decimal result = (end - start) / start;//做出收益率
            return result;
        }

        /// <summary>
        /// 年化收益
        /// </summary>
        /// <param name="P">收益率</param>
        /// <param name="EntDays">执行天数</param>
        /// <returns></returns>
        public decimal AnnualizedIncome(decimal P, int EntDays)
        {
            decimal TheFla = (1 + P);
            try
            {
                decimal AnnualizedIncomes = Convert.ToInt32(Math.Pow(Convert.ToDouble(TheFla), 250 / EntDays) - 1);///该处可能损失浮点,但是不会导致异常或报错!!!
                return AnnualizedIncomes;
            }
            catch (Exception ex)
            {
                return 0m;///表示异常,溢出
                throw;
            }
        }

        /// <summary>
        /// 计算夏普比率
        /// </summary>
        /// <param name="Rp">收益率</param>
        /// <param name="Rf">无风险利率(有默认值)</param>
        /// <param name="σp">策略收益波动率</param>
        /// <returns></returns>
        public decimal Sharpe_Ratio(decimal Rp, decimal σp, decimal Rf = 0.04m)
        {
            decimal result = (Rp - Rf) / σp;
            return Math.Round(result,2);
        }

        /// <summary>
        /// 计算策略收益波动率 σp
        /// </summary>
        /// <param name="Rp">收益率</param>
        /// <param name="Rpav">策略收益率的平均值</param>
        /// <param name="EnterDays">执行天数</param>
        /// <returns></returns>
        public decimal Volatility(decimal Rp, decimal Rpav, int EnterDays)
        {
            decimal FirstData = Convert.ToDecimal(Math.Pow(Convert.ToDouble((Rp - Rpav)), 2));///该处计算可能算是浮点,但是不会报错或抛出异常!!!
            //decimal SecondData = SigmaAddition(EnterDays, 1, FirstData);///迭代算式1
            decimal SecondData = DoMaths(SigmaAddition, EnterDays, 1, FirstData);///迭代算式2
            decimal ThirdData = SecondData * (250 / EnterDays - 1);
            decimal result = Convert.ToDecimal(Math.Sqrt(Convert.ToDouble(ThirdData)));///该处可能丢失浮点,但是不会报错或者抛出异常!!!
            return result;
        }

        /// <summary>
        /// 策略收益率的平均值(包含数乘性)
        /// </summary>
        /// <param name="SubScript">∑西格玛下标(公式里的i,这里改为动态下标)</param>
        /// <param name="Rp">收益率</param>
        /// <param name="EnterDays">执行天数(∑上标)</param>
        /// <returns></returns>
        public decimal The_Average_Daily_Return_Of_The_Strategy(int SubScript, decimal Rp, int EnterDays)
        {
            Data_Algorithm Da = new Data_Algorithm();
            decimal result = 0;

            //for (int i = SubScript; i <= EnterDays; i++)
            //{
            //    result += Rp * i;
            //}///∑西格玛运算

            result += DoMaths(SigmaMultiplication, SubScript, EnterDays, Rp);///迭代计算
            result = result * (1 / EnterDays);//平均值
            return result;
        }

        /// <summary>
        /// 最大回撤率
        /// </summary>
        /// <param name="Px">过去式(策略某日股票和现金总价值)</param>
        /// <param name="Py">现在或将来(策略某日股票和现金总价值)</param>
        /// <returns></returns>
        public decimal Max_DrowDown(decimal Px, decimal Py) => (Px - Py) / Px;

        /// <summary>
        /// 西格玛连加计算(不含数乘)
        /// </summary>
        /// <param name="up">上标</param>
        /// <param name="down">下标</param>
        /// <param name="access">待处理的基数</param>
        /// <returns></returns>
        private decimal SigmaAddition(int up, int down, decimal access)
        {
            decimal result = 0;
            for (int i = down; i <= up; i++)
            {
                result += access;
            }
            return result;
        }

        /// <summary>
        /// 西格玛加乘混合计算
        /// </summary>
        /// <param name="up">上标</param>
        /// <param name="down">下标</param>
        /// <param name="access">待处理的基数</param>
        /// <returns></returns>
        private decimal SigmaMultiplication(int up, int down, decimal access)
        {
            decimal result = 0;
            for (int i = down; i < up; i++)
            {
                result += access * i;
            }
            return result;
        }

        /// <summary>
        /// 胜率
        /// </summary>
        /// <param name="Number_Of_Profitable_Transactions">盈利交易次数</param>
        /// <param name="Number_Of_Transactions">总交易次数</param>
        /// <returns></returns>
        public decimal Winning_Probability(int Number_Of_Profitable_Transactions, int Number_Of_Transactions) => Number_Of_Profitable_Transactions / Number_Of_Transactions;
    }
}

好,以上就是最简单的几个基本算法和代码逻辑的部分实现过程,作为本人算法的进步记录和经验分享

如有不足请同志积极指正,共同学习!

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值