Path: blob/master/src/strategies/BNFORB30Min.py
301 views
import logging1from datetime import datetime23from instruments.Instruments import Instruments4from models.Direction import Direction5from models.ProductType import ProductType6from strategies.BaseStrategy import BaseStrategy7from utils.Utils import Utils8from trademgmt.Trade import Trade9from trademgmt.TradeManager import TradeManager1011# Each strategy has to be derived from BaseStrategy12class BNFORB30Min(BaseStrategy):13__instance = None1415@staticmethod16def getInstance(): # singleton class17if BNFORB30Min.__instance == None:18BNFORB30Min()19return BNFORB30Min.__instance2021def __init__(self):22if BNFORB30Min.__instance != None:23raise Exception("This class is a singleton!")24else:25BNFORB30Min.__instance = self26# Call Base class constructor27super().__init__("BNFORB30Min")28# Initialize all the properties specific to this strategy29self.productType = ProductType.MIS30self.symbols = []31self.slPercentage = 032self.targetPercentage = 033self.startTimestamp = Utils.getTimeOfToDay(9, 45, 0) # When to start the strategy. Default is Market start time34self.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.35self.squareOffTimestamp = Utils.getTimeOfToDay(15, 0, 0) # Square off time36self.capital = 100000 # Capital to trade (This is the margin you allocate from your broker account for this strategy)37self.leverage = 038self.maxTradesPerDay = 1 # Max number of trades per day under this strategy39self.isFnO = True # Does this strategy trade in FnO or not40self.capitalPerSet = 100000 # Applicable if isFnO is True (1 set means 1CE/1PE or 2CE/2PE etc based on your strategy logic)4142def process(self):43now = datetime.now()44processEndTime = Utils.getTimeOfToDay(9, 50, 0)45if now < self.startTimestamp:46return47if now > processEndTime:48# We are interested in creating the symbol only between 09:45 and 09:5049# since we are not using historical candles so not aware of exact high and low of the first 30 mins50return5152if len(self.trades) >= 2:53return5455symbol = Utils.prepareMonthlyExpiryFuturesSymbol('BANKNIFTY')56quote = self.getQuote(symbol)57if quote == None:58logging.error('%s: Could not get quote for %s', self.getName(), symbol)59return6061logging.info('%s: %s => lastTradedPrice = %f', self.getName(), symbol, quote.lastTradedPrice)62self.generateTrade(symbol, Direction.LONG, quote.high, quote.low)63self.generateTrade(symbol, Direction.SHORT, quote.high, quote.low)646566def generateTrade(self, tradingSymbol, direction, high, low):67trade = Trade(tradingSymbol)68trade.strategy = self.getName()69trade.isFutures = True70trade.direction = direction71trade.productType = self.productType72trade.placeMarketOrder = True73trade.requestedEntry = high if direction == Direction.LONG else low74trade.timestamp = Utils.getEpoch(self.startTimestamp) # setting this to strategy timestamp75# Calculate lots76numLots = self.calculateLotsPerTrade()77isd = Instruments.getInstrumentDataBySymbol(tradingSymbol) # Get instrument data to know qty per lot78trade.qty = isd['lot_size'] * numLots7980trade.stopLoss = low if direction == Direction.LONG else high81slDiff = high - low82# target is 1.5 times of SL83if direction == 'LONG':84trade.target = Utils.roundToNSEPrice(trade.requestedEntry + 1.5 * slDiff)85else:86trade.target = Utils.roundToNSEPrice(trade.requestedEntry - 1.5 * slDiff)8788trade.intradaySquareOffTimestamp = Utils.getEpoch(self.squareOffTimestamp)89# Hand over the trade to TradeManager90TradeManager.addNewTrade(trade)9192def shouldPlaceTrade(self, trade, tick):93# First call base class implementation and if it returns True then only proceed94if super().shouldPlaceTrade(trade, tick) == False:95return False9697if tick == None:98return False99100if trade.direction == Direction.LONG and tick.lastTradedPrice > trade.requestedEntry:101return True102elif trade.direction == Direction.SHORT and tick.lastTradedPrice < trade.requestedEntry:103return True104return False105106107