精华内容
下载资源
问答
  • 均线策略
    2021-06-04 08:45:31

    导语: 双均线策略,通过建立m天移动平均线,n天移动平均线,则两条均线必有交点。若m>n,n天平均线“上穿越”m天均线则为买入点,反之为卖出点。该策略基于不同天数均线的交叉点,抓住股票的强势和弱势时刻,进行交易。

     

    均线嘛,都是均线

    对于每一个交易日,都可以计算出前N天的移动平均值,然后把这些移动平均值连起来,成为一条线,就叫做N日移动平均线。

    比如前5个交易日的收盘价分别为10,9,9,10,11元,那么,5日的移动平均股价为9.8元。同理,如果下一个交易日的收盘价为12,那么在下一次计算移动平均值的时候,需要计算9,9,10,11,12元的平均值,也就是10.2元。

    将这平均值连起来,就是均线。

    如下图所示,收盘价是蓝线,橙色的线表示5日的移动平均线。

    1.png

    可以看到股票价格的波动比5天均线的波动要大,这是因为5天均线取的是前5个交易日的均值,相当于做了一个平滑。

     

    双均线

    顾名思义就是两条天数不同的移动平均线,比如说,一条是5天的移动平均线,另一条是10天的移动平均线。如图,蓝色的是5天均线,黄色的是10天均线。

    更多相关内容
  • 在文章《三均线策略是否好于双均线(上)》中,我跟大家说过,将60日均线作为判断趋势的依据,同时通过10/30日均线找买卖点是大多数投资者最常用的方法。 但是三条均线可不止这一种用法,所以本文,继续探讨其他方法...
  • python股票均线策略

    2020-03-27 05:20:19
    python下的股票均线策略 代码实例
  • 用python实现均线策略,结合pandas库实现
  • 均线策略 量化 Python 聚宽 JoinQuant.com 双均线策略,当五日均线位于十日均线上方则买入,反之卖出。
  • 主要介绍了浅谈python量化 双均线策略(金叉死叉),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • # python构建双均线策略 # 均线策略中最常见的一种方法是根据长期均线和短期均线的交叉情况来确定交易信号,即:当短期均线从下往上穿越长期均线时,形成金叉,做多; # 反之,当长期均线从上往下穿越短期均线时,...
    # python构建双均线策略
    
    # 均线策略中最常见的一种方法是根据长期均线和短期均线的交叉情况来确定交易信号,即:当短期均线从下往上穿越长期均线时,形成金叉,做多;
    # 反之,当长期均线从上往下穿越短期均线时,形成死叉,做空或平仓。下面是常见的双均线策略如下:
    # 均线:以 5 日均线为短期均线、以 20 日均线为长期均线;
    # 买入开仓:当前无持仓,当日 5 日均线上穿 20 日均线,第二天以市价单买入,开仓;
    # 卖出平仓:当前持有多单,当日 5 日均线下穿 20 日均线,第二天以市价单卖出,平仓。
    
    # 三均线策略与双均线策略类似,只不过交易信号是由短期均线、中期均线、长期均线这 3 条均线共同确定的。如果只考虑做多的情况,一般是短期均线>中期均线>长期均线,
    # 呈多头排列时,买入开仓;出现短期均线下穿中期均线时,卖出平仓。下面是案例具体的策略逻辑:
    # 均线:5 日均线为短期均线、20 日均线为中期均线、60 日均线为长期均线;
    # 买入开仓:当前无持仓,当开始出现 5 日均线>20 日均线>60 日均线多头排列时,第二天以市价单买入,开仓;
    # 卖出平仓:当前持有多单,当日 5 日均线下穿 20 日均线,第二天以市价单卖出,平仓。
    
    import numpy as np
    import pandas as pd
    import warnings
    warnings.filterwarnings('ignore')
    def get_data(code,start_time,end_time):
        df = get_price(security=code, start_date=start_time, end_date=end_time, frequency='daily')
        df.index=pd.to_datetime(df.index)
        df['openinterest']=0
        df=df[['open','high','low','close','volume','openinterest']] #按照back trader数据格式进行整合
        return df
    
    code='600519.XSHG'
    start_time='2016-9-7'
    end_time='2022-5-20'
    stock_df=get_data(code,start_time,end_time)
    stock_df
    
    openhighlowclosevolumeopeninterest
    2016-09-07290.26290.26286.34287.373162902.00
    2016-09-08286.07287.28285.32286.641782374.00
    2016-09-09287.42287.61284.93285.521730813.00
    2016-09-12283.06284.93279.09279.364079778.00
    2016-09-13281.14282.09280.53281.591734373.00
    .....................
    2022-05-161797.001797.001742.671758.002776531.00
    2022-05-171769.881775.001755.001768.002014474.00
    2022-05-181773.661773.921743.021761.002485044.00
    2022-05-191745.001757.001739.001756.001977626.00
    2022-05-201759.991801.151752.001800.014194960.00

    1382 rows × 6 columns

    # 计算均线
    def sma_cal(df,window):
        sma=df['close'].rolling(window=window).mean()
        return sma
    
    sma_df={}
    window=[5,10,20,60]
    for i in range(len(window)):
        sma_name=str(window[i])
        value=sma_cal(stock_df,window[i])
        sma_df['sma'+sma_name]=value
    sma_df=pd.DataFrame(sma_df)
    sma_df['close']=stock_df['close']
    sma_df['ret']=sma_df['close'].pct_change()
    sma_df=sma_df.dropna()
    sma_df
    
    sma5sma10sma20sma60closeret
    2016-12-08305.418302.715297.6910290.251167316.530.031345
    2016-12-09308.414304.671298.7535290.737833316.570.000126
    2016-12-12310.464305.361299.4975291.066500306.36-0.032252
    2016-12-13311.698306.209300.3880291.509833312.120.018801
    2016-12-14312.602307.445301.2840292.044333311.43-0.002211
    .....................
    2022-05-161766.6201787.8481782.99851771.6578331758.00-0.011382
    2022-05-171766.9821781.1481780.94851769.6141671768.000.005688
    2022-05-181765.5821774.4101778.69901767.4216671761.00-0.003959
    2022-05-191764.2481766.3101776.95801765.2385001756.00-0.002839
    2022-05-201768.6021767.0111777.44351763.4553331800.010.025063

    1323 rows × 6 columns

    import matplotlib.pyplot as plt
    sma_df.iloc[:,0:5].plot(figsize=(12,7))
    

    在这里插入图片描述

    # 双均线
    # 采用5日均线与20日均线
    signal=pd.Series(0,index=sma_df.index)
    for i in range(1,len(signal)):
        if all([sma_df['sma5'][i]>sma_df['sma20'][i],sma_df['sma5'][i-1]<sma_df['sma20'][i-1]]):
            signal[i]=1
        elif all([sma_df['sma5'][i]<sma_df['sma20'][i],sma_df['sma5'][i-1]>sma_df['sma20'][i-1]]):
            signal[i]=-1
    signal
    
    2016-12-08    0
    2016-12-09    0
    2016-12-12    0
    2016-12-13    0
    2016-12-14    0
                 ..
    2022-05-16    0
    2022-05-17    0
    2022-05-18    0
    2022-05-19    0
    2022-05-20    0
    Length: 1323, dtype: int64
    
    trad_signal=signal.shift(1)
    trad_signal
    
    2016-12-08    NaN
    2016-12-09    0.0
    2016-12-12    0.0
    2016-12-13    0.0
    2016-12-14    0.0
                 ... 
    2022-05-16    0.0
    2022-05-17    0.0
    2022-05-18    0.0
    2022-05-19    0.0
    2022-05-20    0.0
    Length: 1323, dtype: float64
    
    long=pd.Series(0,index=sma_df.index)
    long[trad_signal==1]=1
    longret=long*sma_df['ret']
    long_winret=len(longret[longret>0])/len(longret[longret!=0])
    long_winret
    
    0.43243243243243246
    
    short=pd.Series(0,index=sma_df.index)
    short[trad_signal==-1]=-1
    shortret=short*sma_df['ret']
    short_winret=len(shortret[shortret>0])/len(shortret[shortret!=0])
    short_winret
    
    0.5128205128205128
    
    tradret=trad_signal*sma_df['ret'].dropna()
    winret=len(tradret[tradret>0])/len(tradret[tradret!=0])
    winret
    
    0.4675324675324675
    
    cumlong=np.cumprod(1+longret)-1
    cumshort=np.cumprod(1+shortret)-1
    cumret=np.cumprod(1+tradret)-1
    
    plt.figure(figsize=(12,8))
    plt.plot(cumlong,label='long ret')
    plt.plot(cumshort,label='short ret')
    plt.plot(cumret,label='long_short ret')
    
    plt.legend()
    plt.show()
    

    在这里插入图片描述

    # 三均线策略
    # 采用5日均线、20日均线与60日均线
    signal1=pd.Series(0,index=sma_df.index)
    for i in range(1,len(signal1)):
        if all([sma_df['sma5'][i]>sma_df['sma20'][i]>sma_df['sma60'][i]]):
            signal1[i]=1
        elif all([sma_df['sma5'][i]<sma_df['sma20'][i],sma_df['sma5'][i-1]>sma_df['sma20'][i-1]]):
            signal1[i]=-1
    signal1
    
    2016-12-08    0
    2016-12-09    1
    2016-12-12    1
    2016-12-13    1
    2016-12-14    1
                 ..
    2022-05-16    0
    2022-05-17    0
    2022-05-18    0
    2022-05-19    0
    2022-05-20    0
    Length: 1323, dtype: int64
    
    trad_signal1=signal1.shift(1)
    trad_signal1
    
    2016-12-08    NaN
    2016-12-09    0.0
    2016-12-12    1.0
    2016-12-13    1.0
    2016-12-14    1.0
                 ... 
    2022-05-16    0.0
    2022-05-17    0.0
    2022-05-18    0.0
    2022-05-19    0.0
    2022-05-20    0.0
    Length: 1323, dtype: float64
    
    long1=pd.Series(0,index=sma_df.index)
    long1[trad_signal1==1]=1
    longret1=long1*sma_df['ret']
    long_winret1=len(longret1[longret1>0])/len(longret1[longret1!=0])
    long_winret1
    
    0.5363214837712519
    
    short1=pd.Series(0,index=sma_df.index)
    short1[trad_signal1==-1]=-1
    shortret1=short1*sma_df['ret']
    short_winret1=len(shortret1[shortret1>0])/len(shortret1[shortret1!=0])
    short_winret1
    
    0.5128205128205128
    
    tradret1=trad_signal1*sma_df['ret'].dropna()
    winret1=len(tradret1[tradret1>0])/len(tradret1[tradret1!=0])
    winret1
    
    0.5342066957787481
    
    cumlong1=np.cumprod(1+longret1)-1
    cumshort1=np.cumprod(1+shortret1)-1
    cumret1=np.cumprod(1+tradret1)-1
    
    plt.figure(figsize=(12,8))
    
    
    plt.plot(cumlong1,label='long ret1')
    plt.plot(cumshort1,label='short ret1')
    plt.plot(cumret1,label='long_short ret1')
    plt.legend()
    plt.show()
    

    在这里插入图片描述

    import backtrader as bt
    import pandas as pd
    # 自定义信号指标
    class MySignal(bt.Indicator):
        lines = ('signal',) # 声明 signal 线,交易信号放在 signal line 上
        params = dict(
            short_period=5,
            long_period=20)
        
               
        def __init__(self):
            
            self.dataclose=self.datas[0].close
            
            self.s_ma = bt.ind.SMA(period=self.p.short_period)
            self.l_ma = bt.ind.SMA(period=self.p.long_period)
            # 短期均线上穿长期均线,取值为1;反之,短期均线下穿长期均线,取值为-1
            self.lines.signal = bt.ind.CrossOver(self.s_ma, self.l_ma)
            
        
    
        
    # 实例化大脑
    cerebro = bt.Cerebro()
    # 加载数据
    
    datafeed = bt.feeds.PandasData(dataname=stock_df,
                                  fromdate=pd.to_datetime('2019-01-02'),
                                  todate=pd.to_datetime('2021-01-28'))
    cerebro.adddata(datafeed)
    # 初始资金 1,000,000
    cerebro.broker.setcash(1000000.0)
    # 佣金,双边各 0.0003
    cerebro.broker.setcommission(commission=0.0003)
    # 滑点:双边各 0.0001
    cerebro.broker.set_slippage_perc(perc=0.0001)
    #每次固定交易100股
    cerebro.addsizer(bt.sizers.FixedSize, stake=100)
    # 添加交易信号
    cerebro.add_signal(bt.SIGNAL_LONG, MySignal)
    # 添加分析器
    cerebro.addanalyzer(bt.analyzers.TimeReturn, _name='pnl') # 返回收益率时序数据
    cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name='_AnnualReturn')
    cerebro.addanalyzer(bt.analyzers.SharpeRatio, riskfreerate=0.003, annualize=True, _name='_SharpeRatio')
    cerebro.addanalyzer(bt.analyzers.DrawDown, _name='_DrawDown')
    # 添加观测器
    cerebro.addobserver(bt.observers.Value)  # 查看账户资产变动
    print(f'组合初始价值:%.2f'%cerebro.broker.getvalue())
    result = cerebro.run()
    print(f'组合期末价值:%.2f'%cerebro.broker.getvalue())
    cerebro.plot(iplot=False)
    
    组合初始价值:1000000.00
    组合期末价值:1055108.41
    

    在这里插入图片描述

    strat = result[0]
    print("--------------- AnnualReturn -----------------")
    print(strat.analyzers._AnnualReturn.get_analysis())
    print("--------------- SharpeRatio -----------------")
    print(strat.analyzers._SharpeRatio.get_analysis())
    print("--------------- DrawDown -----------------")
    print(strat.analyzers._DrawDown.get_analysis())
    
    --------------- AnnualReturn -----------------
    OrderedDict([(2019, 0.004241777782910017), (2020, 0.04177344221019741), (2021, 0.008522332874576044)])
    --------------- SharpeRatio -----------------
    OrderedDict([('sharperatio', 0.9048730445652012)])
    --------------- DrawDown -----------------
    AutoOrderedDict([('len', 3), ('drawdown', 0.8102639726476181), ('moneydown', 8619.0), ('max', AutoOrderedDict([('len', 172), ('drawdown', 3.3309121179482157), ('moneydown', 33756.307311659795)]))])
    
    # 自定义信号指标
    class MySignal(bt.Indicator):
        lines = ('signal',) # 声明 signal 线,交易信号放在 signal line 上
        params = dict(
            short_period=5,
            median_period=20,
            long_period=60)
        def __init__(self):
            self.s_ma = bt.ind.SMA(period=self.p.short_period)
            self.m_ma = bt.ind.SMA(period=self.p.median_period)
            self.l_ma = bt.ind.SMA(period=self.p.long_period)
            # 短期均线在中期均线上方,且中期均取也在长期均线上方,三线多头排列,取值为1;反之,取值为0
            self.signal1 = bt.And(self.m_ma>self.l_ma, self.s_ma>self.m_ma)
            # 求上面 self.signal1 的环比增量,可以判断得到第一次同时满足上述条件的时间,第一次满足条件为1,其余条件为0
            self.buy_signal = bt.If((self.signal1-self.signal1(-1))>0, 1, 0)
            # 短期均线下穿长期均线时,取值为1;反之取值为0
            self.sell_signal = bt.ind.CrossDown(self.s_ma, self.m_ma)
            # 将买卖信号合并成一个信号
            self.lines.signal = bt.Sum(self.buy_signal, self.sell_signal*(-1))
    
    # 实例化大脑
    cerebro = bt.Cerebro()
    # 加载数据
    # 读取行情数据
    
    datafeed = bt.feeds.PandasData(dataname=stock_df,
                                  fromdate=pd.to_datetime('2019-01-02'),
                                  todate=pd.to_datetime('2021-01-28'))
    cerebro.adddata(datafeed)
    # 初始资金 1,000,000
    cerebro.broker.setcash(1000000.0)
    # 佣金,双边各 0.0003
    cerebro.broker.setcommission(commission=0.0003)
    # 滑点:双边各 0.0001
    cerebro.broker.set_slippage_perc(perc=0.0001)
    #每次固定交易100股
    cerebro.addsizer(bt.sizers.FixedSize, stake=100)
    # 添加交易信号
    cerebro.add_signal(bt.SIGNAL_LONG, MySignal)
    # 添加交易信号
    cerebro.add_signal(bt.SIGNAL_LONG, MySignal)
    # 添加分析器
    cerebro.addanalyzer(bt.analyzers.TimeReturn, _name='pnl') # 返回收益率时序数据
    cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name='_AnnualReturn')
    cerebro.addanalyzer(bt.analyzers.SharpeRatio, riskfreerate=0.003, annualize=True, _name='_SharpeRatio')
    cerebro.addanalyzer(bt.analyzers.DrawDown, _name='_DrawDown')
    
    # 回测时需要添加 PyFolio 分析器
    cerebro.addanalyzer(bt.analyzers.PyFolio, _name='pyfolio')
    cerebro.addobserver(bt.observers.Value)  # 查看账户资产变动
    print(f'组合初始价值:%.2f'%cerebro.broker.getvalue())
    result = cerebro.run()
    print(f'组合期末价值:%.2f'%cerebro.broker.getvalue())
    cerebro.plot(iplot=False)
    
    组合初始价值:1000000.00
    组合期末价值:1071222.93
    

    在这里插入图片描述

    strat = result[0]
    print("--------------- AnnualReturn -----------------")
    print(strat.analyzers._AnnualReturn.get_analysis())
    print("--------------- SharpeRatio -----------------")
    print(strat.analyzers._SharpeRatio.get_analysis())
    print("--------------- DrawDown -----------------")
    print(strat.analyzers._DrawDown.get_analysis())
    
    --------------- AnnualReturn -----------------
    OrderedDict([(2019, 0.007321597032730054), (2020, 0.0545856770351798), (2021, 0.008393054551040002)])
    --------------- SharpeRatio -----------------
    OrderedDict([('sharperatio', 0.9274312773078117)])
    --------------- DrawDown -----------------
    AutoOrderedDict([('len', 3), ('drawdown', 0.7981723781349532), ('moneydown', 8619.0), ('max', AutoOrderedDict([('len', 137), ('drawdown', 2.7729689789715986), ('moneydown', 29437.66091440979)]))])
    
    
    
    展开全文
  • 写在前面: 本文不是在量化平台上做策略回测的coding,仅以2016-04-15~2019-04-15期间阿里巴巴(BABA)的收盘价模拟均线策略,从而基于数据得出某些观点。平台:python3 1、单均线策略均线策略:上个交易日股价...

    写在前面: 本文不是在量化平台上做策略回测的coding,仅以2016-04-15~2019-04-15期间阿里巴巴(BABA)的收盘价模拟均线策略,从而基于数据得出某些观点。平台:python3

    1、单均线策略

    单均线策略:上个交易日股价超出10日均线,则今日买入,跌破则卖出

    1. 获取股票收盘价

    加载数据,把date这一列设置为索引,简单起见,只用收盘价进行分析。
    「Tips」
    a. 参数index_col可以在读取数据时指定index
    b. pd.Series.str.strip()可以去除series数据的指定符号,具体查看文档
    c. pd.DatetimeIndex()可设置某列为时间戳的index
    d. sort_index()按照index排序

    import numpy as np
    import pandas as pd
    df = pd.read_csv('./BABA_stock.csv', index_col = 'date', usecols = [0,1])
    # 先查看数据
    df.head()
    # 将索引转换成datetime格式,并去除引号。时间戳的索引可以保证,数据运算时,是对应当天的值计算
    df.index = pd.DatetimeIndex(df.index.str.strip("'"))
    # 按照日期,升序排列
    df.sort_index(inplace = True)
    print(df.head())
    df.describe()
    

    「数据」

    「描述性统计」

    从数据的描述性统计来看,在这段期间,BABA每股收盘价的最低价是$74.23,最高价是$219.86,平均价为$143.37。这就是买一股的成本。

    2. 计算10日均线数据

    「Tips」
    df.rolling(10)滚动窗口取10条数据

    ma10 = df.rolling(10).mean()
    ma10_model = df['close'] - ma10['close'] >0
    

    ma10是每个交易日对应的10日均价,ma10_model的结果是每一个交易日的布尔值。如果当天的收盘价高于10日均线价格,赋值True,反之False,也就是说,当ma10_model由False变为True,第二天就是买入点;由True变为False,第二天就是卖出点。我们看一下ma10_model的前25条数据:

    3. 判断买点和卖点

    「Tips」
    a. get_deal_date()是自定义函数,参数w是连续3个交易日的bool值,参数is_buy是得到买点OR卖点,该函数用来得到本策略的交易日。
    b. apply()有一个参数args,用来传参。
    c. reset_index(drop = True)是drop当前的index,恢复默认index。

    # 第一个值False,第二个值是True,在True的时候买入,需要自定义一个移动窗口处理函数
    # 因为卖的时候还需要定义类似的函数,所以这里把这两个函数放在一起
    # 可以在自定义函数中print一些信息,例如w值,以方便调试---这也是调试的一种方式
    # 注意:1.如果第一个卖点在第一个买点之前,则需要删除第一个卖点的数据,因为中国股市不能做空
    # 2.看买点和卖点个数是否一样多,考虑一种情况,买了之后卖点到现在还没有出现,也就是卖点比买点少一个,
    # 这种情况我们把当前的股价加到卖点数据中(也可以把最后一个买点数据删除)
    def get_deal_date(w, is_buy = True):
        if is_buy == True:
            return True if w[0] == False and w[1] == True else False
        else:
            return True if w[0] == True and w[1] == False else False
    
    date_buy = ma10_model.rolling(3).apply(get_deal_date, raw = False).fillna(0).astype('bool')
    date_sell = ma10_model.rolling(3).apply(get_deal_date, raw = False, args=[False]).fillna(0).astype('bool')
    # 具体的买卖点
    buy_info = df[date_buy.values]
    sell_info = df[date_sell.values]
    # 买和卖的索引值不同,所以删除时间索引信息.
    # 买的数据比卖多一条,所以删除买点的最后一条数据
    no_index_buy_info = buy_info.reset_index(drop = True)
    no_index_sell_info = sell_info.reset_index(drop = True)
    # 每次交易的盈利情况
    profit = no_index_sell_info - no_index_buy_info
    profit.columns = ['profit']
    print(profit.describe())
    profit.sum()
    

    「结果」
    在不考虑佣金、总金额、每次只买1股的情况下,根据单均线策略,一共交易62个回合,平均每次赚$0.09,总计$5.77。
    注意这是每次买和卖一股的利润(买固定的股数),三年的时间交易了62次,最多投入210.86,平均投入143.366954,按最高投入算利润率(5.77 / 210.860000),年化收益率约为0.90%,按平均投入来算,年化收益率约为1.32%。这个回报率是非常低的,甚至赶不上通货膨胀,因此我们接下来计算给定一定本金情况下的回报率。

    4. 计算盈利

    之前的假设是每次只买1股,显然不符合逻辑。现在我们假设,有1w美元,每次看多都all-in,万3手续费,最终盈利多少?

    def get_profit(buy_info, sell_info,all_money=10000, fee=0.0003):
        remian = all_money
        for i in range(len(buy_info)):
            n = all_money // buy_info.iloc[i]
            remain = all_money - n * buy_info.iloc[i]
            all_money = sell_info.iloc[i] * n * (1-fee) + remain
        print('total money:{}'.format(all_money.values))
        
    get_profit(buy_info=no_index_buy_info, sell_info=no_index_sell_info)
    # 最后获利 1176.443819
    # total money:[11176.443819]
    

    根据结果,初始资金1w美金,3年共买卖62次,累计获利$1176.4438,年化收益率为3.78%

    2、双均线策略

    双均线策略:上个交易日10日均线上穿20日均线则买入,下穿则卖出

    1. 计算20日均线数据

    ma20 = df.rolling(20).mean()
    ma20_model = ma20['close'] - ma10['close'] >0
    

    2. 判断买点卖点

    date_buy_2 = ma20_model.rolling(3).apply(get_deal_date, raw = False).fillna(0).astype('bool')
    date_sell_2 = ma20_model.rolling(3).apply(get_deal_date, raw = False, args=[False]).fillna(0).astype('bool')
    # 具体的买卖点
    buy_info_2 = df[date_buy_2.values]
    sell_info_2 = df[date_sell_2.values]
    # 买和卖的索引值不同,所以删除时间索引信息
    no_index_buy_info_2 = buy_info_2.reset_index(drop = True)
    no_index_sell_info_2 = sell_info_2.reset_index(drop = True)
    # 每次交易的盈利情况
    profit_2 = no_index_sell_info_2 - no_index_buy_info_2
    profit_2.columns = ['profit']
    print(profit_2.describe())
    profit_2.sum()
    

    「结果」
    在不考虑佣金、总金额、每次只买1股的情况下,根据双均线策略,一共交易15个回合,平均每次赚$3.92,总计$58.88。
    注意这是每次买和卖一股的利润(买固定的股数),三年的时间交易了15次,最多投入210.86,平均投入143.366954,按最高投入算利润率(58.88 / 210.860000),年化收益率约为8.55%,按平均投入来算,年化收益率约为12.15%。收益率结果比单均线策略高,下面计算给定一定本金情况下的回报率。

    3. 计算盈利

    跟前面单均线策略同样的假设:有1w美元,每次看多都all-in,万3手续费,最终盈利多少?

    直接调用前面的函数即可,参数换成策略二的。

    get_profit(buy_info=no_index_buy_info_2, sell_info=no_index_sell_info_2)
    

    「结果」
    根据结果,初始资金1w美金,3年共买卖15次,累计获利$3703.061336,年化收益率为11.07%。很明显,比单均线策略的收益要高~

    总结

    策略固定股数年化收益率固定金额年化收益率
    单均线策略1.32%3.78%
    双均线策略12.15%11.07%

    仅从收益率的角度来看(不考虑最大回撤),双均线策略更优——上个交易日10日均线上穿20日均线,则本交易日买入,下穿则卖出。

    展开全文
  • python实现双均线策略

    千次阅读 2020-11-01 19:01:51
    均线策略:双均线策略,当五日均线位于十日均线上方则买入,反之卖出。 二、证券知识: 策略收益(Total Returns) 最容易理解的一个概念,策略收益也就是策略开始到结束,总资产的变化率。 ----本文 选取的平安...

    本文采用了聚宽平台接口进行量化策略设置:

    一、效果图

    双均线策略:双均线策略,当五日均线位于十日均线上方则买入,反之卖出。
    image.png

    二、证券知识:

    策略收益(Total Returns)
    最容易理解的一个概念,策略收益也就是策略开始到结束,总资产的变化率。

    ----本文 选取的平安银行 这只股票,通过双均线策略来计算策略收益。

    基准收益(Benchmark Returns)
    如果一个策略一年赚了50%,而这一年来上证指数上涨了100%,所以要评判一个策略的好坏,不过是要看它的收益率,还需要一个基准来衡量它的优劣性,这个准基就是准基收益率。

    对于股票的策略如果高于上证指数,那么就跑赢了基准收益率,也就是跑赢了大盘;低于上证指数,那么就是跑输了基准收益率。所以说一个好的策略至少要高于基准收益。

    ----本文 选取的沪深三百指数,获取某段时间的基本收益。

    贝塔(Beta)
    代表了策略表现对大盘变化的敏感性,也即是策略与大盘的相关性。

    例如一个策略的Beta为1.5,则大盘涨1%的时候,策略可能涨1.5%,反之亦然;如果一个策略的Beta为-1.5,说明大盘涨1%的时候,策略可能跌1.5%,反之亦然。

    分别是策略的每日收益和基准的每日收益

    阿尔法(Alpha)
    alpha是超额收益,它与市场波动无关,也就是说不是靠系统性的上涨而获得收益。

    分别是策略年化收益率、基准年化收益率和无风险利率(默认0.04)。

    通过预测方向或者其他可解释原因的策略也即是alpha策略;而通过波动率来带来利润的策略就是beta策略。

    夏普比率(Sharpe)
    描述的是策略在单位总风险下所能获得的超额收益。

    是策略收益波动率,也即是策略收益率的年化标准差。

    所提诺比率(Sortino)
    描述的是策略在单位下行风险下所能获得的超额收益。

    是策略下行波动率。

    信息比率(Information Ratio)
    描述的是策略在单位超额风险下的超额收益。

    是策略与基准每日收益差值的年化标准差。

    最大回撤(Max Drawdown)
    描述的策略最大的亏损情况。最大回撤通常越小越好。

    是策略两日的累计收益。

    三、python代码

    # 导入函数库
    from jqdata import *
    
    # 初始化函数,设定基准等等
    def initialize(context):
        # 设定沪深300作为基准
        set_benchmark('000300.XSHG')
        # 开启动态复权模式(真实价格)
        set_option('use_real_price', True)
        # 输出内容到日志 log.info()
        log.info('初始函数开始运行且全局只运行一次')
        # 过滤掉order系列API产生的比error级别低的log
        # log.set_level('order', 'error')
    
        ### 股票相关设定 ###
        # 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
        set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
        ## 运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'000300.XSHG'或'510300.XSHG'是一样的)
          # 开盘前运行
        run_daily(before_market_open, time='before_open', reference_security='000300.XSHG')
          # 开盘时运行
        run_daily(market_open, time='open', reference_security='000300.XSHG')
          # 收盘后运行
        run_daily(after_market_close, time='after_close', reference_security='000300.XSHG')
    
    ## 开盘前运行函数
    def before_market_open(context):
        # 输出运行时间
        log.info('函数运行时间(before_market_open):'+str(context.current_dt.time()))
    
        # 给微信发送消息(添加模拟交易,并绑定微信生效)
        # send_message('美好的一天~')
    
        # 要操作的股票:平安银行(g.为全局变量)
        g.security = '000001.XSHE'
    
    ## 开盘时运行函数
    def market_open(context):
        log.info('函数运行时间(market_open):'+str(context.current_dt.time()))
        security = g.security
        # 获取股票的收盘价
        close_data = get_bars(security, count=5, unit='1d', fields=['close'])
        # 取得过去五天的平均价格
        MA5 = close_data['close'].mean()
        # 取得上一时间点价格
        current_price = close_data['close'][-1]
        # 取得当前的现金
        cash = context.portfolio.available_cash
    
        # 如果上一时间点价格高出五天平均价1%, 则全仓买入
        if (current_price > 1.01*MA5) and (cash > 0):
            # 记录这次买入
            log.info("价格高于均价 1%%, 买入 %s" % (security))
            print("当前可用资金为{0}, position_value为{0}".format(cash, context.portfolio.positions_value))
            # 用所有 cash 买入股票
            order_value(security, cash)
        # 如果上一时间点价格低于五天平均价, 则空仓卖出
        elif current_price < MA5 and context.portfolio.positions[security].closeable_amount > 0:
            # 记录这次卖出
            log.info("价格低于均价, 卖出 %s" % (security))
            # 卖出所有股票,使这只股票的最终持有量为0
            order_target(security, 0)
    
    ## 收盘后运行函数
    def after_market_close(context):
        log.info(str('函数运行时间(after_market_close):'+str(context.current_dt.time())))
        #得到当天所有成交记录
        trades = get_trades()
        for _trade in trades.values():
            log.info('成交记录:'+str(_trade))
        log.info('一天结束')
        log.info('##############################################################')
    

    四、最大回撤详细图
    image.png

    展开全文
  • 博文《【实战】——基于GUI编程的python股票量化交易策略之双均线策略》利用GUI编程开发用户操作界面,以此来绘制动态的K线及双均线,实现界面动态交互效果。 学习完该实战项目后,你将掌握基于tkinter程序包开发...
  • 策略篇--量化投资之双均线策略

    万次阅读 2019-04-12 15:59:46
    均线策略应该是我们刚进入股市时就听过的一个策略,而双均线策略,顾名思义,就是两根均线:短期均线和长期均线。当短线均线上穿长期均线(金叉)时买入,当短期均线下穿长期均线(死叉)时卖出,这就是双均线策略的...
  • Python股票双均线策略

    2022-07-06 14:32:26
    Python股票双均线策略,绘制双均线图,找到金叉与死叉点。
  • 【python股票量化】双均线策略编程实现
  • 本软件包包含三种不同的均线交易策略源码,1,单均线系统,2,双均线系统,3,三均线系统。单均线策略是判断k线与均线的交叉判断,双均线是快线与慢线的交叉判断,三均线是多头排列判断。
  • 简单的均线交易策略以及回测指标等,包括回撤,收益率,仓位控制等
  • 问题:3. 三均线策略是一个非常经典的趋势追踪策略。它的具体表述如下,快速均线往上穿过中速均线时就买进,而当快速均线往下穿过慢速均线时就卖出。假设我们使用3日均线作为快速均线,6日均线作为中速均线,9日...
  • 定义双均线策略,通过建立m天移动平均线,n天移动平均线,则这两条均线必有交点。若m>n,n天平均线“上穿越”m天均线则为买入点,反之为卖点。该策略基于不同天数均线的交叉点,抓住股票的强势和弱势时刻,进行...
  • 第28节 真 • 动态自适应双均线策略作者: 阿布阿布量化版权所有 未经允许 禁止转载阿布量化微信公众号: abu_quant上一节讲解了选股策略与择时策略相互配合的示例,本节的内容将讲解择时策略中的经典策略双均线策略,...
  • 4、Python量化交易-双均线策略笔记
  • Python双均线策略回测(2021-10-12)

    万次阅读 2021-10-12 10:05:53
    这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变...Python双均线策略回测 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页
  • 原标题:GAEA:终极战法——双均线策略大家好,这次GAEA为大家带来的是双均线策略。我们之前介绍过趋势追踪策略和均值回归策略一直是量化投资两大永恒的主题。并且以网格策略为例勾勒了均值回归策略的一般形式。这类...
  • Python做双均线策略

    2022-05-26 14:51:05
    pandas.DataFrame获取多列构成一个新的pandas.DataFrame data=df[[‘trade_date’,‘close’]]#...pandas.Series.rolling功能生成均线,window设置均线周期,.mean功能计算window的均值 data[‘5d’]=pd.Series.rolling
  • 均线策略(CTA)

    2021-04-25 12:34:09
    均线策略,指的是运用两条不同周期的移动平均线,即短周期移动平均线和长周期移动平均线的相对大小,研判买进与卖出时机的策略。由短周期均线自下向上穿越长周期均线,所形成的交点,称为金叉。当短周期均线...
  • 课程内容从随处可见的双均线策略入手,对市场交易数据进行深入分析,识别出其中的问题,进行策略优化。课程注重实战,学员上课后,可以达到:能够自行继续研发新的策略。将策略研究过程带到短期,中期交易策略中,...
  • 什么是双均线? 有两条线:短期均线和长期均线。当短线均线上穿长期均线(金叉)时买入,当短期均线下穿长期均线(死叉)时卖出。 代码: # 导入函数库 from jqdata import * # 初始化函数,设定基准等等 def ...
  • 量化交易 聚宽 双均线策略 # 导入函数库 from jqdata import * # 初始化函数,设定基准等等 def initialize(context): # 设定沪深300作为基准 set_benchmark('000300.XSHG') # 开启动态复权模式(真实价格) set_...
  • 策略为:笔者认为如果5日均线高于10日均线,就认为股价处于上升阶段,就全仓位买入,如果5日均线低于10日均线,笔者认为股价处于下降阶段,全仓位卖出。 我们准备的数据为2006-8-18到2022-3-22 这段时间的中国国航...
  • 文章目录一、双均线策略是什么?二、代码编写思路三、代码实现1.收取数据2.导入库并定义全局变量 一、双均线策略是什么? 双均线策略的思想很简单,是根据长短周期的价格的移动平均线之间的关系来确定买卖点。其中...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,812
精华内容 1,924
关键字:

均线策略