Hi Everyone

Since QC's alpha submission requirement has been changed to minute resolution or below, the bid-ask filling might cause some trouble in some existing algos or your development if you used sparser resolution before. So I made this execution model to share with you such that your spread will be tighter for less slippage, and lower error chance by extreme spreads in non-regular trading time quotes.

Enjoy!

Cheers
Louis

from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Indicators")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Algorithm.Framework")

from System import *
from QuantConnect import *
from QuantConnect.Indicators import *
from QuantConnect.Data import *
from QuantConnect.Data.Market import *
from QuantConnect.Orders import *
from QuantConnect.Algorithm import *
from QuantConnect.Algorithm.Framework import *
from QuantConnect.Algorithm.Framework.Execution import *
from QuantConnect.Algorithm.Framework.Portfolio import *


class SpreadExecutionModel(ExecutionModel):
    '''Execution model that submits orders while the current pread is tight.'''

    def __init__(self, acceptingSpreadPercent=0.005):
        '''Initializes a new instance of the SpreadExecutionModel class'''
        self.targetsCollection = PortfolioTargetCollection()
        
        # Gets or sets the maximum spread compare to current price in percentage.
        self.acceptingSpreadPercent = acceptingSpreadPercent

    def Execute(self, algorithm, targets):
        '''Executes market orders if the spread percentage to price is in desirable range.
       Args:
           algorithm: The algorithm instance
           targets: The portfolio targets'''
           
        # update the complete set of portfolio targets with the new targets
        self.targetsCollection.AddRange(targets)

        # for performance we check count value, OrderByMarginImpact and ClearFulfilled are expensive to call
        if self.targetsCollection.Count > 0:
            for target in self.targetsCollection.OrderByMarginImpact(algorithm):
                symbol = target.Symbol
                
                # calculate remaining quantity to be ordered
                unorderedQuantity = OrderSizing.GetUnorderedQuantity(algorithm, target)

                # check order entry conditions
                if unorderedQuantity != 0 and algorithm.Securities[symbol].Price > 0 and algorithm.Securities[symbol].Exchange.ExchangeOpen and abs(algorithm.Securities[symbol].AskPrice - algorithm.Securities[symbol].BidPrice)/algorithm.Securities[symbol].Price <= self.acceptingSpreadPercent:
                    algorithm.MarketOrder(symbol, unorderedQuantity)

            self.targetsCollection.ClearFulfilled(algorithm)

Author