今日策略:年化460%,回撤7%,夏普5.27,2积分可查看
RD(BIAS1):这里的 RD 函数在您的代码中没有定义,但通常代表 “四舍五入” 或保留指定小数位数的操作(例如 round(BIAS1, 2) 保留两位小数)。乖离率(BIAS)是通过计算股价(收盘价)与某条移动平均线(MA)之间的偏离程度,来反映股价因波动偏离平均成本太远,从而可能产生的回拉或反弹效应。当然,总有人或事会“提醒”你,从来没有什么“岁月静好”,要居安思危,未雨绸缪。现在,更加
原创内容第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人工智能的趋势崛起。
每天“不管”一点点,每天就变强一天天。
更多推荐
所有评论(0)