Quant Buffet放轻松,别过度思虑

利率动量预测外汇汇率策略

登录后收藏

回测表现

年化收益9.01%
波动率5.54%
贝塔-0.075
夏普比率1.63
胜率46%

完整 Python 代码

import data_tools
from AlgorithmImports import *
import numpy as np
class InterestRatesMomentumPredictsFXRates(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2000, 1, 1)
self.SetCash(100000)

# Country symbol and currency future symbol.
self.symbols = {
                "USD" : "not_traded", # US Dollar index Futures, Continuous Contract #1
                "EUR" : "CME_EC1", # Euro FX Futures, Continuous Contract #1
                "GBP" : "CME_BP1", # British Pound Futures, Continuous Contract #1
                "CHF" : "CME_SF1", # Swiss Franc Futures, Continuous Contract #1
                "JPY" : "CME_JY1", # Japanese Yen Futures, Continuous Contract #1
                }
# Interest rate data.
self.interest_rate = self.AddData(data_tools.InterestRate, 'InterestRate', Resolution.Daily).Symbol

self.period = 15
self.yield_difference = {}

countries = [x[0] for x in self.symbols.items()]
for i, country1 in enumerate(countries):
    for j, country2 in enumerate(countries):
        if i <= j: continue
        self.yield_difference[country1 + country2] = RollingWindow[float](self.period)
for country, currency_future in self.symbols.items():
    # Currency futures data.
    data = self.AddData(data_tools.QuantpediaFutures, currency_future, Resolution.Daily)
    data.SetLeverage(10)
    data.SetFeeModel(data_tools.CustomFeeModel())

def OnData(self, data):
if not self.Securities.ContainsKey(self.interest_rate): return

interest_rate_date = self.Securities[self.interest_rate].GetLastData()
if not interest_rate_date: return

# make sure interest data is still comming in
if (self.Time.date() - interest_rate_date.Time.date()).days >= 5:
    self.Liquidate()
    return

countries = [x[0] for x in self.symbols.items()]
signal = {}
for i, country1 in enumerate(countries):
    sub_signal = {}
    for j, country2 in enumerate(countries):
        if i <= j: continue
    
        index = country1 + country2
        yield1 = interest_rate_date[country1]
        yield2 = interest_rate_date[country2]
        diff = yield1 - yield2
        
        self.yield_difference[index].Add(diff)
        
        if self.yield_difference[index].IsReady:
            avg_diff = np.mean([x for x in self.yield_difference[index]])
            sub_signal[index] = (diff - avg_diff) / abs(avg_diff)
    
    if len(sub_signal) > 0:
        abs_percentile = np.percentile([abs(x[1]) for x in sub_signal.items()], 50)
        
        for signal_index, sig in sub_signal.items():
            iter_country1 = signal_index[:3]
            iter_country2 = signal_index[-3:]
            if abs(sig) > abs_percentile:
                if iter_country1 != 'USD':
                    iter_future1 = self.symbols[iter_country1]
                    if iter_future1 not in signal:
                        signal[iter_future1] = 0
                    signal[iter_future1] += np.sign(sig)
                    
                if iter_country2 != 'USD':
                    iter_future2 = self.symbols[iter_country2]
                    if iter_future2 not in signal:
                        signal[iter_future2] = 0
                    signal[iter_future2] -= np.sign(sig)

if len(signal) != 0:
    futures_invested = [x.Key.Value for x in self.Portfolio if x.Value.Invested]
    for currency_future in futures_invested:
        if currency_future not in signal:
            self.Liquidate(currency_future)
    
    foo = 3
    
    for currency_future, country_signal in signal.items():
        self.SetHoldings(currency_future, country_signal)