Overall Statistics
Total Trades
1664
Average Win
0.25%
Average Loss
-0.29%
Compounding Annual Return
-5.416%
Drawdown
24.900%
Expectancy
-0.048
Net Profit
-10.661%
Sharpe Ratio
-0.352
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
0.89
Alpha
-0.094
Beta
3.457
Annual Standard Deviation
0.11
Annual Variance
0.012
Information Ratio
-0.498
Tracking Error
0.11
Treynor Ratio
-0.011
Total Fees
$0.00
# https://quantpedia.com/Screener/Details/8
# Create an investment universe consisting of several currencies (15). 
# Go long 3 currencies with strongest 12 month momentum against USD and 
# go short 3 currencies with lowest 12 month momentum against USD.
import pandas as pd
from datetime import datetime
import sys 

class FXMomentumAlgorithm(QCAlgorithm):

    def Initialize(self):
        sys.setrecursionlimit(1500)
        self.SetStartDate(2017, 7, 7)  
        self.SetEndDate(datetime.now())  
        self.SetCash(100000) 
        # create a dictionary to store momentum indicators for all symbols  
        self.data = {}
        period = 33
        period1 = 12*21
        # choose 15 forex pairs
        self.symbols = ["GBPSGD", "GBPJPY", "GBPNZD", "GBPCHF",
                        "GBPAUD", "GBPUSD", "GBPCAD"
                        ]
                        
        # warm up the MOM indicator
        self.SetWarmUp(period1)
        for symbol in self.symbols:
            self.AddForex(symbol, Resolution.Minute, Market.Oanda)
            self.data[symbol] = self.MOM(symbol, period, Resolution.Hour)
        # shcedule the function to fire at the month start 
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday, DayOfWeek.Wednesday), self.TimeRules.AfterMarketOpen("GBPSGD", 30), self.Rebalance)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Friday), self.TimeRules.At(9, 0), self.Penguin)
        
    def OnData(self, data):
        pass

    def Rebalance(self):
        if self.IsWarmingUp: return
        spread = False
        if self.Securities["GBPUSD"].AskPrice - self.Securities["GBPUSD"].BidPrice <= 0.0005:
                spread = True
        top3 = pd.Series(self.data).sort_values(ascending = False)[:2]
        for kvp in self.Portfolio:
            security_hold = kvp.Value
            # liquidate the security which is no longer in the top3 momentum list
            if security_hold.Invested and (security_hold.Symbol.Value not in top3.index):
                self.Liquidate(security_hold.Symbol)
                
        low3 = pd.Series(self.data).sort_values(ascending = True)[:2]
        for abc in self.Portfolio:
            security_holdz = abc.Value
            # liquidate the security which is no longer in the low3 momentum list
            if security_holdz.Invested and (security_holdz.Symbol.Value not in low3.index):
                self.Liquidate(security_holdz.Symbol)
        
        added_symbols = []        
        for symbol in top3.index:
            if not self.Portfolio[symbol].Invested:
                added_symbols.append(symbol)
        for added in added_symbols:
            if spread:
                self.SetHoldings(added, -1/len(added_symbols))
        added_symbolz = []        
        for symbol in low3.index:
            if not self.Portfolio[symbol].Invested:
                added_symbolz.append(symbol)
        for added in added_symbolz:
            if spread:
                self.SetHoldings(added, 1/len(added_symbolz))
    def Penguin(self):
        if self.Portfolio.Invested:
            '''
            self.Log("the ATR of CADSGD are " + str(self.data["CADSGD"].Current.Value))
            self.Log("the ATR of GBPJPY are " + str(self.data["GBPJPY"].Current.Value))
            self.Log("the ATR of NZDUSD are " + str(self.data["NZDUSD"].Current.Value))
            self.Log("the ATR of EURAUD are " + str(self.data["EURAUD"].Current.Value))
            self.Log("the ATR of AUDCHF are " + str(self.data["AUDCHF"].Current.Value))'''
            self.Liquidate()