@@ -18,6 +18,7 @@ def __init__(self, config):
1818
1919 def read_configuration (self , config ):
2020 self .interval = config ['strategies' ]['simple_macd' ]['interval' ]
21+ self .controlledRisk = config ['ig_interface' ]['controlled_risk' ]
2122 self .timeout = 1
2223
2324 # TODO make as generic as possible and move in Strategy class
@@ -81,13 +82,17 @@ def find_trade_signal(self, broker, epic_id):
8182 limit = None
8283 stop = None
8384
85+ # Collect data from the broker interface
8486 prices = broker .get_prices (epic_id , self .interval , 30 )
85- current_bid , current_offer = broker .get_market_price (epic_id )
87+ market = broker .get_market_info (epic_id )
8688
87- if prices is None or current_bid is None or current_offer is None or 'prices' not in prices :
89+ # Safety checks before processing the epic
90+ if (prices is None or 'prices' not in prices
91+ or market is None or 'markets' in market ):
8892 logging .warn ('Strategy can`t process {}' .format (epic_id ))
8993 return TradeDirection .NONE , None , None
9094
95+ # Create a list of close prices
9196 data = []
9297 prevBid = 0
9398 for p in prices ['prices' ]:
@@ -97,6 +102,7 @@ def find_trade_signal(self, broker, epic_id):
97102 data .append (p ['closePrice' ]['bid' ])
98103 prevBid = p ['closePrice' ]['bid' ]
99104
105+ # Calculate the MACD indicator and find signals where macd cross its sma(9) average
100106 px = pd .DataFrame ({'close' : data })
101107 px ['26_ema' ] = pd .DataFrame .ewm (px ['close' ], span = 26 ).mean ()
102108 px ['12_ema' ] = pd .DataFrame .ewm (px ['close' ], span = 12 ).mean ()
@@ -106,16 +112,24 @@ def find_trade_signal(self, broker, epic_id):
106112 px ['positions' ][9 :]= np .where (px ['macd' ][9 :]>= px ['macd_signal' ][9 :],1 ,0 )
107113 px ['signals' ]= px ['positions' ].diff ()
108114
115+ # Identify the trade direction looking at the last signal
109116 if len (px ['signals' ]) > 0 and px ['signals' ].iloc [- 1 ] > 0 :
110117 tradeDirection = TradeDirection .BUY
111118 elif len (px ['signals' ]) > 0 and px ['signals' ].iloc [- 1 ] < 0 :
112119 tradeDirection = TradeDirection .SELL
113120 else :
114121 tradeDirection = TradeDirection .NONE
115122
123+ # Extract market data to calculate stop and limit values
124+ key = 'minNormalStopOrLimitDistance'
125+ if self .controlledRisk :
126+ key = 'minControlledRiskStopDistance'
127+ stop_perc = market ['dealingRules' ][key ]['value' ] + 1 # +1 to avoid rejection
128+ current_bid = market ['snapshot' ]['bid' ]
116129 limit = current_bid + percentage_of (10 , current_bid )
117- stop = current_bid - percentage_of (10 , current_bid )
130+ stop = current_bid - percentage_of (stop_perc , current_bid )
118131
132+ # Log only tradable epics
119133 if tradeDirection is not TradeDirection .NONE :
120134 logging .info ("SimpleMACD says: {} {}" .format (tradeDirection , epic_id ))
121135
0 commit comments