Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sreenivasdoosa
GitHub Repository: sreenivasdoosa/sdoosa-algo-trade-python
Path: blob/master/src/strategies/SampleStrategy.py
298 views
1
import logging
2
3
from models.Direction import Direction
4
from models.ProductType import ProductType
5
from strategies.BaseStrategy import BaseStrategy
6
from utils.Utils import Utils
7
from trademgmt.Trade import Trade
8
from trademgmt.TradeManager import TradeManager
9
10
# Each strategy has to be derived from BaseStrategy
11
class SampleStrategy(BaseStrategy):
12
__instance = None
13
14
@staticmethod
15
def getInstance(): # singleton class
16
if SampleStrategy.__instance == None:
17
SampleStrategy()
18
return SampleStrategy.__instance
19
20
def __init__(self):
21
if SampleStrategy.__instance != None:
22
raise Exception("This class is a singleton!")
23
else:
24
SampleStrategy.__instance = self
25
# Call Base class constructor
26
super().__init__("SAMPLE")
27
# Initialize all the properties specific to this strategy
28
self.productType = ProductType.MIS
29
self.symbols = ["SBIN", "INFY", "TATASTEEL", "RELIANCE", "HDFCBANK", "CIPLA"]
30
self.slPercentage = 1.1
31
self.targetPercentage = 2.2
32
self.startTimestamp = Utils.getTimeOfToDay(9, 30, 0) # When to start the strategy. Default is Market start time
33
self.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.
34
self.squareOffTimestamp = Utils.getTimeOfToDay(15, 0, 0) # Square off time
35
self.capital = 3000 # Capital to trade (This is the margin you allocate from your broker account for this strategy)
36
self.leverage = 2 # 2x, 3x Etc
37
self.maxTradesPerDay = 3 # Max number of trades per day under this strategy
38
self.isFnO = False # Does this strategy trade in FnO or not
39
self.capitalPerSet = 0 # Applicable if isFnO is True (1 set means 1CE/1PE or 2CE/2PE etc based on your strategy logic)
40
41
def process(self):
42
if len(self.trades) >= self.maxTradesPerDay:
43
return
44
# This is a sample strategy with the following logic:
45
# 1. If current market price > 0.5% from previous day close then create LONG trade
46
# 2. If current market price < 0.5% from previous day close then create SHORT trade
47
for symbol in self.symbols:
48
quote = self.getQuote(symbol)
49
if quote == None:
50
logging.error('%s: Could not get quote for %s', self.getName(), symbol)
51
continue
52
longBreakoutPrice = Utils.roundToNSEPrice(quote.close + quote.close * 0.5 / 100)
53
shortBreakoutPrice = Utils.roundToNSEPrice(quote.close - quote.close * 0.5 / 100)
54
cmp = quote.lastTradedPrice
55
logging.info('%s: %s => long = %f, short = %f, CMP = %f', self.getName(), symbol, longBreakoutPrice, shortBreakoutPrice, cmp)
56
57
direction = None
58
breakoutPrice = 0
59
if cmp > longBreakoutPrice:
60
direction = 'LONG'
61
breakoutPrice = longBreakoutPrice
62
elif cmp < shortBreakoutPrice:
63
direction = 'SHORT'
64
breakoutPrice = shortBreakoutPrice
65
if direction == None:
66
continue
67
68
self.generateTrade(symbol, direction, breakoutPrice, cmp)
69
70
71
def generateTrade(self, tradingSymbol, direction, breakoutPrice, cmp):
72
trade = Trade(tradingSymbol)
73
trade.strategy = self.getName()
74
trade.direction = direction
75
trade.productType = self.productType
76
trade.placeMarketOrder = True
77
trade.requestedEntry = breakoutPrice
78
trade.timestamp = Utils.getEpoch(self.startTimestamp) # setting this to strategy timestamp
79
trade.qty = int(self.calculateCapitalPerTrade() / breakoutPrice)
80
if trade.qty == 0:
81
trade.qty = 1 # Keep min 1 qty
82
if direction == 'LONG':
83
trade.stopLoss = Utils.roundToNSEPrice(breakoutPrice - breakoutPrice * self.slPercentage / 100)
84
if cmp < trade.stopLoss:
85
trade.stopLoss = Utils.roundToNSEPrice(cmp - cmp * 1 / 100)
86
else:
87
trade.stopLoss = Utils.roundToNSEPrice(breakoutPrice + breakoutPrice * self.slPercentage / 100)
88
if cmp > trade.stopLoss:
89
trade.stopLoss = Utils.roundToNSEPrice(cmp + cmp * 1 / 100)
90
91
if direction == 'LONG':
92
trade.target = Utils.roundToNSEPrice(breakoutPrice + breakoutPrice * self.targetPercentage / 100)
93
else:
94
trade.target = Utils.roundToNSEPrice(breakoutPrice - breakoutPrice * self.targetPercentage / 100)
95
96
trade.intradaySquareOffTimestamp = Utils.getEpoch(self.squareOffTimestamp)
97
# Hand over the trade to TradeManager
98
TradeManager.addNewTrade(trade)
99
100
def shouldPlaceTrade(self, trade, tick):
101
# First call base class implementation and if it returns True then only proceed
102
if super().shouldPlaceTrade(trade, tick) == False:
103
return False
104
105
if tick == None:
106
return False
107
108
if trade.direction == Direction.LONG and tick.lastTradedPrice > trade.requestedEntry:
109
return True
110
elif trade.direction == Direction.SHORT and tick.lastTradedPrice < trade.requestedEntry:
111
return True
112
return False
113
114