Overall Statistics
Total Trades
62
Average Win
0.00%
Average Loss
0.00%
Compounding Annual Return
-0.356%
Drawdown
1.800%
Expectancy
-0.176
Net Profit
-0.089%
Sharpe Ratio
-0.061
Probabilistic Sharpe Ratio
26.423%
Loss Rate
54%
Win Rate
46%
Profit-Loss Ratio
0.77
Alpha
0.004
Beta
0.062
Annual Standard Deviation
0.032
Annual Variance
0.001
Information Ratio
0.594
Tracking Error
0.17
Treynor Ratio
-0.032
Total Fees
$0.00
Estimated Strategy Capacity
$3300000.00
Lowest Capacity Asset
NZDUSD 8G
# Forex Intraday Mean Reversion Strategy!?

import numpy as np
from datetime import timedelta
from datetime import datetime
import pandas as pd


class IntradayMR_FX(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2022, 1, 1)
        self.SetEndDate(2022, 4, 1)
        self.InitCap = 1000000
        self.SetCash(self.InitCap)
   
        self.minimumSTD = 15
        assets = ["EURUSD","GBPUSD","AUDUSD","NZDUSD","USDCHF","USDJPY","USDCAD"]
        self.pairs = [ Pair(self, ticker, self.minimumSTD) for ticker in assets ]

        self.positionSizeUSD = 100000 
        self.portval = self.Portfolio.TotalPortfolioValue  

        self.is_invested = None

        self.Settings.FreePortfolioValuePercentage = 0.02 # Cash Buffer 

        self.SetWarmUp(30,Resolution.Daily)
        
            
    def OnData(self, data):

        for pair in self.pairs:
            if not pair.std.IsReady: return
            
            symbol = pair.symbol
            ma = pair.ma.Current.Value
            std = pair.std.Current.Value
            
            open = self.Securities[symbol].Open     
            high = self.History(symbol, 2, Resolution.Daily)['high'][-1]
            low = self.History(symbol, 2, Resolution.Daily)['low'][-1]
            close = self.History(symbol, 2, Resolution.Daily)['close'][-1]
            
            if self.Portfolio[symbol].Invested:
                if not pair.Investable():
                    self.Liquidate(symbol, "Not Ready to Invest")
                elif close > self.minimumSTD:
                    self.Liquidate(symbol, "STD not in threshold")
                continue
            
            if not pair.Investable():
                continue

            if (open - low) < std and open > ma and self.Portfolio.MarginRemaining > self.positionSizeUSD:
                self.Buy(symbol, self.positionSizeUSD / self.Securities[symbol].Price)

                self.is_invested = 'long'

            if abs(open - high) > std and open < ma and self.Portfolio.MarginRemaining > self.positionSizeUSD:
                self.Sell(symbol, -(self.positionSizeUSD / self.Securities[symbol].Price))

                self.is_invested = 'short'
                
        
class Pair:
    def __init__(self, algorithm, ticker, minimumSTD): 
        self.symbol = algorithm.AddForex(ticker, Resolution.Daily, Market.Oanda).Symbol
        self.ma    = algorithm.SMA(self.symbol, 8, Resolution.Daily)
        self.std = algorithm.STD(self.symbol, 15, Resolution.Daily)
        
        self.minimumSTD = minimumSTD
        
    def Investable(self):
        return (self.std.Current.Value <= self.minimumSTD)