| Overall Statistics |
|
Total Trades 177 Average Win 0.12% Average Loss -0.12% Compounding Annual Return 1.781% Drawdown 3.000% Expectancy 0.304 Net Profit 2.690% Sharpe Ratio 0.497 Probabilistic Sharpe Ratio 23.025% Loss Rate 34% Win Rate 66% Profit-Loss Ratio 0.98 Alpha 0.002 Beta 0.391 Annual Standard Deviation 0.025 Annual Variance 0.001 Information Ratio -0.406 Tracking Error 0.037 Treynor Ratio 0.032 Total Fees $0.00 Estimated Strategy Capacity $890000.00 Lowest Capacity Asset EURUSD 8G |
# region imports
from AlgorithmImports import *
# endregion
class Strategy(QCAlgorithm):
def Initialize(self):
self.Pair_1 = "EURUSD"
self.holdingDays = 1
self.SetStartDate (2020, 1, 1)
self.SetEndDate(2021,7,1)
self.SetCash(10000)
self.SetBrokerageModel(BrokerageName.OandaBrokerage)
self.EURSEK = self.AddForex(self.Pair_1, Resolution.Daily, Market.Oanda)
self.symbols = [self.Pair_1]
self.prevPrices = { symbol : RollingWindow[QuoteBar](7) for symbol in self.symbols }
self.ticketPair1 = None
self.TrailingSL = 0.99
self.stop_loss_ticket = None
self.stopLossOrderFillTime = datetime.min
self.highestPair1Price = 0
def OnData(self,data):
self.Plot("PAIR1", "currprice", self.Securities[self.Pair_1].Price)
self.quantity_1 = self.CalculateOrderQuantity(self.Pair_1, 1)
for symbol in self.symbols:
if data.ContainsKey(symbol):
self.prevPrices[symbol].Add( data[symbol] )
if not all([ window.IsReady for window in self.prevPrices.values() ]):
return
Pair1_window = self.prevPrices[self.Pair_1]
Pair1_1D = Pair1_window[1].Close
Pair1_0D = Pair1_window[0].Close
if self.ticketPair1 is not None and self.UtcTime < self.ticketPair1.Time + timedelta(days=(self.holdingDays)):
return
# place orders: 1 without SL and one with Trailing SL
if self.ticketPair1 is None and self.stop_loss_ticket is None and self.Securities[self.Pair_1].Exchange.ExchangeOpen is True and Pair1_0D > Pair1_1D :
self.ticketPair1 = self.MarketOrder(self.Pair_1, 1000 )
stop_price = self.ticketPair1.AverageFillPrice * self.TrailingSL
self.stop_loss_ticket = self.StopMarketOrder(self.Pair_1, 3000, stop_price)
self.price = self.ticketPair1.AverageFillPrice
#check if Pair1 Price is higher than the latest highest Price
if self.Securities[self.Pair_1].Close > self.highestPair1Price and self.stop_loss_ticket is not None:
# if it is: save the new high to self.highestPair1Price and update stop loss
self.highestPair1Price = self.Securities[self.Pair_1].Close
updateFields = UpdateOrderFields()
updateFields.StopPrice = self.highestPair1Price * self.TrailingSL
self.stop_loss_ticket.Update(updateFields)
self.Plot("PAIR1", "high", self.highestPair1Price)
self.Plot("PAIR1", "stop", updateFields.StopPrice)
# after 4 days close ONLY the 1st order (self.TicketPair1)
if self.ticketPair1 is not None and self.Securities[self.Pair_1].Exchange.ExchangeOpen is True and self.UtcTime >= self.ticketPair1.Time + timedelta(days = 4):
self.MarketOrder(self.ticketPair1.Symbol, -self.ticketPair1.Quantity)
self.ticketPair1 = None
# if only SL position is active and yesterday price was higher than today: buy 1 position without SL
if self.stop_loss_ticket is not None and self.ticketPair1 is None and self.Securities[self.Pair_1].Exchange.ExchangeOpen is True and Pair1_0D > Pair1_1D :
self.ticketPair1 = self.MarketOrder(self.Pair_1, 1000 )
self.price = self.ticketPair1.AverageFillPrice
def OnOrderEvent(self, orderEvent):
if orderEvent.Status != OrderStatus.Filled:
return
if self.stop_loss_ticket is not None and self.stop_loss_ticket.OrderId == orderEvent.OrderId:
self.stopLossOrderFillTime = self.Time