写了一个工具分析基金回撤,分享实现过程 – 皇家救星

  近日有第一网友让我帮他写第一器剖析基金回撤局面,日前物品对比地忙就直没入手,赠送早晨宁愿时期,得出所预测的发生了一下。

先把赠送的得出所预测的发生成果分享:

  要剖析利率期货回撤,率先一定必须基金的净值变更知识。要抓知识一定是到天天基金网上抓,究竟别个是专业机构。

我找了一只人事栏对比地爱意的基金,易方达基金中小盘混合 (110011),在天天基金网站上一言可尽找到它的历史净值页:

  

  因在前抓过天天基金当天利率期货知识,实现它的页知识是藏在js外面,在阅读顺序逗留页后,实施js从维修服务静态获取再窗侧到阅读顺序。

  要实现是哪个js本子,方式有很多。我用的是谷歌阅读顺序自带的显影剂器,列举如下图:

  翻开显影剂器的局面下阅读利率期货页,就查看该页逗留的承认资源网址。知识对比地乱,不外关注的正确的js,因而按典型排了序。不外可以看摆脱逗留的js也不少,权时还不好地实现是哪第一js包括我要的知识。

  鉴于默许只显示了第编页码或张数知识,因而我就恣意点了其它页净值,从逗留的资源列表变更局面,一言可尽被发现的事物缺少的js网址,如图

  把这些带有callback的js网址拷下降,列举如下:

  从命令参量上猜想fundCode是基金信号,pageIndex是净值页编页码,其它参量权时不实现意思。

  先尝试运用大约网址在阅读顺序逗留看是啥局面:

  

  可以看出网站对大约js逗留做了把持,不准用户直接的在阅读顺序逗留。 鉴于到http抓包很少熟识,浊度这种局面下要怎样处置,总不大可能…必要写第一阅读顺序来抓第一js知识吧。

过后找了第一熟识抓包的助手顾及一下。顾及发生不远的将来再说,跟上面大约请关系到。

GET /f10/lsjz?callback=jQuery183018519977574130597_1558194911277&fundCode=110011&pageIndex=4&pageSize=20&startDate=&endDate=&_=1558195568400 HTTP/1.1
Host: api.fund.
Connection: keep-alive
User-Agent: Mozilla/ (Windows NT 10.0; Win64; x64) AppleWebKit/ (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/
Accept: */*
Referer: 
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9

   ———————————————–

  接上文,这是逗留利率期货页的http请教训头。小心外面的Referer。百度百科上是这么说的:HTTP Referer是header的一份,当阅读顺序向web维修服务发送请的时分,普通会带上Referer,告知维修服务双面碧昂丝从哪个页互连顺便来访的,维修服务基此可以获得稍许的通讯用于处置。

  喂天天基金网站执意用Referer来预先阻止他人盗链的。我直接的在阅读顺序输出js网址,发发出维修服务的请外面的Referer是空的,但以防是在网页上点击,则Referer是网页的网址。

  为了批准加法referer加法后条件能不变的逗留利率期货知识,我用curl做了第一实验:

curl "" --referer "" --user-agent "Mozilla/ (Windows NT 10.0; Win64; x64) AppleWebKit/ (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/" -o tmp.txt

  实验成,不变的获取到了净值。

  ———————————————–

  获取基金的方式找到了,接下降再看一下js网址:

  复杂猜想,这外面的fundCode是基金信号,pageIndex是页编号,pageSize是每页净值音量,startDate和endDate是净值日期区间,以防要获取某年级的学生的净值,可以运用

  pageIndex = 1,pageSize = 300, startDate = 2019-01-01,endDate = 2019-12-31,用curl再实验一下,猜想得对。

  接下降执意全力的活了,再写第一顺序传送获取每年净值,过后再停止剖析就可以。

  ———————————————–

看我剖析110011 易方达基金中小盘的发生

 

   可以看出易方达基金中小盘2008年头儿立,直到今天总进项是370%,也执意10年前把一万入伙该基金而且设置了分赃再值得买的东西,如今在理论上市值有3万7。

在这时期补进该基金,最惨的是在2015-08-19,从那天起基金延续下跌,直到2015-08-25才开端止跌,在这段时期内,总减幅试图贿赂15%。

最侥幸的是在2015-07-08补进基金的值得买的东西者,他们买了后基金就一向高涨,直到涨了20%才开端回调。

  当年易方达基金中小的业绩列举如下:

剖析起止日期:[2019-01-02,2019-06-06]
区间回撤/高涨率: [2019-01-02, 2019-06-06] [, 4.7011]
———————
最大延续回撤率: [2019-04-30, 2019-05-06] [403, ]
时期最大回撤率: [2019-04-10, 2019-05-09] [, ]
从起首时期算最大回撤率: [2019-01-02, 2019-01-03] [, ]
最大延续回撤天数率: 4 [2019-03-04, 2019-03-08] [, 0]
———————
最大延续高涨率: [2019-01-30, 2019-02-14] [, ]
时期最大高涨率: [2019-01-03, 2019-04-10] [, ]
从起首时期算最大高涨率: [2019-01-02, 2019-04-10] [, ]
最大延续高涨天数率: 6 [2019-01-30, 2019-02-14] [, ]

  当年基金还正确的,试图贿赂30%,最赚钱的时分是20190410,然后基金赚了41%

————————————————————-

  有兴趣的同窗可以到喂下载我大约小器:

互连: 使滴下码: zg97 抄写这段愿意的后翻开百度网盘蜂窝式便携无线电话App,手感更便于使用的哦

————————————————————-

相干信号(写得对比地简陋的,因忆起少量的写少量的,不久以后有时期再思索最优化)

#pragma once

#include ""
#include 
#include 
typedef struct __tagNetValueInfo{
    string strNetValueDate;
    double dAccumulatedNet;

    __tagNetValueInfo()
    {
        dAccumulatedNet = 0;
    }

    __tagNetValueInfo(conststring& v1, double v2)
    {
        strNetValueDate = v1;
        dAccumulatedNet = v2;
    }
}NetValueInfo;

typedef struct __StatisticalNetValueInfo{
    string strValue;
    string strNode;
    string strBegDate;
    double dBegNetValue;
    string strEndDate;
    double dEndNetValue;

    __StatisticalNetValueInfo()
    {
        dBegNetValue = dEndNetValue = 0;
        strBegDate = strEndDate = "-";
    }

    string getString()
    {
        string strRet;
        char buf[1024];
        size_t nStrNodeLen = () + 1;
        string strPad = "";
        for (size_t i = nStrNodeLen / 8; i < 3; ++i)
        {
            strPad += "\t";
        }
        _snprintf(buf, sizeof(buf), "%s:%s%s\t",
            (), (), ());
        strRet += buf;

        _snprintf(buf, sizeof(buf), "[%s,%s]\t",
            (), ());
        strRet += buf;

        _snprintf(buf, sizeof(buf), "[%04f,%04f]\n",
            dBegNetValue, dEndNetValue);
        strRet += buf;

        return strRet;
    }

    void print()
    {
        size_t nStrNodeLen = () + 1;
        string strPad = "";
        for (size_t i = nStrNodeLen / 8; i < 3; ++i)
        {
            strPad += "\t";
        }
        cout << strNode << ":" << strPad << strValue << "\t";// << endl;
        cout << "[" << strBegDate << ", " << strEndDate << "]\t";// << endl;
        (''0'');
        cout << "[" << fixed << setprecision(4) << dBegNetValue 
            << ", "  << fixed << setprecision(4) << dEndNetValue 
            << "]" << endl;
    }
}StatisticalNetValueInfo;

typedef struct __tagResultInfo{
    //最大延续回撤率/高涨率通讯    StatisticalNetValueInfo resMaxContinRetraceInfo;
    StatisticalNetValueInfo resMaxContinRiseInfo;

    //最大延续回撤天数/高涨天数通讯    StatisticalNetValueInfo resMaxContinRetraceDaysInfo;
    StatisticalNetValueInfo resMaxContinRiseDaysInfo;

    //最大回撤率/高涨率通讯    StatisticalNetValueInfo resMaxRetraceInfo;
    StatisticalNetValueInfo resMaxRiseInfo;

    //从起首时期算最大回撤率/高涨率通讯    StatisticalNetValueInfo resMaxRetraceFromBeginInfo;
    StatisticalNetValueInfo resMaxRiseFromBeginInfo;


    //从起首时期算回撤率/高涨率通讯    StatisticalNetValueInfo resRetraceRiseFromBeginInfo;

    __tagResultInfo()
    {
        resMaxContinRetraceInfo.strNode = "最大延续回撤率";
        resMaxContinRetraceDaysInfo.strNode = "最大延续回撤天数率";
        resMaxRetraceInfo.strNode = "时期最大回撤率";
        resMaxRetraceFromBeginInfo.strNode = "从起首时期算最大回撤率";
        resMaxContinRiseInfo.strNode = "最大延续高涨率";
        resMaxContinRiseDaysInfo.strNode = "最大延续高涨天数率";
        resMaxRiseInfo.strNode = "时期最大高涨率";
        resMaxRiseFromBeginInfo.strNode = "从起首时期算最大高涨率";

        resRetraceRiseFromBeginInfo.strNode = "区间回撤/高涨率";
    }

    string getString()
    {
        string strRet;
        strRet += ();
        strRet += "---------------------\n";
        strRet += ();
        strRet += ();
        strRet += ();
        strRet += ();
        strRet += "---------------------\n";
        strRet += ();
        strRet += ();
        strRet += ();
        strRet += ();

        return strRet;
    }

    void print()
    {
        ();
        cout << "---------------------" << endl;
        ();
        ();
        ();
        ();
        cout << "---------------------" << endl;
        ();
        ();
        ();
        ();
    }
}ResultInfo;

int getRectracement(const vector &vecNetValueInfo, size_t nBegPos, size_t nEndPos,
    OUT ResultInfo& resultInfo);

void testGetRectracement();
//  : 规范体系包括公文的包括公文,
// 猜想常常运用但罕见更改的
// 特定于物品的包括公文
//
#pragma once


#define WIN32_LEAN_AND_MEAN        // 从 Windows 头中距离极少运用的材料
#include 
#include 



// TODO: 在此处援用顺序必要的等等头公文
#include 
#include <string>
#include 
#include 
usingnamespace std;
#include 
#include 

#define itoa _itoa


conststring& stringReplace(string& str, conststring& strToReplace, conststring& strReplaceTo);
char *stringReplace(char *str, constchar *strToReplace, constchar *strReplaceTo);

// UTF8编码替换到GBK编码int UTF8ToGBK(constchar *lpUTF8Str, char *lpGBKStr,int nGBKStrLen);
//GBK编码替换到UTF8编码int GBKToUTF8(constchar *lpGBKStr, char *lpUTF8Str, int nUTF8StrLen);


enum URL_TYPE{unkowurl, eastmoney, howbuy, fund123, jjmmw, qq};

getFundNetValue.cpp

// getFundNetValue.cpp : 下定义把持台应用顺序的进入权点。
//

#include
""
#include

#include
<string>
#include


#include

#include

#include
""usingnamespace std;

URL_TYPE getUrlType(conststring& url)
{
string urlLower = url;
transform((), (), (), ::tolower);
if (("") != string::npos || url.find("") != string::npos )
{
return eastmoney;
}
elseif (("") != string::npos)
{
return howbuy;
}
elseif (("") != string::npos)
{
return fund123;
}
elseif (("") != string::npos)
{
return jjmmw;
}
elseif (("") != string::npos)
{
return qq;
}
else
{
return unkowurl;
}
}

size_t splitToVector(constchar *src, constchar *separator, vector<string>& vecOut)
{
constchar *pFound, *pBegin = src;
const size_t nSeparatorLen = strlen(separator);

();

while ( NULL != (pFound = strstr(pBegin, separator)) )
{
(
string(pBegin, pFound));
pBegin
= pFound + nSeparatorLen;
}

if (*pBegin != ''\0'')
{
(pBegin);
}

return vecOut.size();
}

void removeCharHeadTail(string& str, constchar trimChr)
{
size_t begPos
= 0;
size_t endPos
= string::npos;
size_t nStrLen
= ();