原创内容第1005篇,专注AGI+,AI量化投资、个人成长与财富自由。

今日策略:年化460%,回撤7%,夏普5.27

图片

http://www.ailabx.com/strategy/68c7c731fd408079e03bcc10

代码下载:AI量化实验室——量化投资的星辰大海

SLOPE斜率指标已经实现:

​​​​​​​

def SLOPE(S, N):  # 线性回归斜率(如趋势线斜率)    return pd.Series(S).rolling(N).apply(lambda x: np.polyfit(range(N), x, deg=1)[0], raw=True)

斜率轮动策略:​​​​​​​

t = Task()    t.name = '全球大类资产-修正斜率轮动'    etfs = [        '510300.SH',  # 沪深300ETF        '159915.SZ',  # 创业板        '518880.SH',  # 黄金ETF        '513100.SH',  # 纳指ETF        '159985.SZ',  # 豆柏ETF        '511880.SH',  # 银华日利ETF    ]
    t.symbols = etfs
    #t.select_sell = ["roc(close,21)>0.17"]    t.order_by_signal =  "slope(close,25)"
    e = Engine()    e.run(t)    e.stats()    e.plot()

图片

新增akshare的数据更新脚本,把创业板的数据更新到昨天,然后策略运行回测:

图片

图片

import akshare as ak
def fetch_etf(symbol):    df = ak.fund_etf_hist_em(symbol=symbol, period="daily", start_date="20000101", adjust="hfq")    cols = {'最高':'high','最低':'low','收盘':'close','开盘':'open','成交量':'volume','日期':'date'}    #print(df)
    df.rename(columns=cols,inplace=True)    df['date'] = df['date'].apply(lambda x: x.replace('-', ''))    return df[list(cols.values())]

symbols = ['513100' #纳指100           ,'513500',#标普500           '510300',#沪深300,           '159915', #创业板           '518880',#黄金           '512890',# 红利低波           '159985', #豆粕           '511880',# 银华日利-货币ETF           '511260', # 十年国债           '511220', #城投债           '510180', #上证180          ]
symbols = ['159915']
for s in symbols:    print(f'获取{s}并保存到csv')    df = fetch_etf(s) # 获取纳指ETF    #df.to_csv(f'{s}.csv',index=False)    if s[0] == '5': s += '.SH'    if s[0] == '1': s += '.SZ'    df.to_csv(f'../data/quotes/{s}.csv',index=False)

backtrader新引擎,时间周期的写法:​​​​​​​

class RunDaily:    def __call__(self, target):        return True

class RunOnce:    def __init__(self):        self.has_run = False
    def __call__(self, target):        # 如果条件满足且还没有执行过,则返回True并标记为已执行        if not self.has_run:            self.has_run = True            return True        return False

class RunEveryNPeriods:    def __init__(self, n, period='days'):        self.n = n        self.period = period        self.last_date = None
    def __call__(self, target):        current_date = target.datetime.date(0)
        # 如果是第一次调用,记录当前日期并返回True        if self.last_date is None:            self.last_date = current_date            return True
        # 根据不同的时间单位计算间隔        if self.period == 'days':            days_diff = (current_date - self.last_date).days            if days_diff >= self.n:                self.last_date = current_date                return True
        elif self.period == 'weeks':            weeks_diff = ((current_date - self.last_date).days) // 7            if weeks_diff >= self.n:                self.last_date = current_date                return True
        elif self.period == 'months':            months_diff = (current_date.year - self.last_date.year) * 12 + (current_date.month - self.last_date.month)            if months_diff >= self.n:                self.last_date = current_date                return True
        elif self.period == 'years':            years_diff = current_date.year - self.last_date.year            if years_diff >= self.n:                self.last_date = current_date                return True
        return False

class RunWeekly:    def __init__(self):        self.last_week = None
    def __call__(self, target):        current_date = target.datetime.date(0)        current_year, current_week, _ = current_date.isocalendar()        current_identifier = (current_year, current_week)  # 使用(年,周)组合处理跨年情况
        # 检查周是否变化        if current_identifier != self.last_week:            self.last_week = current_identifier            return True        return False

class RunMonthly:    def __init__(self):        self.last_month = None
    def __call__(self, target):        current_date = target.datetime.date(0)        current_year = current_date.year        current_month = current_date.month        current_identifier = (current_year, current_month)  # 使用(年,月)组合处理跨年情况
        # 检查月份是否变化        if current_identifier != self.last_month:            self.last_month = current_identifier            return True        return False

class RunQuarterly:    def __init__(self):        self.last_quarter = None
    def __call__(self, target):        current_date = target.datetime.date(0)        current_year = current_date.year        current_month = current_date.month        current_quarter = (current_month - 1) // 3 + 1  # 计算当前季度        current_identifier = (current_year, current_quarter)  # 使用(年,季度)组合
        # 检查季度是否变化        if current_identifier != self.last_quarter:            self.last_quarter = current_identifier            return True        return False

class RunYearly:    def __init__(self):        self.last_year = None
    def __call__(self, target):        current_date = target.datetime.date(0)        current_year = current_date.year
        # 检查年份是否变化        if current_year != self.last_year:            self.last_year = current_year            return True        return False

bias指标的计算:​​​​​​​

def BIAS(CLOSE, L1=6):    # 输入:CLOSE(收盘价)    BIAS1 = (CLOSE - MA(CLOSE, L1)) / MA(CLOSE, L1) * 100    return RD(BIAS1)

乖离率(BIAS)是通过计算股价(收盘价)与某条移动平均线(MA)之间的偏离程度,来反映股价因波动偏离平均成本太远,从而可能产生的回拉或反弹效应。

2. 公式拆解:

BIAS1 = (CLOSE - MA(CLOSE, L1)) / MA(CLOSE, L1) * 100

这个公式可以分解为三个部分:

CLOSE - MA(CLOSE, L1):这是收盘价与N日移动平均价的绝对差值。正数表示股价在均线之上,负数表示在均线之下。

/ MA(CLOSE, L1):将绝对差值除以移动平均价,得到的是相对比率。这一步是为了消除股价绝对值高低不同的影响,使得不同价格的股票之间可以进行比较。

* 100:将比率转换为百分比,让数值更加直观。

3. 最终输出:

RD(BIAS1):这里的 RD 函数在您的代码中没有定义,但通常代表 “四舍五入” 或保留指定小数位数的操作(例如 round(BIAS1, 2) 保留两位小数)。目的是让输出的指标值更整洁易读。

一句话总结:BIAS(6) 衡量的是当日收盘价相对于过去6日平均收盘价的偏离百分比。

使用场景与市场含义

BIAS指标主要用于判断市场的超买和超卖状态,以及寻找趋势中的短期反转机会。

1. 超买与超卖(主要用法):

正值过大(如 > +5%):表示股价远高于其近期平均成本,属于超买状态。市场上的多数短期投资者处于盈利状态,获利回吐的压力较大,股价有较高概率回调或下跌。此时可以考虑卖出。

负值过大(如 < -5%):表示股价远低于其近期平均成本,属于超卖状态。市场上的多数短期投资者处于亏损状态,抛压减轻,股价有较高概率出现技术性反弹。此时可以考虑买入。

2. 趋势确认:

BIAS值 > 0:股价在均线之上,市场处于多头(上涨)趋势。

BIAS值 < 0:股价在均线之下,市场处于空头(下跌)趋势。

吾日三省吾身

本次七年计划,不是一句口号,而是目标,系统和执行计划。

七年前的“且战且退”,有些许无奈,些许不安。

彼时,“ABCZ”均未成型,且没有思路。甚至只有思路过要有自己可以掌控的事情,如此而已。

后来,A计划迎来转机,缓了口气。但方向不应该偏。

当然,总有人或事会“提醒”你,从来没有什么“岁月静好”,要居安思危,未雨绸缪。

现在,更加有底气,B和Z的成型,加之AGI人工智能的趋势崛起。

每天“不管”一点点,每天就变强一天天。

年化390%,回撤7%,夏普6.32 | A股量化策略配置

年化30.24%,最大回撤19%,综合动量多因子评分策略再升级(python代码+数据)

年化429%,夏普5.51 | 全A股市场回测引擎构建

年化443%,回撤才7%,夏普5.53,3积分可查看策略参数

Logo

更多推荐