| Overall Statistics |
|
Total Trades 8 Average Win 0.00% Average Loss 0.00% Compounding Annual Return -0.001% Drawdown 0.000% Expectancy -0.662 Net Profit 0.000% Sharpe Ratio -4.625 Probabilistic Sharpe Ratio 0.149% Loss Rate 75% Win Rate 25% Profit-Loss Ratio 0.35 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 1.637 Tracking Error 0.145 Treynor Ratio -10.516 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.SetRiskManagement(PortfolioDrawdownRiskModel(1e-7)) # Some very small drawdown threshold
def OnData(self, data):
pass
def TradeStuff(self):
# Long EURUSD
insight = Insight('EURUSD',
timedelta(days=2),
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, 1) #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 = True # Flag for whether risk model liquidated
def ManageRisk(self, algorithm, targets):
portfolioValue = algorithm.Portfolio.TotalPortfolioValue
if targets and self.isLiquidated:
self.portfolioHigh = portfolioValue
self.isLiquidated = False
# Update trailing highs of portfolio value
if portfolioValue > self.portfolioHigh:
self.portfolioHigh = portfolioValue
return []
# Liquidate portfolio if exceed drawdown
drawdown = (portfolioValue / self.portfolioHigh) - 1.0
if (drawdown < -self.maxDrawdown) or self.isLiquidated:
self.isLiquidated = True
portfolio_targets = []
for kvp in algorithm.Securities:
security = kvp.Value
if security.Invested:
portfolio_targets.append(PortfolioTarget(security.Symbol, 0))
algorithm.Log(f'{algorithm.Time} Risk Model triggered with realized {drawdown*100:.2f}% drawdown. Liquidated.')
return portfolio_targets
return []