
“该策略使用比特币的移动平均线(20天、1天、2天、4天、10天)来指导买入或卖出决策。投资组合每天重新平衡,其中10%为积极交易,子策略等权重。”
资产类别: 加密货币 | 地区: 全球 | 周期: 每日 | 市场: 加密货币 | 关键词: 移动平均
I. 策略概要
投资范围包括比特币,每日价格来自Coindesk.com。该策略使用20天、1天、2天、4天和10天的移动平均线来指导买卖决策。如果比特币在t-1时刻的价格除以移动平均线大于1,投资者买入比特币;如果小于1,投资者卖出并投资于无风险资产。这些子策略等权重,最终投资组合每日重新平衡。只有10%的投资组合进行积极交易。
II. 策略合理性
方差比率测试表明,比特币的价格是可预测的,而不是随机游走。虽然常见的宏观经济变量显示出一些样本内可预测性,但它们缺乏样本外显著性。相比之下,移动平均线比率等技术分析指标在样本内和样本外都显示出有意义的预测能力。结合不同的移动平均线信号可以增强比特币的可预测性。此外,比特币的交易量部分可以用移动平均线信号来解释。值得注意的是,移动平均线指标可以迅速发出退出信号,从而最大限度地减少回撤并提高业绩。在比特币重大危机期间,移动平均线策略有效地减少了回撤,显示了其在风险管理方面的价值。
III. 来源论文
Bitcoin: Learning and Predictability via Technical Analysis: Evidence from Bitcoin and Stocks with Hard-to- Value Fundamentals [点击查看论文]
- 安德鲁·L·德策尔(Andrew L. Detzel)、刘宏(Hong Liu)、杰克·斯特劳斯(Jack Strauss)、周国富(Guofu Zhou)和朱英姿(Yingzi Zhu)。贝勒大学汉卡默商学院,圣路易斯华盛顿大学奥林商学院;复旦大学中国经济金融研究院,丹佛大学丹尼尔斯商学院,圣路易斯华盛顿大学约翰·M·奥林商学院,清华大学经济管理学院
<摘要>
对于具有“难以估值”基本面的资产(例如比特币和新兴产业的股票),什么因素可以预测其回报?我们提出了一个均衡模型,该模型展示了理性学习如何通过技术分析实现回报的可预测性。我们记录了价格与其移动平均线之比可以预测比特币的日内和样本外回报。基于这些比率的交易策略相对于买入并持有的头寸,产生了经济上显著的阿尔法和夏普比率收益。对于小盘股、年轻公司和分析师覆盖率低的股票,以及互联网泡沫时期的纳斯达克股票,也存在类似的结果。


IV. 回测表现
| 年化回报 | 10.03% |
| 波动率 | 4.97% |
| β值 | 0.033 |
| 夏普比率 | 2.45 |
| 索提诺比率 | 0.571 |
| 最大回撤 | -4.01% |
| 胜率 | 51% |
V. 完整的 Python 代码
from AlgorithmImports import *
class MovingAverageCryptocurrencies(QCAlgorithm):
def Initialize(self):
self.set_start_date(2015, 1, 1)
self.set_cash(100_000)
self.symbol: Symbol = self.add_crypto('BTCUSD', Resolution.DAILY, Market.BITFINEX).symbol
self.securities[self.symbol].set_fee_model(CustomFeeModel())
self.MAs: List[SimpleMovingAverage] = [
self.SMA(self.symbol, 1, Resolution.Daily),
self.SMA(self.symbol, 2, Resolution.Daily),
self.SMA(self.symbol, 4, Resolution.Daily),
self.SMA(self.symbol, 10, Resolution.Daily),
self.SMA(self.symbol, 20, Resolution.Daily)
]
def OnData(self, slice: Slice) -> None:
if not self.symbol in slice: return
price: float = slice[self.symbol].Value
if price == 0: return
long_signal_count: int = 0
for ma in self.MAs:
if ma.IsReady:
if price > ma.Current.Value:
long_signal_count += 1
else:
self.Liquidate()
w: float = (0.1 / len(self.MAs)) * long_signal_count
self.SetHoldings(self.symbol, w)
# Custom fee model
class CustomFeeModel(FeeModel):
def GetOrderFee(self, parameters):
fee = parameters.Security.Price * parameters.Order.AbsoluteQuantity * 0.00005
return OrderFee(CashAmount(fee, "USD"))