Path: blob/master/src/strategies/SampleStrategy.py
298 views
import logging12from models.Direction import Direction3from models.ProductType import ProductType4from strategies.BaseStrategy import BaseStrategy5from utils.Utils import Utils6from trademgmt.Trade import Trade7from trademgmt.TradeManager import TradeManager89# Each strategy has to be derived from BaseStrategy10class SampleStrategy(BaseStrategy):11__instance = None1213@staticmethod14def getInstance(): # singleton class15if SampleStrategy.__instance == None:16SampleStrategy()17return SampleStrategy.__instance1819def __init__(self):20if SampleStrategy.__instance != None:21raise Exception("This class is a singleton!")22else:23SampleStrategy.__instance = self24# Call Base class constructor25super().__init__("SAMPLE")26# Initialize all the properties specific to this strategy27self.productType = ProductType.MIS28self.symbols = ["SBIN", "INFY", "TATASTEEL", "RELIANCE", "HDFCBANK", "CIPLA"]29self.slPercentage = 1.130self.targetPercentage = 2.231self.startTimestamp = Utils.getTimeOfToDay(9, 30, 0) # When to start the strategy. Default is Market start time32self.stopTimestamp = Utils.getTimeOfToDay(14, 30, 0) # This is not square off timestamp. This is the timestamp after which no new trades will be placed under this strategy but existing trades continue to be active.33self.squareOffTimestamp = Utils.getTimeOfToDay(15, 0, 0) # Square off time34self.capital = 3000 # Capital to trade (This is the margin you allocate from your broker account for this strategy)35self.leverage = 2 # 2x, 3x Etc36self.maxTradesPerDay = 3 # Max number of trades per day under this strategy37self.isFnO = False # Does this strategy trade in FnO or not38self.capitalPerSet = 0 # Applicable if isFnO is True (1 set means 1CE/1PE or 2CE/2PE etc based on your strategy logic)3940def process(self):41if len(self.trades) >= self.maxTradesPerDay:42return43# This is a sample strategy with the following logic:44# 1. If current market price > 0.5% from previous day close then create LONG trade45# 2. If current market price < 0.5% from previous day close then create SHORT trade46for symbol in self.symbols:47quote = self.getQuote(symbol)48if quote == None:49logging.error('%s: Could not get quote for %s', self.getName(), symbol)50continue51longBreakoutPrice = Utils.roundToNSEPrice(quote.close + quote.close * 0.5 / 100)52shortBreakoutPrice = Utils.roundToNSEPrice(quote.close - quote.close * 0.5 / 100)53cmp = quote.lastTradedPrice54logging.info('%s: %s => long = %f, short = %f, CMP = %f', self.getName(), symbol, longBreakoutPrice, shortBreakoutPrice, cmp)5556direction = None57breakoutPrice = 058if cmp > longBreakoutPrice:59direction = 'LONG'60breakoutPrice = longBreakoutPrice61elif cmp < shortBreakoutPrice:62direction = 'SHORT'63breakoutPrice = shortBreakoutPrice64if direction == None:65continue6667self.generateTrade(symbol, direction, breakoutPrice, cmp)686970def generateTrade(self, tradingSymbol, direction, breakoutPrice, cmp):71trade = Trade(tradingSymbol)72trade.strategy = self.getName()73trade.direction = direction74trade.productType = self.productType75trade.placeMarketOrder = True76trade.requestedEntry = breakoutPrice77trade.timestamp = Utils.getEpoch(self.startTimestamp) # setting this to strategy timestamp78trade.qty = int(self.calculateCapitalPerTrade() / breakoutPrice)79if trade.qty == 0:80trade.qty = 1 # Keep min 1 qty81if direction == 'LONG':82trade.stopLoss = Utils.roundToNSEPrice(breakoutPrice - breakoutPrice * self.slPercentage / 100)83if cmp < trade.stopLoss:84trade.stopLoss = Utils.roundToNSEPrice(cmp - cmp * 1 / 100)85else:86trade.stopLoss = Utils.roundToNSEPrice(breakoutPrice + breakoutPrice * self.slPercentage / 100)87if cmp > trade.stopLoss:88trade.stopLoss = Utils.roundToNSEPrice(cmp + cmp * 1 / 100)8990if direction == 'LONG':91trade.target = Utils.roundToNSEPrice(breakoutPrice + breakoutPrice * self.targetPercentage / 100)92else:93trade.target = Utils.roundToNSEPrice(breakoutPrice - breakoutPrice * self.targetPercentage / 100)9495trade.intradaySquareOffTimestamp = Utils.getEpoch(self.squareOffTimestamp)96# Hand over the trade to TradeManager97TradeManager.addNewTrade(trade)9899def shouldPlaceTrade(self, trade, tick):100# First call base class implementation and if it returns True then only proceed101if super().shouldPlaceTrade(trade, tick) == False:102return False103104if tick == None:105return False106107if trade.direction == Direction.LONG and tick.lastTradedPrice > trade.requestedEntry:108return True109elif trade.direction == Direction.SHORT and tick.lastTradedPrice < trade.requestedEntry:110return True111return False112113114