Overall Statistics |
Total Trades 675 Average Win 0.01% Average Loss -0.02% Compounding Annual Return -4.276% Drawdown 4.100% Expectancy -0.468 Net Profit -3.318% Sharpe Ratio -1.3 Loss Rate 65% Win Rate 35% Profit-Loss Ratio 0.52 Alpha -0.069 Beta 2.174 Annual Standard Deviation 0.027 Annual Variance 0.001 Information Ratio -1.901 Tracking Error 0.027 Treynor Ratio -0.016 Total Fees $0.00 |
import numpy as np from datetime import datetime, timedelta from collections import deque from decimal import Decimal from itertools import groupby from pytz import utc UTCMIN = datetime.min.replace(tzinfo=utc) from Execution.NullExecutionModel import NullExecutionModel from Risk.NullRiskManagementModel import NullRiskManagementModel class BasicTemplateFrameworkAlgorithm(QCAlgorithmFramework): def Initialize(self): # self.SetWarmUp(10) self.SetStartDate(2018, 1, 18) #Set Start Date self.SetEndDate(2018, 10, 25) #Set End Date self.SetCash(1000) #Set Strategy Cash self.SetBrokerageModel(BrokerageName.OandaBrokerage,AccountType.Margin) self.resolution = Resolution.Daily self.UniverseSettings.Resolution = Resolution.Daily symbols = [Symbol.Create("EURUSD", SecurityType.Forex, Market.Oanda), Symbol.Create("GBPUSD", SecurityType.Forex, Market.Oanda)] self.SetUniverseSelection( ManualUniverseSelectionModel(symbols) ) self.SetAlpha(MyAlpha()) self.SetPortfolioConstruction(MyPortfolio()) self.SetExecution(MyExecution()) self.SetRiskManagement(NullRiskManagementModel()) def OnOrderEvent(self, orderEvent): if orderEvent.Status == OrderStatus.Filled: self.Log("Order Executed for: {0}".format(orderEvent.Symbol)+" | "+str(orderEvent)) pass class MyAlpha(AlphaModel): def __init__(self, prediction_interval=1): self.predictionInterval = Time.Multiply(Extensions.ToTimeSpan(Resolution.Daily), prediction_interval) def Update(self, algorithm, data): insights = [] for kvp in algorithm.Securities: Open = data[kvp.Key].Open Close = data[kvp.Key].Close algorithm.Log("{}: Open:{} Close:{}".format(str(kvp.Key), str(Open), str(Close)) ) if Open > Close: insights.append(Insight.Price(kvp.Key, self.predictionInterval, InsightDirection.Up, None, None)) algorithm.Log("self.predictionInterval: "+str(self.predictionInterval)) return insights class MyPortfolio(PortfolioConstructionModel): def __init__(self, resolution = Resolution.Daily, percent = 0.02): self.insightCollection = InsightCollection() self.removedSymbols = [] self.nextExpiryTime = UTCMIN self.rebalancingTime = UTCMIN self.rebalancingPeriod = Extensions.ToTimeSpan(resolution) self.percentage = percent def CreateTargets(self, algorithm, insights): targets = [] self.insightCollection.AddRange(insights) algorithm.Log("insightCollection "+str([str(x.Symbol)+" "+str(x.Direction) for x in self.insightCollection]) ) # Create flatten target for each security that was removed from the universe if self.removedSymbols is not None: universeDeselectionTargets = [ PortfolioTarget(symbol, 0) for symbol in self.removedSymbols ] targets.extend(universeDeselectionTargets) self.removedSymbols = None # Get insight that haven't expired of each symbol that is still in the universe activeInsights = self.insightCollection.GetActiveInsights(algorithm.UtcTime) # Get the last generated active insight for each symbol lastActiveInsights = [] for symbol, g in groupby(activeInsights, lambda x: x.Symbol): lastActiveInsights.append(sorted(g, key = lambda x: x.GeneratedTimeUtc)[-1]) percent = self.percentage errorSymbols = {} for insight in lastActiveInsights: target = PortfolioTarget.Percent(algorithm, insight.Symbol, insight.Direction * percent) if not target is None: targets.append(target) else: errorSymbols[insight.Symbol] = insight.Symbol # Get expired insights and create flatten targets for each symbol expiredInsights = self.insightCollection.RemoveExpiredInsights(algorithm.UtcTime) algorithm.Log("expiredInsights: "+str([str(x.Symbol)+" "+str(x.Direction) for x in expiredInsights]) ) expiredTargets = [] for symbol, f in groupby(expiredInsights, lambda x: x.Symbol): if not self.insightCollection.HasActiveInsights(symbol, algorithm.UtcTime) and not symbol in errorSymbols: expiredTargets.append(PortfolioTarget(symbol, 0)) continue targets.extend(expiredTargets) self.nextExpiryTime = self.insightCollection.GetNextExpiryTime() if self.nextExpiryTime is None: self.nextExpiryTime = UTCMIN # self.rebalancingTime = algorithm.UtcTime + self.rebalancingPeriod algorithm.Log("in Portfolio -targets: "+str([( str(x.Symbol) ,x.Quantity) for x in targets])) algorithm.Log("nextExpiryTime: "+str(self.nextExpiryTime)) return targets def OnSecuritiesChanged(self, algorithm, changes): '''Event fired each time the we add/remove securities from the data feed Args: algorithm: The algorithm instance that experienced the change in securities changes: The security additions and removals from the algorithm''' # Get removed symbol and invalidate them in the insight collection self.removedSymbols = [x.Symbol for x in changes.RemovedSecurities] self.insightCollection.Clear(self.removedSymbols) class MyExecution(ExecutionModel): def __init__(self, entry_pips = 5, take_profit_pips = 30): self.targetsCollection = PortfolioTargetCollection() self.entry_pips = entry_pips self.take_profit_pips = self.entry_pips + take_profit_pips def Execute(self, algorithm, targets): self.targetsCollection.AddRange(targets) algorithm.Log("in Execution -targets: "+str([( str(x.Symbol) ,x.Quantity) for x in targets])) algorithm.Log("in Execution -targetsCollection: "+str([( str(x.Symbol), x.Quantity) for x in self.targetsCollection])) algorithm.Log("in Execution -OrderByMarginImpact: "+str([( str(x.Symbol), x.Quantity) for x in self.targetsCollection.OrderByMarginImpact(algorithm)])) for target in self.targetsCollection: open_quantity = sum([x.Quantity for x in algorithm.Transactions.GetOpenOrders(target.Symbol)]) existing_quantity = algorithm.Securities[target.Symbol].Holdings.Quantity + open_quantity target_quantity = target.Quantity price = algorithm.Securities[target.Symbol].Price entry_price = 0 take_profit_price = 0 if np.sign(target_quantity) == 1: entry_price = price + Decimal(0.0005) take_profit_price = price + Decimal(0.0030) if np.sign(target_quantity) == -1: entry_price = price - Decimal(0.0005) take_profit_price = price - Decimal(0.0030) algorithm.StopMarketOrder(target.Symbol, target_quantity, entry_price, tag="where is tag shown?") algorithm.Log("__placed StopMarketOrder at: "+str(entry_price) ) algorithm.LimitOrder(target.Symbol, -1*target_quantity, take_profit_price, tag="where is tag shown?") algorithm.Log("__placed LimitOrder at: "+str(take_profit_price) )