指数波段划分以及底部反弹行业特征统计分析

article/2025/9/27 19:36:31

本文参考国金证券杨勇博士最近发的研报《底部反弹特征统计分析》,在优矿网做一个分析实现。

首先是作出指数的波段划分图,用以确定指数的各个底部。

1
import numpy as np
2
import pandas as pd

我写了如下一个函数,可以用于划出各个指数的波段图,虽然写的有点繁琐,但毕竟是可以用。当然我们划出的波段图不仅可以用来找寻顶部、底部。更是可以进一步用来做技术分析,例如波浪理论、缠轮等等。我有关注杨勇老师微信的公众号,其对大盘指数的预测还是非常精准的,用到的也主要是波浪理论、缠轮等。

1
def wave_division(indexid = u"000001.ZICN",begindate = u"20050104", enddate = u"20160530",up_range = 1.2,down_range = 0.85):
2
    
3
    index = DataAPI.MktIdxdGet(indexID=indexid,beginDate=begindate,endDate=enddate,field=u"tradeDate,lowestIndex,highestIndex",pandas="1")
4
    index = index.set_index(['tradeDate'])
5
    date_flex = [0]
6
    inflexion_flag_high = index.iloc[0]['highestIndex']
7
    inflexion_flag_low = index.iloc[0]['lowestIndex']
8
    m = 0
9
    k = 0
10
    for i in range(len(index)):
11
        #print i,m,k
12
        if i > m  and i > k:
13
            if index.iloc[i]['highestIndex'] / inflexion_flag_low > up_range:
14
                k = i
15
                for j in range(i+1,len(index)):
16
                    #print j,k
17
                    if index.iloc[j]['highestIndex'] > index.iloc[k]['highestIndex']:
18
                        k = j
19
                    elif index.iloc[j]['lowestIndex'] / index.iloc[k]['highestIndex'] < down_range and k != j:
20
                        date_flex.append(k)
21
                        break
22
23
            elif index.iloc[i]['lowestIndex'] / inflexion_flag_high < down_range:
24
                m = i
25
                for n in range(i+1,len(index)):
26
                    #print n,m
27
                    if index.iloc[n]['lowestIndex'] < index.iloc[m]['lowestIndex']:
28
                        m = n 
29
                    elif index.iloc[n]['highestIndex'] / index.iloc[m]['lowestIndex'] > up_range and m !=n:
30
                        date_flex.append(m)
31
                        break
32
        else:
33
            pass
34
35
        if len(date_flex) > 0:
36
            inflexion_flag_low = index.iloc[max(date_flex)]['lowestIndex']
37
            inflexion_flag_high = index.iloc[max(date_flex)]['highestIndex']
38
            
39
    #print i,inflexion_flag_low,inflexion_flag_high
40
    
41
    date_flex.sort()
42
    index['inflexion'] = np.nan
43
     
44
    if index.iloc[date_flex[1]].mean() > index.iloc[date_flex[0]].mean():
45
        for i in range(len(date_flex)):
46
            if i % 2 == 0:
47
                index['inflexion'].iloc[date_flex[i]] = index.iloc[date_flex[i]]['lowestIndex']
48
            else:
49
                index['inflexion'].iloc[date_flex[i]] = index.iloc[date_flex[i]]['highestIndex']
50
                
51
    else:
52
        for i in range(len(date_flex)):
53
            if i % 2 == 0:
54
                index['inflexion'].iloc[date_flex[i]] = index.iloc[date_flex[i]]['highestIndex']
55
            else:
56
                index['inflexion'].iloc[date_flex[i]] = index.iloc[date_flex[i]]['lowestIndex']
57
58
        
59
    for i in range(len(index)):
60
        for j in range(len(date_flex)-1):
61
            if i <= date_flex[j+1] and i >= date_flex[j]:
62
                slope = (index['inflexion'].iloc[date_flex[j+1]] - index['inflexion'].iloc[date_flex[j]]) / (date_flex[j+1] - date_flex[j])
63
                index['inflexion'].iloc[i] = slope * (i-date_flex[j]) + index['inflexion'].iloc[date_flex[j]] 
64
                
65
    return date_flex,index

1
date_flex,cyindex = wave_division(indexid = u"399006.ZICN",begindate = u"20100101", enddate = u"20160530",up_range = 1.1,down_range = 0.92)

1
cyindex.plot(figsize=(20,9),linewidth=2)

1
date_flex,shindex = wave_division()

1
shindex.plot(figsize=(16,9),linewidth=2)

<matplotlib.axes._subplots.AxesSubplot at 0x6252150>

因为波段图就是一个底部一个顶部相交互,我们筛选出底部的时间点与指数低点

1
shindex.iloc[[date_flex[i] for i in range(1,len(date_flex),2)]]

 lowestIndexhighestIndexinflexion
tradeDate   
2005-06-06998.2281034.853998.228
2007-02-062541.5252677.0422541.525
2007-06-053404.1463768.5633404.146
2007-07-063563.5443785.3463563.544
2008-04-222990.7883148.7312990.788
2008-09-181802.3311942.8461802.331
2008-10-281664.9251786.4351664.925
2009-03-032037.0242088.6282037.024
2009-09-012639.7592727.0772639.759
2010-07-022319.7392386.4002319.739
2012-12-041949.4571980.1191949.457
2013-06-251849.6531963.5661849.653
2015-07-093373.5403748.4793373.540
2015-08-262850.7143092.0412850.714

可以看出与研报中的结果相比,少了2016-01-27这个底部,因为实际上从2016-01-27的2638.3的底部至今没有涨幅超过20%的时候,最多的时候是17%。但没有关系我们还是加上去一起统计。

1
#shindex.iloc[2688].name
2
date_flex.append(2688)
3
shindex.iloc[2688]['inflexion'] = 2638.302

1
shindex.iloc[[date_flex[i] for i in range(1,len(date_flex),2)]]

 lowestIndexhighestIndexinflexion
tradeDate   
2005-06-06998.2281034.853998.228
2007-02-062541.5252677.0422541.525
2007-06-053404.1463768.5633404.146
2007-07-063563.5443785.3463563.544
2008-04-222990.7883148.7312990.788
2008-09-181802.3311942.8461802.331
2008-10-281664.9251786.4351664.925
2009-03-032037.0242088.6282037.024
2009-09-012639.7592727.0772639.759
2010-07-022319.7392386.4002319.739
2012-12-041949.4571980.1191949.457
2013-06-251849.6531963.5661849.653
2015-07-093373.5403748.4793373.540
2015-08-262850.7143092.0412850.714
2016-01-272638.3022768.7722638.302
1
bottom_index = shindex.iloc[[date_flex[i] for i in range(1,len(date_flex),2)]]['inflexion']
2
bottom_static = {}
3
for i in range(1,len(date_flex),2):
4
    try:
5
        bottom_static[shindex.iloc[date_flex[i]].name] = [shindex.iloc[date_flex[i+1]]['inflexion'] / shindex.iloc[date_flex[i]]['inflexion'] - 1,date_flex[i+1] - date_flex[i]]
6
    except:
7
        print shindex.iloc[date_flex[i]].name,shindex.iloc[date_flex[i]]['inflexion'],'最后一个底部其反弹多少还不能确定'

2016-01-27
2638.302 最后一个底部其反弹多少还不能确
1
bottom_static = pd.DataFrame(bottom_static).T
2
bottom_static = pd.concat([bottom_index,bottom_static],axis=1)
3
bottom_static = bottom_static.rename(columns={'inflexion':'指数低点',0:'反弹幅度',1:'反弹时间长度'})

1
bottom_static

 指数低点反弹幅度反弹时间长度
2005-06-06998.2281.999597400
2007-02-062541.5250.70604870
2007-06-053404.1460.26669011
2007-07-063563.5440.71852667
2008-04-222990.7880.2658958
2008-09-181802.3310.2945895
2008-10-281664.9250.44319273
2009-03-032037.0240.707398106
2009-09-012639.7590.27336954
2010-07-022319.7390.37374186
2012-12-041949.4570.25409546
2013-06-251849.6531.799547481
2015-07-093373.5400.24037311
2015-08-262850.7140.29250778
2016-01-272638.302NaNNaN

恩,统计的结果和杨勇老师的一模一样呢。接下来我们探索以下底部行业超额收益的情况。

1
from CAL.PyCAL import *
2
import matplotlib.pyplot as plt
3
cal = Calendar('China.SSE')
4
cal.removeHoliday(Date(2007,4,4)) #cal里面的一个小错误,20070404是一个交易日

1
def net_ind_cumret(date_list,indContent):
2
    
3
    time_list = [[cal.advanceDate(date_list[i], '-20B', BizDayConvention.Unadjusted),cal.advanceDate(date_list[i], '40B', BizDayConvention.Unadjusted)] for i in range(len(for_ind_static))] #得到每个底部日的前20个交易日与后40个交易日
4
    
5
    #print time_list
6
    #初始化avg_ind_cumret(行业平均累计收益率)
7
    avg_ind_cumret = {}
8
    for ind in indContent.keys():
9
        avg_ind_cumret[ind] = 0
10
    
11
    
12
    for i in range(1,len(time_list)): #因为DataAPI.EquRetudGet的数据从06年才开始,故我们不算第一个底部情况,当然也可以使用日线数据直接计算日收益率,此处就不算了
13
    
14
        index_ret = DataAPI.MktIdxdGet(indexID=u"000001.ZICN",beginDate=time_list[i][0].strftime('%Y%m%d'),endDate=time_list[i][1].strftime('%Y%m%d'),field=['tradeDate','preCloseIndex','closeIndex'],pandas="1")
15
        index_ret['return'] = (index_ret['closeIndex'] - index_ret['preCloseIndex']) / index_ret['preCloseIndex']
16
        #index_cumret = np.array((1 + index_ret['return']).cumprod()) #底部交易日附近指数的累计收益率
17
18
        ind_ret = {}
19
        ind_cumret = []
20
        
21
        for ind in indContent:
22
23
            df_ret = DataAPI.EquRetudGet(listStatusCD='L',secID=indContent[ind],beginDate=time_list[i][0].strftime('%Y%m%d'),endDate=time_list[i][1].strftime('%Y%m%d'),field=['secID','tradeDate','dailyReturnReinv'],pandas="1") #得到行业每日收益率
24
            df_marketValue = DataAPI.MktEqudGet(secID=indContent[ind],beginDate=time_list[i][0].strftime('%Y%m%d'),endDate=time_list[i][1].strftime('%Y%m%d'),field=['secID','tradeDate','negMarketValue'],pandas="1")
25
            ##计算行业内指数加权日收益率
26
            df_ret = df_ret.set_index(['tradeDate','secID'])
27
            df_marketValue = df_marketValue.set_index(['tradeDate','secID'])
28
            ind_ret[ind] = (df_ret.unstack() * (df_marketValue.unstack()['negMarketValue'].T / df_marketValue.unstack().sum(axis=1)).T).sum(axis=1) #不想写循环,运用DataFrame的特性
29
            #print ind_ret[ind]
30
            
31
            for j in range(0,20,5):
32
                ind_cumret.append((1 + ind_ret[ind].iloc[j:20]).prod() - (1 + index_ret['return'].iloc[j:20]).prod())
33
            for j in range(25,61,5):
34
                ind_cumret.append((1 + ind_ret[ind].iloc[20:j]).prod() - (1 + index_ret['return'].iloc[20:j]).prod())
35
            
36
            avg_ind_cumret[ind] = avg_ind_cumret[ind] + np.array(ind_cumret)
37
            
38
            ind_cumret = []
39
            #print avg_ind_cumret
40
            
41
    for key in avg_ind_cumret:
42
        avg_ind_cumret[key] = avg_ind_cumret[key] / (len(time_list) - 1)
43
        
44
    return avg_ind_cumret

1
def industryGet(tradeDate):             # 设置行业
2
    trade_date = tradeDate
3
    df = DataAPI.EquIndustryGet(industryVersionCD=u"010303",secID = set_universe('HS300',date=trade_date.strftime('%Y%m%d')),intoDate=trade_date.strftime('%Y%m%d'),field=['secID','industryName1','industryName2'])
4
    ind1 = df[df['secID'] == '600000.XSHG']['industryName1'].values[0]
5
    ind2 = df[df['secID'] == '600030.XSHG']['industryName1'].values[0]
6
    industry = df['industryName1'].drop_duplicates().tolist()
7
    if ind1 == ind2 :
8
        industry.remove(ind1)
9
    else:
10
        industry.remove(ind1)
11
        industry.remove(ind2)
12
        
13
    industry = industry + ['银行','证券','保险','多元金融']
14
    return industry
15
16
industry = industryGet(Date(2016,5,26))
17
stkIndustry = DataAPI.EquIndustryGet(industryVersionCD=u"010303",secID = set_universe('A'),intoDate='20160526',field=['secID','industryName1','industryName2'],pandas="1")
18
indContent = {}
19
for ind_name in industry:
20
    indContent[ind_name] = stkIndustry[(stkIndustry['industryName1']==ind_name) | (stkIndustry['industryName2']==ind_name)]['secID'].tolist()

1
avg_ind_cumret = net_ind_cumret(bottom_static[bottom_static['反弹时间长度']>5].index,indContent)

1
index = range(-20,41,5)
2
index.remove(0)
3
avg_ind_cumret = pd.DataFrame(avg_ind_cumret,index=index)

得到底部左右超额收益的相关系数,与研报的结论基本一致,行业超额收益反转的现象,过去超额收益率越高的行业,在底部之后的10个交易日之后将收益率越低。

其中-20表示[-20,0]的超额收益,5表示[0,5]的超额收益

1
avg_ind_cumret.T.corr()

index-20-15-10-5510152025303540
index            
-201.0000000.7943230.7358180.7365150.284202-0.244573-0.210857-0.299900-0.163276-0.219598-0.195432-0.201444
-150.7943231.0000000.9557180.8211110.135788-0.348093-0.307521-0.331221-0.197013-0.314560-0.329344-0.312431
-100.7358180.9557181.0000000.8524370.020425-0.463183-0.430745-0.435674-0.308467-0.425406-0.414646-0.404961
-50.7365150.8211110.8524371.0000000.050341-0.550097-0.594889-0.630819-0.564937-0.634865-0.606732-0.560034
50.2842020.1357880.0204250.0503411.0000000.5431610.3336310.2231080.1477770.1019480.2187130.233550
10-0.244573-0.348093-0.463183-0.5500970.5431611.0000000.8724290.7873820.6678750.6959690.7141060.719874
15-0.210857-0.307521-0.430745-0.5948890.3336310.8724291.0000000.9370920.8836340.9069570.8874500.890454
20-0.299900-0.331221-0.435674-0.6308190.2231080.7873820.9370921.0000000.9178930.8973380.8843000.875722
25-0.163276-0.197013-0.308467-0.5649370.1477770.6678750.8836340.9178931.0000000.9607220.9296740.902757
30-0.219598-0.314560-0.425406-0.6348650.1019480.6959690.9069570.8973380.9607221.0000000.9443500.912436
35-0.195432-0.329344-0.414646-0.6067320.2187130.7141060.8874500.8843000.9296740.9443501.0000000.982007
40-0.201444-0.312431-0.404961-0.5600340.2335500.7198740.8904540.8757220.9027570.9124360.9820071.000000
1
plt.figure(figsize=(20,15))
2
for x in avg_ind_cumret.columns:
3
    plt.plot(avg_ind_cumret.index, avg_ind_cumret[x])
4
# plt.plot(avg_ind_cumret)
5
plt.legend([e.decode('utf-8') for e in avg_ind_cumret.columns],loc='upper left',prop = font)

<matplotlib.legend.Legend at 0x109946d0>

结果与研报的有所不同,可能是行业收益率的计算方式不同,以及我舍去了第一个底部的数据。

我们看下处于反弹时,我们分析结果推荐的行业

1
avg_ind_cumret.ix[5].order(ascending=False).head(5)
房地产 0.025092保险 0.024473证券 0.023604银行 0.021189国防军工 0.016889Name: 5, dtype: float6

4
1
avg_ind_cumret.ix[10].order(ascending=False).head(5)
多元金融 0.058046国防军工 0.043713房地产 0.042585建筑材料 0.040470有色金属 0.039688Name: 10, dtype: float6

4
1
avg_ind_cumret.ix[20].order(ascending=False).head(5)
建筑材料 0.093642房地产 0.081750有色金属 0.076970多元金融 0.065906电气设备 0.065045Name: 20, dtype: float6

4
1
avg_ind_cumret.ix[30].order(ascending=False).head(5)
电气设备 0.140919有色金属 0.127539房地产 0.119225国防军工 0.116397建筑材料 0.108876Name: 30, dtype: float6

4
1
avg_ind_cumret.ix[40].order(ascending=False).head(5)
有色金属 0.148778电气设备 0.137068建筑材料 0.124374房地产 0.117752汽车 0.113629Name: 40, dtype: float6

4

总结一下

反弹的带头大哥都是银行、保险、证券和房地产等行业,但往后走银行等金融行业的收益率在不断下降,而房地产仍能保持不错的收益率。反弹多天后推荐的行业是有色金属、电气设备、建筑材料、汽车等。


http://chatgpt.dhexx.cn/article/51vvZBx9.shtml

相关文章

频谱和波段划分

光是一种电磁波。 可见光&#xff1a;由光源发出的辐射能中的一部分&#xff0c;即能产生视觉的辐射能&#xff0e;常被称作为“可见光”。 可见光的波长&#xff1a;从380nm----780nm 紫外线的波长&#xff1a;从100nm---380nm&#xff0c;肉眼看不见。 红外线的波长&#xff…

电磁波频谱 和 波段划分以及名称由来(收集)

电磁波频谱和波段划分 段号 频段名称 频段范围 &#xff08;含上限&#xff0c;不含下限&#xff09; 波段名称 波长范围 &#xff08;含上限&#xff0c;不含下限&#xff09; 1 极低频(ELF) 3&#xff5e;30赫&#xff08;Hz&#xff09; 极长波 100&#xff5e;10兆米 2 超低…

【图像处理】多光谱 波长波段划分 主要波段特性 植被遥感原理 典型植被指数

他们仅仅看到自我的影子&#xff0c;他们的影子就是他们的法律。太阳对他们来说&#xff0c;只是个投影者。 文章目录 前言 前言 本文记录多光谱波段划分&#xff0c;主要波段特性&#xff0c;植被遥感原理&#xff0c;典型植被指数。 资料参考&#xff1a; 冈萨雷斯-数字图像…

通信原理 | 波段的划分

波段(wave band) 在无线电技术中,波段(wave band)这个名词具有两种含义。 电磁波频谱的划分,例如长波、短波、超短波等波段。 发射机、接收机等设备的工作频率范围的划分。若把工作频率范围分成几个部分,这些部分也称为波段,例如三波段收音机等。 波段划分 波段通常是…

手机 Python 编程神器!

点击上方“逆锋起笔”&#xff0c;公众号回复 编程资源 领取大佬们推荐的学习资料来源&#xff1a;软件测评说 手机编程软件有很多&#xff0c;大部分都很难使用&#xff0c;操作不灵活&#xff0c;甚至不能安装第三方库。 尝试安装了很多Python移动编程软件&#xff0c;发现了…

你知道用手机也能写软件吗?手机编程开发

手机编程开发 除了我们常见的php&#xff0c;java&#xff0c;c&#xff0c;前后端等等等用电脑来编写程序的&#xff0c;还有可以用手机编写软件的 用手机来开发软件 既然是在手机上开发编写软件那么肯定也少不了工具&#xff0c;这篇文章就给大家分享几个手机编程开发的工具…

PLC编程安卓版 兼容三菱FX PLC编程指令 软件在线仿真 硬件PLC工控板蓝牙与手机蓝牙在线下载程序 在线仿真

硬件连接1 APP功能描述 2 APP下载与安装注册 3 APP介面操作 3.1 主介面介绍 3.2 状态栏 3.3 工件区 3.4 工具栏 3.5 转换成上位机GX Works2文件 APP下载地址&#xff1a;https://www.pgyer.com/RziG 硬件连接 . 硬件连接&#xff08;注&#xff1a;目前测试的蓝牙模块…

AIDE手机编程初级教程(零基础向)导航

AIDE手机编程初级教程&#xff08;零基础向&#xff09;导航 引入 第一章 第一个应用 1.1 认识我的第一个应用 1.2 初识界面编程 第二章 第一个游戏 序言 2.1 Java基础一 你好 2.1.1 上篇 2.1.2 下篇 2.2 Java基础二 简单计算器 2.3 Java基础…

python可以编程手机版_手机最强Python编程神器,在手机上运行Python

手机编程软件有很多,大部分都很难使用,操作不灵活,甚至不能安装第三方库。 尝试安装了很多Python移动编程软件,发现了很多问题,不是编码效率低就是各种bug。今天,来自一位python编程小哥指导,向大家推荐两款精心挑选的手机编程软件,它们也是非常成熟的手机编程工具。 Q…

简单好玩的手机编程代码

想学编程没有电脑?手机也能编程!为了让大家在任何时候都可以进行编程,这次给大家推荐四款手机编程APP,让你不论在何时何地都可以化身码农。甚至暂时没有电脑,但是又想 Java:AIDE集成开发环境AIDE集成开发环境可以直接编译运行Java代码,同时还可以编写简单的安卓程序,支持自动补…

手机编程该用什么输入法?

工欲善其事&#xff0c;必先利其器&#xff01; 在开始正式编程之前&#xff0c;舞剑有必要说一说输入法/键盘的注意事项。 市面上大多数的输入法都是为了适应国人习惯的输入法&#xff0c;九宫格、二十六键……数字与各种半角符号都隐藏在深处&#xff0c;切换起来非常不方便。…

AIDE手机编程初级教程(零基础向) 1.2 初识界面编程

第一章 第一个应用 系列教程导航 1.2 初识界面编程 文章目录 为什么讲解后记 为什么 对于一个Android应用来说&#xff0c;一个好看的界面是非常重要的。在上一篇文章&#xff0c;你已经学会了自定义我们的第一个应用中间的文字。但是这还不够&#xff0c;因为我们平常见到的…

如何用手机编程Python?

如何用手机编程Python&#xff1f;&#xff0c;这里再总结一下&#xff0c;以安卓手机为例&#xff0c;有2种方法&#xff0c;一种是安装QPython3&#xff0c;一种是安装Termux&#xff0c;这2个软件都能完成python的编辑和运行&#xff0c;下面我简单介绍一下这2个软件的安装和…

AIDE手机编程初级教程(零基础向) 引入篇

引入 系列教程导航 文章目录 前言基本知识准备工作你的第一个应用后记 前言 本篇文章是AIDE初级教程的第一篇文章&#xff0c;也是我的第一篇文章&#xff0c;说实话&#xff0c;写的时候我也很紧张。不过&#xff0c;我会尽量的。 注意&#xff0c;本教程是零基础向的A…

c++手机编程软件_手机也能编程?盘点这5个可以用手机编程的App!快收藏!

学编程,最方便的肯定是电脑啦。但是有很多时候电脑没办法带电脑怎么学习编程呢?小青在网上整理了一些:简单几个可以在手机上编程的软件,主要分为C/C++,Java,Python,前端网页,Linux这5个方面,感兴趣可以下载尝试一下: 1、C/C++ 这里介绍一个软件—C++编译器(c4droid)…

如何在手机上进行编程?

这里介绍几个可以在手机上编程的软件&#xff0c;感兴趣的可以下载一下&#xff0c;试着操作一下&#xff1a; 1.Python&#xff1a;这里推荐一个软件—QPython3&#xff0c;集成了Python3解释器、Console控制台和QEdit编辑器&#xff0c;可以直接编辑运行python代码&#xff…

在手机上学习编程?这4个软件让你轻松搞定!

前言 编程是一项非常有用也很有趣的技能&#xff0c;但是很多人可能觉得在电脑上学习编程太麻烦了&#xff0c;或者没有时间和条件去学习。其实&#xff0c;在手机上也可以学习编程哦&#xff01;今天我就给大家推荐4个可以在手机上编程的软件&#xff0c;涵盖了C/C&#xff0…

网络类型-P2P

网络类型–P2P 网络类型&#xff1a; 根据数据链路层使用的协议进行划分 MA&#xff1a;多点接入网络 BMA&#xff1a;广播型多点接入 NBMA&#xff1a;非广播型多点接入 P2P&#xff1a;点到点网络类型 ​ 以太网协议&#xff1a;需要使用MAC地址对不同的主机设备进行区…

java基于t-io框架实现区块链中的p2p网络构建模拟区块信息同步

前言 上次我们用java实现了默克树,这次我们用java基于t-io框架实现区块链中的p2p网络构建,实现通信的功能,当然,实现p2p也可以基于WebSocket!下次我们再来实现一下。 区块链 P2P闲聊 P2P Peer-to-Peer ,最早起源于 1997 年, otlin ommunication 公司研制了能让用户从别…

区块链中P2P网络

转载自https://keeganlee.me/post/blockchain/20180313 有整理 P2P网络在区块链里面解决了去中心化的问题&#xff0c;原理很容易理解&#xff0c;但是其中细节则复杂得多。 推荐书籍&#xff1a;《P2P对等网络原理与应用》 P2P 网络不同于传统的客户端/服务端(client/serve…