| Overall Statistics |
|
Total Trades 1 Average Win 0% Average Loss 0% Compounding Annual Return -0.073% Drawdown 0.000% Expectancy 0 Net Profit -0.006% Sharpe Ratio -4.647 Probabilistic Sharpe Ratio 1.981% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha -0.001 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 1.633 Tracking Error 0.145 Treynor Ratio 4.801 Total Fees $0.00 |
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Algorithm.Framework")
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Algorithm.Framework import *
from QuantConnect.Algorithm.Framework.Portfolio import PortfolioTarget
from QuantConnect.Algorithm.Framework.Risk import RiskManagementModel
class ScheduledRiskTest(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2015, 1, 1)
self.SetEndDate(2015, 2, 1)
self.SetCash(1000)
self.SetBrokerageModel(BrokerageName.OandaBrokerage, AccountType.Margin)
self.AddForex("EURUSD", Resolution.Minute, Market.Oanda)
# Emit an insight every Monday
self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday),
self.TimeRules.AfterMarketOpen('EURUSD',15),
self.TradeStuff)
self.SetPortfolioConstruction(CustomPortfolioModel())
self.SetExecution(ImmediateExecutionModel())
self.AddRiskManagement(PortfolioDrawdownRiskModel(1e-7)) # Some very small drawdown threshold
def OnData(self, data):
pass
def TradeStuff(self):
# Long EURUSD
insight = Insight('EURUSD',
timedelta(days=7),
InsightType.Price,
InsightDirection.Up,
None,
None,
None,
1
)
self.EmitInsights(insight)
class CustomPortfolioModel(PortfolioConstructionModel):
def __init__(self):
pass
def CreateTargets(self, algorithm, insights):
targets = []
for insight in insights:
targ = PortfolioTarget(insight.Symbol, insight.Direction*insight.Weight)
targets.append(targ)
return targets
class PortfolioDrawdownRiskModel(RiskManagementModel):
"""
Tracks and limits portfolio drawdowns from highest equity value. Resets trailing stops on new targets.
"""
def __init__(self, maxDrawdown=0.1):
self.maxDrawdown = maxDrawdown
self.currentTargets = set() # Tracks states of new targets
self.portfolioHigh = 0 # Tracks portfolio highs
self.isLiquidated = False # Flag for whether risk model liquidated
def ManageRisk(self, algorithm, targets):
# Reset trackers on new targets
if set(targets) != set(self.currentTargets):
self.currentTargets = set(targets)
self.portfolioHigh = 0
self.isLiquidated = False
# Update trailing highs of portfolio value
portfolioValue = algorithm.Portfolio.TotalPortfolioValue
if portfolioValue > self.portfolioHigh:
self.portfolioHigh = portfolioValue
return []
if self.portfolioHigh == 0:
return []
# Liquidate portfolio if exceed drawdown
drawdown = (portfolioValue / self.portfolioHigh) - 1.0
if (drawdown < -self.maxDrawdown) or self.isLiquidated:
if algorithm.Portfolio.Invested:
algorithm.Debug(f'{algorithm.Time} Risk Model triggered with realized {drawdown*100:.2f}% drawdown. Liquidated.')
self.isLiquidated = True
return [ PortfolioTarget(target.Symbol, 0) for target in targets]
return []