Overall Statistics |
Total Trades 1195 Average Win 0.11% Average Loss -0.31% Compounding Annual Return 14.527% Drawdown 10.700% Expectancy 0.068 Net Profit 13.757% Sharpe Ratio 0.802 Probabilistic Sharpe Ratio 38.994% Loss Rate 22% Win Rate 78% Profit-Loss Ratio 0.36 Alpha 0.093 Beta -0.288 Annual Standard Deviation 0.135 Annual Variance 0.018 Information Ratio 1.109 Tracking Error 0.147 Treynor Ratio -0.377 Total Fees $0.00 Estimated Strategy Capacity $630000000.00 Lowest Capacity Asset HKDJPY 8G |
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. # Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from AlgorithmImports import * from sklearn.linear_model import LinearRegression class ScikitLearnLinearRegressionAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2013, 10, 7) # Set Start Date self.SetEndDate(2013, 10, 8) # Set End Date self.lookback = 30 # number of previous days for training self.SetCash(100000) # Set Strategy Cash spy = self.AddEquity("SPY", Resolution.Minute) self.symbols = [ spy.Symbol ] # In the future, we can include more symbols to the list in this way self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 28), self.Regression) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 30), self.Trade) def Regression(self): # Daily historical data is used to train the machine learning model history = self.History(self.symbols, self.lookback, Resolution.Daily) # price dictionary: key: symbol; value: historical price self.prices = {} # slope dictionary: key: symbol; value: slope self.slopes = {} for symbol in self.symbols: if not history.empty: # get historical open price self.prices[symbol] = list(history.loc[symbol.Value]['open']) # A is the design matrix A = range(self.lookback + 1) for symbol in self.symbols: if symbol in self.prices: # response Y = self.prices[symbol] # features X = np.column_stack([np.ones(len(A)), A]) # data preparation length = min(len(X), len(Y)) X = X[-length:] Y = Y[-length:] A = A[-length:] # fit the linear regression reg = LinearRegression().fit(X, Y) # run linear regression y = ax + b b = reg.intercept_ a = reg.coef_[1] # store slopes for symbols self.slopes[symbol] = a/b def Trade(self): # if there is no open price if not self.prices: return thod_buy = 0.001 # threshold of slope to buy thod_liquidate = -0.001 # threshold of slope to liquidate for holding in self.Portfolio.Values: slope = self.slopes[holding.Symbol] # liquidate when slope smaller than thod_liquidate if holding.Invested and slope < thod_liquidate: self.Liquidate(holding.Symbol) for symbol in self.symbols: # buy when slope larger than thod_buy if self.slopes[symbol] > thod_buy: self.SetHoldings(symbol, 1 / len(self.symbols)) # Your New Python File
from AlgoToolbox import AlgoToolbox ''' To use this library place this at the top: from StrategyFxScalper import StrategyFxScalper Then instantiate the function: StrategyFxScalpCustom(StrategyFxScalper): ... startegy = StrategyFxScalpCustom() strategy.Run(data) ''' # ******************************** class StrategyFxScalper: # ******************************** # ------------------------------------------------------------------------------------------------------------- def __init__(self, qcAlgo, fxGalaxy, resolution, anchor_resolution, scalp_period, anchor_period, show_debug, show_log, anchor_slots): #, trade_units): # ------------------------------------------------------------------------------------------------------------- self.buy_flag = 0 self.sell_flag = 0 self.limitOrderTicket = None self.profitTargetOrderTicket = None self.stopLossOrderTicket = None self.scalp_ema_fast = 0 self.scalp_ema_slow = 0 self.anchor_ema_fast = 0 self.anchor_ema_slow = 0 self.qcAlgo = qcAlgo self.fxGalaxy = fxGalaxy self.BrickData = {} self.fxHoldingCoeff = 1 / len(fxGalaxy) self.resolution = resolution self.anchorResolution = anchor_resolution self.scalp_period = scalp_period self.anchor_period = anchor_period self.anchor_max_slots = anchor_slots #self.trade_units_amount = trade_units self.holding_value = 0 self.showDebug = show_debug self.showLog = show_log self.toolbox = AlgoToolbox(self.qcAlgo, self.showDebug, self.showLog) # ------------------------------------------------------------------------------------------------------------- def Run(self, data, scalp_call = False, anchor_call = False): # ------------------------------------------------------------------------------------------------------------- # validation # exit if warming up if self.qcAlgo.IsWarmingUp: return # init ctxData = data if ctxData is None: ctxData = self.BrickData # loop through all currencies in the galaxy for fxStarBrick in self.fxGalaxy.values(): # assign current strategy fxStarBrick.strategy = self # debug if needed if self.showDebug: if scalp_call or anchor_call: # debug for scalp/anchor live calls only! if fxStarBrick.IsChartHour(ctxData.Time): # debug for the chart time only self.debugRunFx(ctxData, fxStarBrick) # save brick data msg_no_brick_data = "No data for " + fxStarBrick.symbol.Value + "!!! Stop Run-Workflow ..."; err_no_brick_data = "ERROR: No data for " + fxStarBrick.symbol.Value + "!!! Stop Run-Workflow. Error-Message: "; data_exists = ctxData.ContainsKey(fxStarBrick.symbol) if data_exists: #try: self.BrickData = ctxData # live-run strategy for actual currency (live) if not scalp_call and not anchor_call: self.RunFx(ctxData, fxStarBrick) # live-run strategy for actual currency (scalp period) if allowed if scalp_call: self.RunFxScalp(ctxData, fxStarBrick) # live-run strategy for actual currency (anchor period) if allowed if anchor_call: self.RunFxAnchor(ctxData, fxStarBrick) #except: # # EXIT IF NO SYMBOL-DATA!!! # self.apriori_debug(err_no_brick_data + sys.exc_info()[0]) # self.apriori_log(err_no_brick_data + sys.exc_info()[0]) # return else: # EXIT IF NO SYMBOL-DATA!!! self.apriori_log(msg_no_brick_data) self.apriori_debug(msg_no_brick_data) return # ------------------------------------------------------------------------------------------------------------- def RunScalp(self, fxBrick): # ------------------------------------------------------------------------------------------------------------- # validation # exit if warming up if self.qcAlgo.IsWarmingUp: return # go! self.RunFxScalp(self.BrickData, fxBrick) # ------------------------------------------------------------------------------------------------------------- def RunAnchor(self, fxBrick): # ------------------------------------------------------------------------------------------------------------- # validation # exit if warming up if self.qcAlgo.IsWarmingUp: return # go! self.RunFxAnchor(self.BrickData, fxBrick) # base (override in custom) # ------------------------------------------------------------------------------------------------------------- def RunFx(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # init fxBrick.UpdateScalpFluentData(data) fxBrick.UpdateAnchorFluentData(data) # go! pass # base (override in custom) # ------------------------------------------------------------------------------------------------------------- def RunFxScalp(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # debug if needed if self.showDebug: self.debugRunFx(data, fxBrick) # init fxBrick.ResetScalpFluentData() # go! # check trades self.CheckTradeRules(data, fxBrick) # ------------------------------------------------------------------------------------------------------------- def CheckTradeRules(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- fxBrick.Check_Trade_Rules(data) # base (override in custom) # ------------------------------------------------------------------------------------------------------------- def RunFxAnchor(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # debug if needed if self.showDebug: self.debugRunFx(data, fxBrick) # init fxBrick.ResetAnchorFluentData() fxBrick.AnchorIsWarmedUp() # go! pass # **************************************************** # * TRADE RULES REGION (BASE / BEGIN) * # **************************************************** # ------------------------------------------------------------------------------------------------------------- def OnTrigger_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnTrigger_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnTriggerDrop_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnTriggerDrop_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnEntry_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnEntry_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnEntry_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnExit_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnExit_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnStopLossAndTakeProfit_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnStopLossAndTakeProfit_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnFinishTrade_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnFinishTrade_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnStopLoss_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnStopLoss_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnTradeContinue_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnTradeContinue_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- pass # TODO 1: Execute Rule # TODO 2: Plot Data if executed # **************************************************** # * TRADE RULES REGION TRADE RULES (BASE / END) * # **************************************************** # ****************************************************** # * TRADE-ACTION RULES REGION TRADE RULES (BASE / BEGIN) * # ****************************************************** # ------------------------------------------------------------------------------------------------------------- def OnTradeOpen_Long_Holdings(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- if self.qcAlgo.emit_trades: # init fxBrick.trade_action("OPEN_LONG") # BUY via SetHoldings() self.holding_value = 1 * self.qcAlgo.forex_leverage * self.qcAlgo.cash_max_ratio * fxBrick.weight self.qcAlgo.SetHoldings(fxBrick.symbol, self.holding_value) fxBrick.Emit_Insight() # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnTradeOpen_Long(self, data, fxBrick, set_limits=True): # ------------------------------------------------------------------------------------------------------------- if self.qcAlgo.emit_trades: # reset limits fxBrick.reset_limits() # !!! prevent initial canceling of the limit orders !!! #fxBrick.veto_cancel_orders() # init fxBrick.trade_action("OPEN_LONG") price = fxBrick.data.Close # set absolute open level fxBrick.trade_abs_start_level = price fxBrick.trade_abs_stop_level = 0 # BUY via order (LONG) # get holgig coeffitient self.holding_value = 1 * self.qcAlgo.forex_leverage * self.qcAlgo.cash_max_ratio * fxBrick.weight # get weighted rounded quantity quantity = (self.qcAlgo.Portfolio.Cash / price) * self.holding_value rounded_quantity = fxBrick.GetRoundedOrderSize(quantity) # place long order (buy) self.qcAlgo.Buy(fxBrick.symbol, rounded_quantity) if set_limits: # calc by PIP rounde price take_profit = self.pip_round(fxBrick.trade_take_profit) stop_loss = self.pip_round(fxBrick.stop_loss_level) # take profit long fxBrick.ProfitTarget = self.qcAlgo.LimitOrder(fxBrick.symbol, -rounded_quantity, take_profit) # stop loss long fxBrick.StopLoss = self.qcAlgo.StopMarketOrder(fxBrick.symbol, -rounded_quantity, stop_loss) fxBrick.Emit_Insight() # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnTradeClose_Long(self, data, fxBrick, closeRatio = 1): # closeRatio = 1 - close all holdings, 0.5 - close 50% of holdings, 0 - nothing to close # ------------------------------------------------------------------------------------------------------------- # avoid part closing on 1. exit (part-close) if closeRatio < 1 and not self.qcAlgo.exit_1_close: return # init price = fxBrick.data.Close # set absolute open level fxBrick.trade_abs_stop_level = price if self.qcAlgo.emit_trades: # close trade on given ratio fxBrick.trade_action("CLOSE_LONG_" + str(closeRatio * 100) + "_PERCENT") self.trade_close(data, fxBrick, closeRatio) fxBrick.Emit_Insight() # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnTradeOpen_Short_Holdings(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- if self.qcAlgo.emit_trades: fxBrick.trade_action("OPEN_SHORT") # SELL via SetHoldings() self.holding_value = -1 * self.qcAlgo.forex_leverage * self.qcAlgo.cash_max_ratio * fxBrick.weight self.qcAlgo.SetHoldings(fxBrick.symbol, self.holding_value) fxBrick.Emit_Insight() # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnTradeOpen_Short(self, data, fxBrick, set_limits=True): # ------------------------------------------------------------------------------------------------------------- if self.qcAlgo.emit_trades: # reset limits fxBrick.reset_limits() # !!! prevent initial canceling of the limit orders !!! #fxBrick.veto_cancel_orders() # init fxBrick.trade_action("OPEN_SHORT") price = fxBrick.data.Close # set absolute open level fxBrick.trade_abs_start_level = price fxBrick.trade_abs_stop_level = 0 # SELL via order (SHORT) # get holgig coeffitient self.holding_value = self.qcAlgo.forex_leverage * self.qcAlgo.cash_max_ratio * fxBrick.weight # get weighted rounded quantity quantity = (self.qcAlgo.Portfolio.Cash / price) * self.holding_value rounded_quantity = fxBrick.GetRoundedOrderSize(quantity) # place short order (sell) self.qcAlgo.Sell(fxBrick.symbol, rounded_quantity) if set_limits: # calc by PIP rounde price take_profit = self.pip_round(fxBrick.trade_take_profit) stop_loss = self.pip_round(fxBrick.stop_loss_level) # take profit short fxBrick.ProfitTarget = self.qcAlgo.LimitOrder(fxBrick.symbol, rounded_quantity, take_profit) # stop loss short fxBrick.StopLoss = self.qcAlgo.StopMarketOrder(fxBrick.symbol, rounded_quantity, stop_loss) fxBrick.Emit_Insight() # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def OnTradeClose_Short(self, data, fxBrick, closeRatio = 1): # closeRatio = 1 - close all holdings, 0.5 - close 50% of holdings, 0 - nothing to close # ------------------------------------------------------------------------------------------------------------- # avoid part closing on 1. exit (part-close) if closeRatio < 1 and not self.qcAlgo.exit_1_close: return # init price = fxBrick.data.Close # set absolute open level fxBrick.trade_abs_stop_level = price if self.qcAlgo.emit_trades: # adjust short coeff if self.holding_value > 0: self.holding_value = -1 * self.holding_value # close trade on given ratio fxBrick.trade_action("CLOSE_SHORT_" + str(closeRatio * 100) + "_PERCENT") self.trade_close(data, fxBrick, closeRatio) fxBrick.Emit_Insight() # TODO 1: Execute Rule # TODO 2: Plot Data if executed # ------------------------------------------------------------------------------------------------------------- def trade_close(self, data, fxBrick, closeRatio = 1): # closeRatio = 1 - close all holdings, 0.5 - close 50% of holdings, 0 - nothing to close # ------------------------------------------------------------------------------------------------------------- current_holding = 1 - closeRatio if current_holding < 0: current_holding = 0 if current_holding > 1: current_holding = 1 # re-balance holding coefficient self.holding_value = current_holding * self.holding_value # close via SetHoldings() self.qcAlgo.SetHoldings(fxBrick.symbol, self.holding_value) # get profit benchmarks fxBrick.get_profit_benchmarks() # ****************************************************** # * TRADE-ACTION RULES REGION TRADE RULES (BASE / END) * # ****************************************************** # ------------------------------------------------------------------------------------------------------------- def debugRunFx(self, bigData, fxStarBrick): # ------------------------------------------------------------------------------------------------------------- try: data = bigData[fxStarBrick.symbol] # validation # exit if chart is disabled if not fxStarBrick.IsChartTime(data.Time): return # go! self.debug("===================================================" ) self.debug("Run:" ) self.debug("Brick-Data: " + str(data.Time) + " : " + str(fxStarBrick.symbol)) self.debug("Current OHLC: " + str(data.Open) + " / " + str(data.High) + " / " \ + str(data.Low) + " / " + str(data.Close)) self.debug("Fluent-Anchor OHLC: " \ + str(fxStarBrick.anchor_fluent_open) + " / " \ + str(fxStarBrick.anchor_fluent_high) + " / " \ + str(fxStarBrick.anchor_fluent_low) + " / " \ + str(fxStarBrick.anchor_fluent_close)) for idx in range(fxStarBrick.scalp_max_slots): self.debug("TS-"+str(idx)+": " + str(fxStarBrick.scalpQuoteBar_RollingWindow[idx].Time)) self.debug("S-RW-"+str(idx)+": " + str(fxStarBrick.scalpQuoteBar_RollingWindow[idx])) self.debug("-----------------------------------------------" ) self.debug("Scalp Indicators:") for ind_rw_key in fxStarBrick.scalpIndicators_RollingWindows: self.debug(str("S-IND:" + ind_rw_key)) rw = fxStarBrick.scalpIndicators_RollingWindows[ind_rw_key] # show current indicator rolling window for current currency for i in range(fxStarBrick.scalp_max_slots + 1): self.debug(str(rw[i])) self.debug("-------------------------------------------------------------------------------" ) for idx in range(fxStarBrick.anchor_max_slots): self.debug("TA-"+str(idx)+": " + str(fxStarBrick.anchorQuoteBar_RollingWindow[idx].Time)) self.debug("A-RW-"+str(idx)+": " + str(fxStarBrick.anchorQuoteBar_RollingWindow[idx])) self.debug("-----------------------------------------------" ) self.debug("Anchor Indicators:") for ind_rw_key in fxStarBrick.anchorIndicators_RollingWindows.keys(): self.debug(str("A-IND:" + ind_rw_key)) rw = fxStarBrick.anchorIndicators_RollingWindows[ind_rw_key] # show current indicator rolling window for current currency for i in range(fxStarBrick.anchor_max_slots + 1): self.debug(str(rw[i])) self.debug("-------------------------------------------------------------------------------" ) except: self.debug("Error debugRunFx() with" + str(fxStarBrick.symbol)) # ------------------------------------------------------------------------------------------------------------- def debug(self, msg): # ------------------------------------------------------------------------------------------------------------- self.toolbox.show_debug(msg) # ------------------------------------------------------------------------------------------------------------- def log(self, msg): # ------------------------------------------------------------------------------------------------------------- self.toolbox.show_log(msg) # ------------------------------------------------------------------------------------------------------------- def Debug(self, msg): # ------------------------------------------------------------------------------------------------------------- self.toolbox.show_debug(msg) # ------------------------------------------------------------------------------------------------------------- def apriori_debug(self, msg): # ------------------------------------------------------------------------------------------------------------- self.toolbox.Debug(msg) # ------------------------------------------------------------------------------------------------------------- def apriori_log(self, msg): # ------------------------------------------------------------------------------------------------------------- self.toolbox.Log(msg) # ------------------------------------------------------------------------------------------------------------- def pip_round(self, price): # ------------------------------------------------------------------------------------------------------------- return self.toolbox.pip_round(price) # ********************************* # * PLOT REGION (BEGIN) * # ********************************* # ------------------------------------------------------------------------------------------------------------- def plot_scalp_chart(self, fxBrick, bar): # ------------------------------------------------------------------------------------------------------------- self.plot_price_chart(fxBrick.scalp_chart.Name, fxBrick, bar) # ------------------------------------------------------------------------------------------------------------- def plot_anchor_chart(self, fxBrick, bar): # ------------------------------------------------------------------------------------------------------------- self.plot_price_chart(fxBrick.anchor_chart.Name, fxBrick, bar) # ------------------------------------------------------------------------------------------------------------- def plot_scalp_ema_cross(self, fxBrick, value): # ------------------------------------------------------------------------------------------------------------- self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_ema_cross_point, value) # ------------------------------------------------------------------------------------------------------------- def plot_anchor_ema_cross(self, fxBrick, value): # ------------------------------------------------------------------------------------------------------------- self.plot(fxBrick.anchor_chart.Name, fxBrick.price_chart_serial_ema_cross_point, value) # ------------------------------------------------------------------------------------------------------------- def plot_price_chart(self, chart_name, fxBrick, bar): # ------------------------------------------------------------------------------------------------------------- self.plot(chart_name, fxBrick.price_chart_serial_open, bar.Open) self.plot(chart_name, fxBrick.price_chart_serial_close, bar.Close) self.plot(chart_name, fxBrick.price_chart_serial_close_consolidated, bar.Close) self.plot(chart_name, fxBrick.price_chart_serial_open_price_point, bar.Open) self.plot(chart_name, fxBrick.price_chart_serial_high_price_point, bar.High) self.plot(chart_name, fxBrick.price_chart_serial_low_price_point, bar.Low) self.plot(chart_name, fxBrick.price_chart_serial_close_price_point, bar.Close) # ------------------------------------------------------------------------------------------------------------- def plot_trigger(self, fxBrick, value, isShort): # ------------------------------------------------------------------------------------------------------------- if isShort: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_short_trigger_point, value) else: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_long_trigger_point, value) # ------------------------------------------------------------------------------------------------------------- def plot_entry(self, fxBrick, value, isShort, isPoint): # ------------------------------------------------------------------------------------------------------------- if isShort: if isPoint: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_short_entry_point, value) else: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_short_entry, value) else: if isPoint: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_long_entry_point, value) else: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_long_entry, value) # ------------------------------------------------------------------------------------------------------------- def plot_stop_loss(self, fxBrick, value, isShort, isPoint): # ------------------------------------------------------------------------------------------------------------- if isShort: if isPoint: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_short_stop_loss_point, value) else: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_short_stop_loss, value) else: if isPoint: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_long_stop_loss_point, value) else: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_long_stop_loss, value) # ------------------------------------------------------------------------------------------------------------- def plot_exit_1(self, fxBrick, value, isShort, isPoint): # ------------------------------------------------------------------------------------------------------------- if isShort: if isPoint: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_short_exit_1_point, value) else: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_short_exit_1, value) else: if isPoint: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_long_exit_1_point, value) else: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_long_exit_1, value) # ------------------------------------------------------------------------------------------------------------- def plot_exit_2(self, fxBrick, value, isShort, isPoint): # ------------------------------------------------------------------------------------------------------------- if isShort: if isPoint: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_short_exit_2_point, value) else: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_short_exit_2, value) else: if isPoint: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_long_exit_2_point, value) else: self.plot(fxBrick.scalp_chart.Name, fxBrick.price_chart_serial_long_exit_2, value) # ------------------------------------------------------------------------------------------------------------- def plot(self, chart_name, serial_name, value): # ------------------------------------------------------------------------------------------------------------- self.qcAlgo.Plot(chart_name, serial_name, value) # ********************************* # * PLOT REGION (END) * # *********************************
# custom inpots from ForexTrendBase import ForexTrendBase from FxRedBirdBrick_South import FxRedBirdBrick_South from StrategyFxRedBird_South import StrategyFxRedBird_South # ******************************** class ForexRedBird_South(ForexTrendBase): # ******************************** # ----------------------------------------------------------- # Initializer (Cosntructor) # ------------------------------------------------------------ def Initializie(self): # ------------------------------------------------------------ # base initializer super(ForexRedBird_South, self).Initializie() # main initializer self.SetBrokerageModel(AlphaStreamsBrokerageModel()) # setup forex brokerages if self.Broker == "FXCM": self.SetBrokerageModel(BrokerageName.FxcmBrokerage) else: self.SetBrokerageModel(BrokerageName.OandaBrokerage) # ------------------ # custom selector method # ----------------------------------------------------------------------------------------------------------- def selectStrategy(self): # ----------------------------------------------------------------------------------------------------------- return StrategyFxRedBird_South(self, self.forex_galaxy, self.resolution, self.anchorResolution, self.scalp_period, self.anchor_period, self.show_debug, self.show_log, self.anchor_max_slots) # ------------------ # custom selector # ----------------------------------------------------------------------------------------------------------- def selectGalaxyStars(self): # ----------------------------------------------------------------------------------------------------------- # init strategy galaxy selected_galaxy = self.selectGalaxy(self.get_str_param("selected_galaxy")) #self.toolbox.show_log result = {} # create galaxy of fx symbol bricks for fxTickerStar in selected_galaxy: fxStarWeight = selected_galaxy[fxTickerStar] result[fxTickerStar] = FxRedBirdBrick_South(self, fxTickerStar, fxStarWeight, self.resolution, self.anchorResolution, self.scalp_period, self.anchor_period, self.show_debug, self.show_log, self.anchor_max_slots, self.scalp_max_slots) # finally return result # ----------------------------------------------------------------------------------------------------------- def OnOrderEvent(self, orderEvent): # ----------------------------------------------------------------------------------------------------------- return ''' # init filledOrderId = orderEvent.OrderId overrule_veto = False # looping all symbol bricks for fxBrickSymbol in self.forex_galaxy: if fxBrickSymbol == str(orderEvent.Symbol): fxBrick = self.forex_galaxy[fxBrickSymbol] #if fxBrick.Ignore_Cancel_Event: # if fxBrick.trade_state == fxBrick.STAND_BY: # return #else: show_action = False #not fxBrick.Ignore_Cancel_Event state_reset = False #not fxBrick.Ignore_Cancel_Event # If the ProfitTarget order was filled, close the StopLoss order if fxBrick.match_order(fxBrick.ProfitTarget, filledOrderId): if fxBrick.cancel_stop_loss(overrule_veto, show_action, state_reset): fxBrick.trade_action_filled_tp_cancel_sl() # If the StopLoss order was filled, close the ProfitTarget if fxBrick.match_order(fxBrick.StopLoss, filledOrderId): if fxBrick.cancel_take_profit(overrule_veto, show_action, state_reset): fxBrick.trade_action_filled_sl_cancel_tp() '''
from ForexSymbolBrick import ForexSymbolBrick from QuantConnect.Data import * from QuantConnect import * class FxRedBirdBrick_South(ForexSymbolBrick): def __init__(self,qcAlgo, ticker, weight, resolution, anchorResolution, scalpPeriod, anchorPeriod, showDebug = False, showLog = False, anchor_max_slots = 24, scalp_max_slots = 10): super(FxRedBirdBrick_South, self).__init__(qcAlgo, ticker, weight, resolution, anchorResolution, scalpPeriod, anchorPeriod, \ showDebug, showLog, anchor_max_slots, scalp_max_slots) # params candidates self.delta_accelerate_max_ratio = 3 #5 #3 #2.7 # 0 deactivate self.orange_risk_invert_weight = 5 self.red_risk_shift_percent = 10 self.exit2_level_min_steps_count = -1 #7 # deactivate = -1 self.RCT_pullback_trailing_stop_ratio = 0 # 0 = deactivate # trailing props self.TTG_trailing_trade_gain = 0 self.TLG_trailing_live_gain = 0 self.LLo_lowest_low_open = 0 self.LLc_lowest_low_close = 0 self.HHo_highest_high_open = 0 self.HHc_highest_high_close = 0 self.LVo_live_open = 0 self.LVc_live_close = 0 # delta props self.minor_delta = 0 self.major_delta = 0 self.delta_acceleration = 0 # semafor props self.IsLevel_Exit_1_Semafor = False self.IsLevel_Exit_2_Semafor = False self.exit2_level_steps_count = 0 # trade control props self.trade_lowest_low = 0 self.trade_highest_high = 0 self.lowest_low_last_trailng_qbars = 0 self.highest_high_last_trailng_qbars = 0 self.touch_level = 0 self.exit_1_rate = self.qcAlgo.exit_1_rate # machine states self.EXIT_1_SHORT = self.EXIT_1_SHORT_BASE self.EXIT_1_LONG = self.EXIT_1_LONG_BASE self.EXIT_2_SHORT = self.EXIT_2_SHORT_BASE self.EXIT_2_LONG = self.EXIT_2_LONG_BASE # fast-ema trigger tolerance to bar touch delta (pips) self.bar_to_fast_indicator_touch_delta_trigger_pips = self.qcAlgo.touch_trigger_pip_tolerance # slow-ema stopper toleracnce to bar touch delta (pips) self.bar_to_slow_inidcator_touch_delta_stopper_pips = self.qcAlgo.touch_trigger_pip_tolerance # * TRADE RULES/EVENTS REGION (CUSTOM / BEGIN) * def calc_trade_props(self, rolling_window_qoute_bar, lookback_steps, bar_touch_margins, trigger_pips_up, trigger_pips_down): # long trade props if self.is_long_trade: self.stop_loss_level = self.touch_level self.trade_highest_high = self.Get_Trade_Scalp_Highest_High(rolling_window_qoute_bar, lookback_steps, bar_touch_margins) self.entry_level = self.plus_pip(self.trade_highest_high, trigger_pips_up) self.trade_risk = abs(self.entry_level - self.stop_loss_level) self.trade_break_even = self.entry_level + self.trade_risk self.trade_exit = self.trade_break_even + self.trade_risk self.trade_take_profit = self.trade_exit # short trade props if self.is_short_trade: self.stop_loss_level = self.touch_level self.trade_lowest_low = self.Get_Trade_Scalp_Lowest_Low(rolling_window_qoute_bar, lookback_steps, bar_touch_margins) self.entry_level = self.plus_pip(self.trade_lowest_low, trigger_pips_down) self.trade_risk = abs(self.entry_level - self.stop_loss_level) self.trade_break_even = self.entry_level - self.trade_risk self.trade_exit = self.trade_break_even - self.trade_risk self.trade_take_profit = self.trade_exit def invert_break_even(self): # long trade props if self.is_long_trade: self.trade_break_even = self.entry_level - self.orange_risk_invert_weight * self.trade_risk # short trade props if self.is_short_trade: self.trade_break_even = self.entry_level + self.orange_risk_invert_weight * self.trade_risk def calc_on_break_even(self): # common trade props (short/long) self.stop_loss_level = self.entry_level # self.trade_break_even = 0 def calc_diff_range(self, rw_qb, d_idx, u_idx): o = 0 c = 0 for i in range(d_idx, u_idx): if self.is_long_trade: if o == 0 or o > rw_qb[i].Open: o = rw_qb[i].Open if c == 0 or c < rw_qb[i].Close: c = rw_qb[i].Close if self.is_short_trade: if o == 0 or o < rw_qb[i].Open: o = rw_qb[i].Open if c == 0 or c > rw_qb[i].Close: c = rw_qb[i].Close return o, c def calc_diff_delta(self, rw_qb): # init a_len_major = rw_qb.Size a_len_minor = int(a_len_major / 2) # go! minor_o, minor_c = self.calc_diff_range(rw_qb, 0, a_len_minor) major_o, major_c = self.calc_diff_range(rw_qb, a_len_minor, a_len_major) self.minor_delta = minor_c - minor_o self.major_delta = major_c - major_o if self.minor_delta != 0: self.delta_acceleration = abs(self.major_delta / self.minor_delta) else: self.delta_acceleration = 0 def Is_Support_Level(self, rw_qb): if self.delta_accelerate_max_ratio == 0: return False else: self.calc_diff_delta(rw_qb) return self.major_delta < 0 and self.delta_acceleration > self.delta_accelerate_max_ratio #return self.delta_acceleration > self.delta_accelerate_max_ratio def Is_Resistance_Level(self, rw_qb): if self.delta_accelerate_max_ratio == 0: return False else: self.calc_diff_delta(rw_qb) return self.major_delta > 0 and self.delta_acceleration > self.delta_accelerate_max_ratio #return self.delta_acceleration > self.delta_accelerate_max_ratio def calc_rolling_trade_props(self, rolling_window_qoute_bar, lookback_steps, bar_touch_margins, trigger_pips_up, trigger_pips_down): force_open_close_touch_margins = "open_close" # init self.oc_lowest_low_last_trailng_qbars = self.Get_Trade_Scalp_Lowest_Low(rolling_window_qoute_bar, lookback_steps, force_open_close_touch_margins) self.oc_highest_high_last_trailng_qbars = self.Get_Trade_Scalp_Highest_High(rolling_window_qoute_bar, lookback_steps, force_open_close_touch_margins) self.TTG_trailing_trade_gain = abs(self.oc_highest_high_last_trailng_qbars - self.oc_lowest_low_last_trailng_qbars) self.TLG_trailing_live_gain = self.scalp_fluent_close # LONG trailing stop loss if self.trade_state == self.EXIT_1_LONG: self.lowest_low_last_trailng_qbars = self.Get_Trade_Scalp_Lowest_Low(rolling_window_qoute_bar, lookback_steps, bar_touch_margins) self.stop_loss_level = self.plus_pip(self.lowest_low_last_trailng_qbars, trigger_pips_down) self.trade_exit = 0 # exit via stop_loss only, while in trailing_exit-mode self.trade_take_profit = self.trade_exit # SHORT trailing stop loss if self.trade_state == self.EXIT_1_SHORT: self.highest_high_last_trailng_qbars = self.Get_Trade_Scalp_Highest_High(rolling_window_qoute_bar, lookback_steps, bar_touch_margins) self.stop_loss_level = self.plus_pip(self.highest_high_last_trailng_qbars, trigger_pips_up) self.trade_exit = 0 # exit via stop_loss only, while in trailing_exit-mode self.trade_take_profit = self.trade_exit # calc lookback profit def update_hh_ll_limits(self): #init live_s_o = self.scalp_fluent_open live_s_c = self.scalp_fluent_close LLo = self.LLo_lowest_low_open LLc = self.LLc_lowest_low_close HHo = self.HHo_highest_high_open HHc = self.HHc_highest_high_close #go! self.LVo_live_open = live_s_o self.LVc_live_close = live_s_c if self.is_long_trade: if LLo == 0 or LLo > live_s_o: self.LLo_lowest_low_open = live_s_o if HHc == 0 or HHc < live_s_c: self.HHc_highest_high_close = live_s_c if self.is_short_trade: if LLc == 0 or LLc > live_s_c: self.LLc_lowest_low_close = live_s_c if HHo == 0 or HHo < live_s_o: self.HHo_highest_high_open = live_s_o def Is_Pullback_Trailing_Exit(self): # init result = False # compare # long trade props if self.is_long_trade: if self.LVc_live_close < self.LVo_live_open: self.TLG_trailing_live_gain = self.HHc_highest_high_close - self.LVc_live_close self.TTG_trailing_trade_gain = self.HHc_highest_high_close - self.LLo_lowest_low_open result = self.LLo_lowest_low_open > 0 and self.HHc_highest_high_close > 0 \ and self.LVo_live_open > self.LLo_lowest_low_open \ and abs(self.TLG_trailing_live_gain / self.TTG_trailing_trade_gain) > self.RCT_pullback_trailing_stop_ratio # short trade props if self.is_short_trade: if self.LVc_live_close > self.LVo_live_open: self.TLG_trailing_live_gain = self.LVc_live_close - self.LLc_lowest_low_close self.TTG_trailing_trade_gain = self.HHo_highest_high_open - self.LLc_lowest_low_close result = self.HHo_highest_high_open > 0 and self.LLc_lowest_low_close > 0 \ and self.LVo_live_open < self.HHo_highest_high_open \ and abs(self.TLG_trailing_live_gain / self.TTG_trailing_trade_gain) > self.RCT_pullback_trailing_stop_ratio # finally return result def Check_Trade_Rules(self, data): # base super(FxRedBirdBrick_South, self).Check_Trade_Rules(data) # init environment vars rw_ai_fast = self.anchorIndicators_RollingWindows["ema_8_anchor"] rw_ai_slow = self.anchorIndicators_RollingWindows["ema_21_anchor"] rw_si_fast = self.scalpIndicators_RollingWindows["ema_8_scalp"] rw_si_slow = self.scalpIndicators_RollingWindows["ema_21_scalp"] rw_a_qb = self.anchorQuoteBar_RollingWindow rw_s_qb = self.scalpQuoteBar_RollingWindow trailing_exit_stop_bars_count = self.qcAlgo.trailing_exit_stop_loss_bars live_s_time = self.scalp_fluent_time live_s_o = self.scalp_fluent_open live_s_h = self.scalp_fluent_high live_s_l = self.scalp_fluent_low live_s_c = self.scalp_fluent_close live_s_value = live_s_c post_s_o = rw_s_qb[0].Open post_s_h = rw_s_qb[0].High post_s_l = rw_s_qb[0].Low post_s_c = rw_s_qb[0].Close prev_s_o = rw_s_qb[1].Open prev_s_h = rw_s_qb[1].High prev_s_l = rw_s_qb[1].Low prev_s_c = rw_s_qb[1].Close live_a_time = self.anchor_fluent_time live_a_o = self.anchor_fluent_open live_a_h = self.anchor_fluent_high live_a_l = self.anchor_fluent_low live_a_c = self.anchor_fluent_close live_a_value = live_a_c live_ai_fast = self.anchor_ema_current_value(8) live_ai_slow = self.anchor_ema_current_value(21) live_si_fast = self.scalp_ema_current_value(8) live_si_mid = self.scalp_ema_current_value(13) live_si_slow = self.scalp_ema_current_value(21) s_narrow = self.is_narrow_ema_scalp s_delta_pips = self.scalp_emas_pips_delta s_delta_min_pips = self.qcAlgo.scalp_delta_min_pips a_delta = self.anchor_emas_pips_delta a_delta_min_pips = self.qcAlgo.anchor_delta_min_pips bar_touch_margins = self.qcAlgo.bar_touch_margins tolerance = self.qcAlgo.touch_trigger_pip_tolerance trigger_touch_tolerance = self.bar_to_fast_indicator_touch_delta_trigger_pips stopper_touch_tolerance = self.bar_to_slow_inidcator_touch_delta_stopper_pips trigger_pips_up = self.qcAlgo.pullback_trigger_pips_up trigger_pips_down = self.qcAlgo.pullback_trigger_pips_down exit_trailing = self.qcAlgo.exit_strategy_trailing_exit exit_break_even = self.qcAlgo.exit_strategy_break_even_exit take_profit_limit = self.qcAlgo.take_profit stop_loss_limit = self.qcAlgo.take_profit # exit_trailing startegy has bigger prioriry if exit_trailing and exit_break_even: exit_break_even = False exit_trailing = True else: if not exit_trailing and not exit_break_even: exit_trailing = True exit_break_even = False # Go! if self.check_trade_allowed: # Init trade section vars self.trade_confidence = 1 live_idx = 0 prior_idx = 1 level = live_s_value # * * # * HANDLE TRADE STATE-MACHINE * # * * if self.trade_state == self.STAND_BY: # --- handle STAND-BY (begin) self.IsLevel_TradeEnabled_Semafors[live_idx] = \ self.IsLevel_TradeEnabled(live_ai_fast, live_ai_slow, live_a_o, live_a_h, live_a_l, live_a_c, tolerance, bar_touch_margins) live_trade_enabled = self.IsLevel_TradeEnabled_Semafors[live_idx] self.Indicator_Deltas[live_idx] = abs(live_ai_fast - live_ai_slow) live_indicator_delta = self.Indicator_Deltas[live_idx] self.Direction_Semafors[live_idx] = \ self.Check_Trade_Direction(live_ai_fast, live_ai_slow, live_a_o, live_a_h, live_a_l, live_a_c, tolerance, bar_touch_margins) live_trade_direction = self.Direction_Semafors[live_idx] # check if trade is enabled if live_trade_enabled: # check anchor history rules hist_trade_enabled = True hist_trade_direction_match = True hist_ind_expanded = True hist_ind_expanded_sum = 0 hist_ind_expanded_count = 0 hist_ind_expanded_avg = 0 for ha_idx in range(1, self.anchor_max_slots + 1): # init self.Indicator_Deltas[ha_idx] = 0 qb_idx = ha_idx - 1 hist_ai_fast = self.value(rw_ai_fast[ha_idx]) hist_ai_slow = self.value(rw_ai_slow[ha_idx]) hist_indicator_delta = abs(hist_ai_fast - hist_ai_slow) # calc history enablers self.IsLevel_TradeEnabled_Semafors[ha_idx] = \ self.IsLevel_TradeEnabled(hist_ai_fast , hist_ai_slow, \ rw_a_qb[qb_idx].Open, rw_a_qb[qb_idx].High, rw_a_qb[qb_idx].Low, rw_a_qb[qb_idx].Close, \ tolerance, bar_touch_margins) # calc history direction self.Direction_Semafors[ha_idx] = \ self.Check_Trade_Direction(hist_ai_fast , hist_ai_slow, \ rw_a_qb[qb_idx].Open, rw_a_qb[qb_idx].High, rw_a_qb[qb_idx].Low, rw_a_qb[qb_idx].Close, \ tolerance, bar_touch_margins) # calc history (rolling window) trade enabling if ha_idx <= self.anchor_lookback_for_trade_enabled: hist_trade_enabled = hist_trade_enabled and self.IsLevel_TradeEnabled_Semafors[ha_idx] if self.direction_lookback: hist_trade_direction_match = hist_trade_direction_match and live_trade_direction == self.Direction_Semafors[ha_idx] if self.indicator_lookback: # calc history indicators self.Indicator_Deltas[live_idx] = abs(hist_ai_fast - hist_ai_slow) hist_ind_expanded_sum = hist_ind_expanded_sum + self.Indicator_Deltas[live_idx] hist_ind_expanded_count = hist_ind_expanded_count + 1 # calc avg history indicators if self.indicator_lookback and hist_ind_expanded_count > 0: hist_ind_expanded_avg = hist_ind_expanded_sum / hist_ind_expanded_count hist_ind_expanded = live_indicator_delta >= hist_ind_expanded_avg # exit if history lookback trades wasn't enabled if not hist_trade_enabled or not hist_trade_direction_match or not hist_ind_expanded: # pay attention to the cancel events # self.cancel_event_attention() return # reset live trend direction props self.IsLevel_TradeEnabled_Semafors[live_idx] = \ self.IsLevel_TradeEnabled(live_ai_fast, live_ai_slow, live_a_o, live_a_h, live_a_l, live_a_c, tolerance, bar_touch_margins) # check trigger is_trigger = \ self.IsLevel_Trigger(\ live_si_fast, live_si_mid, live_si_slow, \ live_s_o, live_s_h, live_s_l, live_s_c, \ trigger_touch_tolerance, bar_touch_margins) # handle trigger semafor if is_trigger: # activate trigger flag self.activate_trigger_semafor() # calculate trade props self.calc_trade_props(rw_s_qb, rw_s_qb.Size, bar_touch_margins, trigger_pips_up, trigger_pips_down) # Calc confidence self.Get_Confidence() # call strategy - trigger (long) if self.is_long_trade: self.strategy.OnTrigger_Long(data, self) # set machine-state self.trade_state = self.TRIGGER_LONG # Log state Event self.trade_action("TRIGGER_LONG", self.qcAlgo.emit_info_insights) # call strategy - trigger (short) if self.is_short_trade: self.strategy.OnTrigger_Short(data, self) # set machine-state self.trade_state = self.TRIGGER_SHORT self.trade_action("TRIGGER_SHORT", self.qcAlgo.emit_info_insights) else: if self.qcAlgo.emit_info_insights: self.trade_action("WAIT_FOR_TRIGGER", self.qcAlgo.emit_info_insights) # exit return # --- handle STAND-BY (end) if self.qcAlgo.emit_info_insights: self.trade_action("WAIT_FOR_TRADE_ENABLING", self.qcAlgo.emit_info_insights) if self.trade_state == self.TRIGGER_LONG: # --- handle TRIGGER_LONG (start) # Calc confidence self.Get_Confidence() if not self.Is_Resistance_Level(rw_a_qb) and self.IsLevel_Entry(level): # disable cancel limit orders self.veto_cancel_orders # reset common trade props (short/long) self.trade_start_level = self.data.Value self.trade_take_profit = self.trade_exit # calc limits self.calc_stop_loss(level, stop_loss_limit) self.calc_take_profit(level, exit_trailing, take_profit_limit) # set semafor self.activate_entry_semafor() # call strategy self.strategy.OnEntry_Long(data, self) # set machine-state self.trade_state = self.ENTRY_LONG # Log state Event self.trade_action("ENTRY_LONG") # call strategy - open trade self.strategy.OnTradeOpen_Long(data, self, False) else: if level < self.stop_loss_level: # 100% confidence on "DROP TRIGGER" self.trade_confidence = 1 # set semafor self.activate_stand_by() # call strategy self.strategy.OnTriggerDrop_Long(data, self) # set machine-state self.trade_state = self.DROP_TRIGGER_LONG # Log state Event self.trade_action("DROP_TRIGGER_LONG") else: if self.qcAlgo.emit_info_insights: self.trade_action("WAIT_FOR_ENTRY_LONG", self.qcAlgo.emit_info_insights) # exit return # --- handle TRIGGER_LONG (end) if self.trade_state == self.TRIGGER_SHORT: # --- handle TRIGGER_SHORT (start) # Calc confidence self.Get_Confidence() if not self.Is_Support_Level(rw_a_qb) and self.IsLevel_Entry(level): # disable cancel limit orders self.veto_cancel_orders # reset common trade props (short/long) self.trade_start_level = self.data.Value self.trade_take_profit = self.trade_exit # calc limits self.calc_stop_loss(level, stop_loss_limit) self.calc_take_profit(level, exit_trailing, take_profit_limit) # set semafor self.activate_entry_semafor() # call strategy self.strategy.OnEntry_Short(data, self) # set machine-state self.trade_state = self.ENTRY_SHORT # Log state Event self.trade_action("ENTRY_SHORT") # call strategy - open trade self.strategy.OnTradeOpen_Short(data, self, False) else: if level > self.stop_loss_level: # 100% confidence on "DROP TRIGGER" self.trade_confidence = 1 # set semafor self.activate_stand_by() # call strategy self.strategy.OnTriggerDrop_Short(data, self) # set machine-state self.trade_state = self.DROP_TRIGGER_SHORT # Log state Event self.trade_action("DROP_TRIGGER_SHORT") else: if self.qcAlgo.emit_info_insights: self.trade_action("WAIT_FOR_ENTRY_SHORT", self.qcAlgo.emit_info_insights) # exit return # --- handle TRIGGER_SHORT (end) if self.trade_state == self.ENTRY_LONG: # check engulf condition if self.qcAlgo.engulf and self.qcAlgo.engulf_ratio > 0: if self.IsLevel_Reverse_Engulf( \ post_s_o,post_s_h,post_s_l, post_s_c, \ prev_s_o, prev_s_h, prev_s_l, prev_s_c, \ self.qcAlgo.engulf_ratio): # change trade state to "trend reversion" self.trade_state = self.TREND_REVERSION_LONG_TO_SHORT # check if trade state is still ENTRY if self.trade_state == self.ENTRY_LONG: # Calc confidence self.Get_Confidence() # --- handle ENTRY_LONG (start) ## Go! (proceed main entry routine) if self.IsLevel_Exit_1(level): # 100% confidence on "EXIT"-Events self.trade_confidence = 1 # set semafor self.activate_exit_1_semafor() # call strategy self.strategy.OnExit_1_Long(data, self) # set machine-state self.trade_state = self.EXIT_1_LONG self.exit2_level_steps_count = 0 # Log state Event self.trade_action("EXIT_1_LONG") # risk management - "break even" on "exit_1" event self.calc_on_break_even() else: if self.IsLevel_StopLoss(level, stop_loss_limit): # pay attention to the cancel events # self.cancel_event_attention() # return # 100% confidence on "STOP LOSS" self.trade_confidence = 1 # set semafors self.activate_stand_by() self.activate_stop_loss_semafor() # call strategy self.strategy.OnStopLoss_Long(data, self) # set machine-state self.trade_state = self.STOP_LOSS_LONG self.trade_action_noinsight_nobenchmark("STOP_LOSS_LONG") # call strategy - close 100% of the holdings self.strategy.OnTradeClose_Long(data, self) else: if self.IsLevel_OrangeRisk(level, stop_loss_limit): # 100% confidence on "ORANGE RISK" self.trade_confidence = 1 # set semafor self.activate_orange_risk_semafor() # force machine-state to EXIT_1 (LONG) # self.trade_state = self.EXIT_1_LONG self.invert_break_even() self.trade_action_insight_benchmark("ORANGE_RISK_LONG") else: self.strategy.OnTradeContinue_Long(data, self) # maintain the same machine-state self.trade_state = self.ENTRY_LONG if self.qcAlgo.emit_info_insights: self.trade_action_insight_benchmark("TRADE_CONTINUE_LONG_1") return # --- handle ENTRY_LONG (end) if self.trade_state == self.ENTRY_SHORT: # check engulf condition if self.qcAlgo.engulf and self.qcAlgo.engulf_ratio > 0: if self.IsLevel_Reverse_Engulf( \ post_s_o,post_s_h,post_s_l, post_s_c, \ prev_s_o, prev_s_h, prev_s_l, prev_s_c, \ self.qcAlgo.engulf_ratio): # change trade state to "trend reversion" self.trade_state = self.TREND_REVERSION_SHORT_TO_LONG # check if trade state is still ENTRY if self.trade_state == self.ENTRY_SHORT: # --- handle ENTRY_SHORT (start) # Calc confidence self.Get_Confidence() if self.IsLevel_Exit_1(level): # 100% confidence on "EXIT"-Events self.trade_confidence = 1 # set semafor self.activate_exit_1_semafor() # call strategy self.strategy.OnExit_1_Short(data, self) # set machine-state self.trade_state = self.EXIT_1_SHORT self.exit2_level_steps_count = 0 # Log state Event self.trade_action("EXIT_1_SHORT") # risk management - "break even" on "exit_1" event self.calc_on_break_even() else: if self.IsLevel_StopLoss(level, stop_loss_limit): # pay attention to the cancel events # self.cancel_event_attention() # return # (deprecated) # 100% confidence on "STOP LOSS" self.trade_confidence = 1 # set semafors self.activate_stand_by() self.activate_stop_loss_semafor() # call strategy self.strategy.OnStopLoss_Short(data, self) # set machine-state self.trade_state = self.STOP_LOSS_SHORT # Log state Event self.trade_action_noinsight_nobenchmark("STOP_LOSS_SHORT") # call strategy - close 100% of the holdings self.strategy.OnTradeClose_Short(data, self) else: if self.IsLevel_OrangeRisk(level, stop_loss_limit): # 100% confidence on "ORANGE RISK" self.trade_confidence = 1 # set semafor self.activate_orange_risk_semafor() # force machine-state to EXIT_1 (SHORT) #self.trade_state = self.EXIT_1_SHORT self.invert_break_even() self.trade_action_insight_benchmark("ORANGE_RISK_SHORT") # risk management - "break even" on "orange risk" event #self.calc_on_break_even() else: self.strategy.OnTradeContinue_Short(data, self) # maintain the same machine-state self.trade_state = self.ENTRY_SHORT if self.qcAlgo.emit_info_insights: self.trade_action_insight_benchmark("TRADE_CONTINUE_SHORT_1") # exit return # --- handle ENTRY_SHORT (end) if self.trade_state == self.EXIT_1_LONG: # --- handle EXIT_1_LONG (start) # Calc confidence self.Get_Confidence() if exit_trailing: # Re-Calculating trailing stop loss (if in trailng exit mode) self.calc_rolling_trade_props(rw_s_qb, trailing_exit_stop_bars_count, bar_touch_margins, trigger_pips_up, trigger_pips_down) # reset common trade props (short/long) self.trade_start_level = self.data.Value self.trade_take_profit = self.trade_exit # calc limits self.calc_stop_loss(level, stop_loss_limit) self.calc_take_profit(level, exit_trailing, take_profit_limit) self.update_hh_ll_limits() if self.IsLevel_Exit_2(level, exit_trailing, take_profit_limit): # 100% confidence on "EXIT"-Events self.trade_confidence = 1 # set semafor self.activate_exit_2_semafor() # call strategy self.strategy.OnExit_2_Long(data, self, exit_trailing) self.trade_state = self.EXIT_2_LONG # Log state Event self.trade_action("EXIT_2_LONG") # call strategy - close trade self.strategy.OnTradeClose_Long(data, self) else: if self.IsLevel_StopLoss(level, stop_loss_limit): # 100% confidence on "STOP LOSS" self.trade_confidence = 1 # set semafors self.activate_stand_by() self.activate_stop_loss_semafor() self.strategy.OnStopLoss_Long(data, self) self.trade_state = self.STOP_LOSS_TAKE_PROFIT_LONG # Log state Event self.trade_action_noinsight_nobenchmark("EXIT_TAKE_PROFIT_LONG") # call strategy - stop loss, close trade and take profit self.strategy.OnStopLossAndTakeProfit_Long(data, self) # call strategy - close 100% of the holdings self.strategy.OnTradeClose_Long(data, self, 100/100) else: self.strategy.OnTradeContinue_Long(data, self) # maintain the same machine-state self.trade_state = self.EXIT_1_LONG if self.qcAlgo.emit_info_insights: self.trade_action_insight_benchmark("TRADE_CONTINUE_LONG_2") # exit return # --- handle EXIT_1_LONG (end) if self.trade_state == self.EXIT_1_SHORT: # --- handle EXIT_1_SHORT (start) # Calc confidence self.Get_Confidence() if exit_trailing: # Re-Calculating trailing stop loss (if in trailng exit mode) self.calc_rolling_trade_props(rw_s_qb, trailing_exit_stop_bars_count, bar_touch_margins, trigger_pips_up, trigger_pips_down) # reset common trade props (short/long) self.trade_start_level = self.data.Value self.trade_take_profit = self.trade_exit # calc limits self.calc_stop_loss(level, stop_loss_limit) self.calc_take_profit(level, exit_trailing, take_profit_limit) self.update_hh_ll_limits() if self.IsLevel_Exit_2(level, exit_trailing, take_profit_limit): # 100% confidence on "EXIT"-Events self.trade_confidence = 1 # set semafor self.activate_exit_2_semafor() # call strategy self.strategy.OnExit_2_Short(data, self, exit_trailing) self.trade_state = self.EXIT_2_SHORT # Log state Event self.trade_action("EXIT_2_SHORT") # call strategy - close trade self.strategy.OnTradeClose_Short(data, self) else: if self.IsLevel_StopLoss(level, stop_loss_limit): # 100% confidence on "STOP LOSS" self.trade_confidence = 1 # set semafors self.activate_stand_by() self.activate_stop_loss_semafor() self.strategy.OnStopLoss_Short(data, self) self.trade_state = self.STOP_LOSS_TAKE_PROFIT_SHORT # Log state Event self.trade_action_noinsight_nobenchmark("EXIT_TAKE_PROFIT_SHORT") # call strategy - stop loss, close trade and take profit self.strategy.OnStopLossAndTakeProfit_Short(data, self) # call strategy - close 100% of the holdings self.strategy.OnTradeClose_Short(data, self, 100/100) else: self.strategy.OnTradeContinue_Short(data, self) # maintain the same machine-state self.trade_state = self.EXIT_1_SHORT if self.qcAlgo.emit_info_insights: self.trade_action_insight_benchmark("TRADE_CONTINUE_SHORT_2") # exit return # --- handle EXIT_1_SHORT (end) if self.trade_state == self.TREND_REVERSION_LONG_TO_SHORT: # --- handle TREND_REVERSION_LONG_TO_LONG (start) # 100% confidence on "EXIT"-Events self.trade_confidence = 1 # drop all semafors self.drop_all_semafors() # Log state Event self.trade_action_insight_benchmark("TREND_REVERSION_LONG_TO_SHORT") # call strategy - close trade self.strategy.OnTradeClose_Long(data, self) # Log state Event self.trade_action_insight_benchmark("CLOSE_LONG_ON_TREND_REVERSION") if self.qcAlgo.reverse_trade: # reverse trade direction self.Flip_Trade_Direction() # calculate trade props self.calc_trade_props(rw_s_qb, rw_s_qb.Size, bar_touch_margins, trigger_pips_up, trigger_pips_down) # reset common trade props (short/long) self.trade_start_level = self.data.Value self.trade_take_profit = self.trade_exit # calc limits self.calc_stop_loss(level, stop_loss_limit) self.calc_take_profit(level, exit_trailing, take_profit_limit) # set semafor self.activate_entry_semafor() # call strategy self.strategy.OnEntry_Short(data, self) # set machine-state self.trade_state = self.ENTRY_SHORT # Log state Event self.trade_action_insight_benchmark("ENTRY_SHORT_ON_TREND_REVERSION") # call strategy - open trade self.strategy.OnTradeOpen_Short(data, self, False) # exit return # --- handle TREND_REVERSION_LONG_TO_LONG (end) if self.trade_state == self.TREND_REVERSION_SHORT_TO_LONG: # --- handle TREND_REVERSION_SHORT_TO_LONG (start) # 100% confidence on "EXIT"-Events self.trade_confidence = 1 # drop all semafors self.drop_all_semafors() # Log state Event self.trade_action_insight_benchmark("TREND_REVERSION_SHORT_TO_LONG") # call strategy - close trade self.strategy.OnTradeClose_Short(data, self) # Log state Event self.trade_action_insight_benchmark("CLOSE_SHORT_ON_TREND_REVERSION") if self.qcAlgo.reverse_trade: # reverse trade direction self.Flip_Trade_Direction() # calculate trade props self.calc_trade_props(rw_s_qb, rw_s_qb.Size, bar_touch_margins, trigger_pips_up, trigger_pips_down) # reset common trade props (short/long) self.trade_start_level = self.data.Value self.trade_take_profit = self.trade_exit # calc limits self.calc_stop_loss(level, stop_loss_limit) self.calc_take_profit(level, exit_trailing, take_profit_limit) # set semafor self.activate_entry_semafor() # call strategy self.strategy.OnEntry_Long(data, self) # set machine-state self.trade_state = self.ENTRY_LONG # Log state Event self.trade_action_insight_benchmark("ENTRY_LONG_ON_TREND_REVERSION") # call strategy - open trade self.strategy.OnTradeOpen_Long(data, self, False) # exit return # --- handle TREND_REVERSION_SHORT_TO_LONG (end) ------------------------ if self.trade_state == self.EXIT_2_LONG or self.trade_state == self.EXIT_2_SHORT \ or self.trade_state == self.TREND_REVERSION_LONG_TO_SHORT or self.trade_state == self.TREND_REVERSION_SHORT_TO_LONG \ or self.trade_state == self.STOP_LOSS_LONG or self.trade_state == self.STOP_LOSS_SHORT \ or self.trade_state == self.STOP_LOSS_TAKE_PROFIT_SHORT or self.trade_state == self.STOP_LOSS_TAKE_PROFIT_LONG \ or self.trade_state == self.DROP_TRIGGER_LONG or self.trade_state == self.DROP_TRIGGER_SHORT: # --- handle EXIT_2 / STOP_LOSS (start) # 100% confidence on exit self.trade_confidence = 1 # reset semafors self.drop_all_semafors() # drop trend direction self.trade_direction_flattening() if self.trade_state == self.EXIT_2_LONG \ or self.trade_state == self.STOP_LOSS_LONG \ or self.trade_state == self.TREND_REVERSION_LONG_TO_SHORT \ or self.trade_state == self.STOP_LOSS_TAKE_PROFIT_LONG \ or self.trade_state == self.DROP_TRIGGER_LONG: # call Long-Strategy self.strategy.OnFinishTrade_Long(data, self) # Log state Event self.trade_action_noinsight_nobenchmark("FINISH_TRADE_LONG") if self.trade_state == self.EXIT_2_SHORT \ or self.trade_state == self.STOP_LOSS_SHORT \ or self.trade_state == self.TREND_REVERSION_SHORT_TO_LONG \ or self.trade_state == self.STOP_LOSS_TAKE_PROFIT_SHORT \ or self.trade_state == self.DROP_TRIGGER_SHORT: # call Short-Strategy self.strategy.OnFinishTrade_Short(data, self) # Log state Event self.trade_action_noinsight_nobenchmark("FINISH_TRADE_SHORT") # reset levels & machine-state self.reset_state() # reset levels self.reset_all_levels() # reset machine-state self.trade_state = self.STAND_BY # exit return # --- handle EXIT_2 / STOP_LOSS (end) else: return def drop_all_semafors(self): self.IsLevel_Trigger_Semafor = False self.IsLevel_Entry_Semafor = False self.IsLevel_Exit_1_Semafor = False self.IsLevel_Exit_2_Semafor = False self.IsLevel_StopLoss_Semafor = False self.IsLevel_OrangeRisk_Semafor = False def reset_all_levels(self): self.exit2_level_steps_count = 0 self.trade_risk = 0 self.touch_level = 0 self.entry_level = 0 self.exit1_level = 0 self.exit2_level = 0 self.stop_loss_level = 0 self.stop_loss_purple_level = 0 self.TTG_trailing_trade_gain = 0 self.TLG_trailing_live_gain = 0 self.LLo_lowest_low_open = 0 self.LLc_lowest_low_close = 0 self.HHo_highest_high_open = 0 self.HHc_highest_high_close = 0 self.LVo_live_open = 0 self.LVc_live_close = 0 self.minor_delta = 0 self.major_delta = 0 self.delta_acceleration = 0 def activate_stand_by(self): self.drop_all_semafors() # reset live trade enabling semafor (idx = 0) self.IsLevel_TradeEnabled_Semafors[0] = False def activate_trigger_semafor(self): self.drop_all_semafors() self.IsLevel_Trigger_Semafor = True def activate_entry_semafor(self): self.drop_all_semafors() self.IsLevel_Entry_Semafor = True def activate_exit_1_semafor(self): self.drop_all_semafors() self.IsLevel_Exit_1_Semafor = True def activate_exit_2_semafor(self): self.drop_all_semafors() self.IsLevel_Exit_2_Semafor = True def activate_stop_loss_semafor(self): self.drop_all_semafors() self.IsLevel_StopLoss_Semafor = True def activate_orange_risk_semafor(self): self.drop_all_semafors() self.IsLevel_OrangeRisk_Semafor = True def Get_Trade_Scalp_Highest_High(self, rw_quote_bar, max_bars, touch_margins): # --------- result = 0 for i in range(max_bars): if touch_margins == "open_close": if result == 0 or result < rw_quote_bar[i].Open: result = rw_quote_bar[i].Open if result == 0 or result < rw_quote_bar[i].Close: result = rw_quote_bar[i].Close else: if result == 0 or result < rw_quote_bar[i].High: result = rw_quote_bar[i].High return result def Get_Trade_Scalp_Lowest_Low(self, rw_quote_bar, max_bars, touch_margins): # --------- result = 0 for i in range(max_bars): if touch_margins == "open_close": if result == 0 or result > rw_quote_bar[i].Open: result = rw_quote_bar[i].Open if result == 0 or result > rw_quote_bar[i].Close: result = rw_quote_bar[i].Close else: if result == 0 or result > rw_quote_bar[i].Low: result = rw_quote_bar[i].Low return result def Get_Live_Spread(self, rw_quote_bar, touch_margins): # --------- if touch_margins == "open_close": return rw_quote_bar[0].Close - rw_quote_bar[0].Open else: return rw_quote_bar[0].High - rw_quote_bar[0].Low def Flip_Trade_Direction(self): # init self.direction_trade = InsightDirection.Flat if self.is_short_trade or self.is_long_trade: # flip short/long self.is_short_trade = not self.is_short_trade self.is_long_trade = not self.is_long_trade # calc direction trend if self.is_short_trade: self.direction_trade = InsightDirection.Down if self.is_long_trade: self.direction_trade = InsightDirection.Up return self.direction_trade def Check_Trade_Direction(self, ind_fast, ind_slow, o,h,l,c, tolerance = 0, touch_margins = "open_close"): # --------- # call base routine base_result = super(FxRedBirdBrick_South, self).Check_Trade_Direction(ind_fast, ind_slow, o,h,l,c, tolerance, touch_margins) self.direction_trade = base_result # init self.direction_trade = InsightDirection.Flat # calc short/long flags self.is_short_trade = ind_fast < ind_slow self.is_long_trade = ind_fast > ind_slow ind_diff = self.pip_diff_abs(ind_fast, ind_slow) if ind_diff < tolerance: self.is_short_trade = False self.is_long_trade = False else: if touch_margins == "open_close": self.is_short_trade = self.is_short_trade and o < self.anchor_slow_indicator_margin and c < self.anchor_slow_indicator_margin self.is_long_trade = self.is_long_trade and o > self.anchor_fast_indicator_margin and c > self.anchor_fast_indicator_margin else: self.is_short_trade = self.is_short_trade and l < self.anchor_slow_indicator_margin and h < self.anchor_slow_indicator_margin# self.is_long_trade = self.is_long_trade and l > self.anchor_fast_indicator_margin and h > self.anchor_fast_indicator_margin # calc direction trend if self.is_short_trade: self.direction_trade = InsightDirection.Down if self.is_long_trade: self.direction_trade = InsightDirection.Up return self.direction_trade def IsLevel_TradeEnabled(self, i_fast, i_slow, o,h,l,c, tolerance = 0, touch_margins = "open_close"): # --------- self.Check_Trade_Direction(i_fast, i_slow, o,h,l,c, tolerance, touch_margins) return self.is_short_trade or self.is_long_trade def IsLevel_Reverse_Engulf(self, o_curr,h_curr,l_curr,c_curr, o_prior,h_prior,l_prior,c_prior, engulf_ratio = 0): # --------- # init result = False # Go! if self.is_short_trade or self.is_long_trade: # trade enabled if self.is_long_trade: # long trade result = c_curr < o_curr and c_prior > o_prior if result: delta_curr = abs(o_curr - c_curr) delta_prior = abs(c_prior - o_prior) if delta_prior > 0: result = delta_curr / delta_prior >= engulf_ratio return result if self.is_short_trade: # long trade result = c_curr > o_curr and c_prior < o_prior if result: delta_curr = abs(c_curr - o_curr) delta_prior = abs(o_prior - c_prior) if delta_prior > 0: result = delta_curr / delta_prior >= engulf_ratio return result else: # no trade return result def IsLevel_Trigger(self, si_fast, si_mid, si_slow, o,h,l,c, tolerance = 0, touch_margins = "open_close"): # --------- # init margins self.Set_Scalp_Indicators_Margins(si_fast, si_mid, si_slow, tolerance) im_fast = self.scalp_fast_indicator_margin im_mid = self.scalp_mid_indicator_margin im_slow = self.scalp_slow_indicator_margin trigger_pips_up = self.qcAlgo.pullback_trigger_pips_up trigger_pips_down = self.qcAlgo.pullback_trigger_pips_down # Go! if self.is_long_trade: # long trade if touch_margins == "open_close": touch_level = c else: touch_level = l if c < o: is_level_trigger = touch_level < im_fast and touch_level > im_mid and touch_level > im_slow if is_level_trigger: self.touch_level = self.plus_pip(touch_level, trigger_pips_down) return is_level_trigger else: return False if self.is_short_trade: # short trade if touch_margins == "open_close": touch_level = c else: touch_level = h if c > o: is_level_trigger = touch_level > im_fast and touch_level < im_mid and touch_level < im_slow if is_level_trigger: self.touch_level = self.plus_pip(touch_level, trigger_pips_up) return is_level_trigger else: return False else: # no trade return False def IsLevel_Entry(self, level): # --------- # Go! if self.is_long_trade: return level > self.entry_level if self.is_short_trade: return level < self.entry_level def IsLevel_Exit_1(self, level): # --------- # Go! if self.is_long_trade: return level > self.trade_break_even if self.is_short_trade: return level < self.trade_break_even def calc_take_profit(self, level, trailing=False, take_profit_limit = 0.001): # --------- # init limit_price = 0 result = False live_si_fast = self.scalp_ema_current_value(8) live_si_mid = self.scalp_ema_current_value(13) live_si_slow = self.scalp_ema_current_value(21) live_trend_down = live_si_fast < live_si_mid and live_si_mid < live_si_slow live_trend_up = live_si_fast > live_si_mid and live_si_mid > live_si_slow # Go! if not trailing: # init if take_profit_limit > 1: take_profit_limit = 1 else: if take_profit_limit < 0: take_profit_limit = 0 # Go! if self.is_long_trade: self.trade_take_profit_level = self.trade_start_level * (1 + abs(take_profit_limit)) result = level > self.trade_take_profit_level else: if self.is_short_trade: self.trade_take_profit_level = self.trade_start_level * (1 - abs(take_profit_limit)) result = level < self.trade_take_profit_level else: result = False limit_price = self.trade_take_profit_level else: delta_profit_guaranteed_part_percent = self.exit_1_profit_guaranteed / 100 delta_exit_1_with_guaranteed_profit = abs(self.trade_break_even - self.trade_abs_start_level) * delta_profit_guaranteed_part_percent if self.is_long_trade: result = level < self.stop_loss_level if self.exit2_level_steps_count > 0 and self.exit2_level_steps_count > self.exit2_level_min_steps_count: result = result or live_trend_down if self.drawdown_on_trade_start and self.trade_abs_start_level > 0 and self.trade_break_even > 0: GP_limit_exit_1 = self.trade_abs_start_level + delta_exit_1_with_guaranteed_profit self.stop_loss_purple_level = GP_limit_exit_1 result = result or level < GP_limit_exit_1 # check trailing exit by pullback ratio if self.RCT_pullback_trailing_stop_ratio > 0: result = result or self.Is_Pullback_Trailing_Exit() else: if self.is_short_trade: result = level > self.stop_loss_level if self.exit2_level_steps_count > 0 and self.exit2_level_steps_count > self.exit2_level_min_steps_count: result = result or live_trend_up if self.drawdown_on_trade_start and self.trade_abs_start_level > 0 and self.trade_break_even > 0: GP_limit_exit_1 = self.trade_abs_start_level - delta_exit_1_with_guaranteed_profit self.stop_loss_purple_level = GP_limit_exit_1 result = result or level > GP_limit_exit_1 # check trailing exit by pullback ratio if self.RCT_pullback_trailing_stop_ratio > 0: result = result or self.Is_Pullback_Trailing_Exit() else: result = False if self.is_long_trade: self.trade_take_profit_level = self.trade_start_level * (1 + abs(take_profit_limit)) if self.is_short_trade: self.trade_take_profit_level = self.trade_start_level * (1 - abs(take_profit_limit)) limit_price = self.trade_take_profit_level # finally if self.exit2_level_steps_count > 0: self.exit2_level_steps_count = self.exit2_level_steps_count + 1 return result def IsLevel_Exit_2(self, level, trailing=False, take_profit_limit = 0.001): # --------- result = self.calc_take_profit(level, trailing, take_profit_limit) limit_price = self.trade_take_profit_level # Update Profit-Target order if not result: self.update_take_profit(limit_price) # finally return result def calc_stop_loss(self, level, stop_loss_limit = .05): # --------- # init stop_loss_limit = self.toolbox.cut_by_zero_one(stop_loss_limit) orange_risk = self.toolbox.normalize_percent_abs(self.qcAlgo.orange_risk) red_orange_risk = self.toolbox.cut_by_zero_one(orange_risk + self.red_risk_shift_percent / 100) # Go! if self.is_long_trade: if not self.IsLevel_OrangeRisk_Semafor: self.trade_given_stop_loss = self.trade_start_level * (1 - abs(stop_loss_limit)) else: self.trade_given_stop_loss = self.trade_start_level * (1 - abs(stop_loss_limit) * red_orange_risk) result = level < self.trade_given_stop_loss else: if self.is_short_trade: if not self.IsLevel_OrangeRisk_Semafor: self.trade_given_stop_loss = self.trade_start_level * (1 + abs(stop_loss_limit)) else: self.trade_given_stop_loss = self.trade_start_level * (1 + abs(stop_loss_limit) * red_orange_risk) result = level > self.trade_given_stop_loss else: result = False # finally return result def IsLevel_StopLoss(self, level, stop_loss_limit = .05): # --------- # init stop_loss_limit = self.toolbox.cut_by_zero_one(stop_loss_limit) # Go! result = self.calc_stop_loss(level, stop_loss_limit) limit_price = self.trade_given_stop_loss # Update Stop-Loss order if not result: self.update_stop_loss(limit_price) # finally return result def calc_orange_risk_level(self, level, stop_loss_limit = .05): # --------- # init stop_loss_limit = self.toolbox.cut_by_zero_one(stop_loss_limit) orange_risk = self.toolbox.normalize_percent_abs(self.qcAlgo.orange_risk) # Go! if self.is_long_trade: self.trade_orange_risk_level = self.trade_start_level * (1 - abs(stop_loss_limit) * orange_risk) result = level < self.trade_orange_risk_level else: if self.is_short_trade: self.trade_orange_risk_level = self.trade_start_level * (1 + abs(stop_loss_limit) * orange_risk) result = level > self.trade_orange_risk_level else: result = False # finally return result def IsLevel_OrangeRisk(self, level, stop_loss_limit = .05): # --------- return self.calc_orange_risk_level(level, stop_loss_limit) # * TRADE RULES/EVENTS REGION (CUSTOM / END) * def new_scalp_indicators(self): # init result = {} self.scalp_periods.append(8) self.scalp_periods.append(13) self.scalp_periods.append(21) # go! for period in self.scalp_periods: ticker = self.scalp_ticker("ema", period) result[ticker] = ExponentialMovingAverage(ticker, period) return result def new_anchor_indicators(self): # init result = {} self.anchor_periods.append(8) self.anchor_periods.append(21) # go! for period in self.anchor_periods: ticker = self.anchor_ticker("ema", period) result[ticker] = ExponentialMovingAverage(ticker, period) return result def update_scalp_indicator_chart(self): # --------- # call base update mathod super(FxRedBirdBrick_South, self).update_scalp_indicator_chart() # adding scalp indicator series self.update_indicator_chart(self.scalp_chart, "scalp", "ema", self.scalp_periods) def update_anchor_indicator_chart(self): # adding anchor indicator series self.update_indicator_chart(self.anchor_chart, "anchor", "ema", self.anchor_periods)
from StrategyFxScalper import StrategyFxScalper ''' To use this library place this at the top: from StrategyFxTrendSurferWest import StrategyFxTrendSurferWest Then instantiate the function: strategy = StrategyFxRedBird_South(...) strategy.Run(data) ''' # ******************************** class StrategyFxRedBird_South(StrategyFxScalper): # ******************************** # **************************************************** # * LONG - TRADE RULES REGION (CUSTOM / BEGIN) * # **************************************************** # override # ------------------------------------------------------------------------------------------------------------- def OnTrigger_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnTrigger_Long(data, fxBrick) # go! (custom part) # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next pass # override # ------------------------------------------------------------------------------------------------------------- def OnEntry_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnEntry_Long(data, fxBrick) # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next # pay attention to the cancel events #fxBrick.cancel_event_attention() # override # ------------------------------------------------------------------------------------------------------------- def OnTradeContinue_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnTradeContinue_Long(data, fxBrick) # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next pass # override # ------------------------------------------------------------------------------------------------------------- def OnStopLoss_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnStopLoss_Long(data, fxBrick) # cancel opened takeprofit and/or stop loss orders #fxBrick.cancel_limits() # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next # i.e.: if fxBrick.trade_state == fxBrick.TRIGGER_LONG: ... etc. for all states except of the STAND_BY-Step (if ) # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next pass # ------------------------------------------------------------------------------------------------------------- def OnExit_1_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next # init exit_trailing = self.qcAlgo.exit_strategy_trailing_exit # calc rest order size old_order_size = fxBrick.roundedOrderSize close_rate = fxBrick.exit_1_rate close_order_size = fxBrick.GetRoundedOrderSize(old_order_size * close_rate) rest_order_size = old_order_size - close_order_size fxBrick.roundedOrderSize = rest_order_size # calc by PIP rounded price take_profit = self.pip_round(fxBrick.trade_take_profit) stop_loss = self.pip_round(fxBrick.stop_loss_level) if close_order_size > 0: # sell part of the equity (long part close) self.qcAlgo.Sell(fxBrick.symbol, close_order_size) #fxBrick.veto_cancel_orders() # Update Take Profit order # fxBrick.update_take_profit(take_profit, -rest_order_size) ''' if exit_trailing: # cancel take profit order in trailing mode overrule_veto = True fxBrick.cancel_take_profit(overrule_veto) else: # Update Take Profit order fxBrick.update_take_profit(take_profit, -rest_order_size) ''' # Update Stop Loss order # fxBrick.update_stop_loss(stop_loss, -rest_order_size) # ------------------------------------------------------------------------------------------------------------- def OnExit_2_Long(self, data, fxBrick, exit_trailing): # ------------------------------------------------------------------------------------------------------------- # cancel opened takeprofit and/or stop loss orders #fxBrick.cancel_limits() # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next # finally self.OnExit_Long(data, fxBrick) # override # ------------------------------------------------------------------------------------------------------------- def OnStopLossAndTakeProfit_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnStopLossAndTakeProfit_Long(data, fxBrick) # cancel opened takeprofit and/or stop loss orders #fxBrick.cancel_limits() # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next # i.e.: if fxBrick.trade_state == fxBrick.TRIGGER_LONG: ... etc. for all states except of the STAND_BY-Step (if ) # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next pass # override # ------------------------------------------------------------------------------------------------------------- def OnExit_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnExit_Long(data, fxBrick) # go! (custom part) # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next # ignore cancel event #fxBrick.cancel_event_ignore() # override # ------------------------------------------------------------------------------------------------------------- def OnFinishTrade_Long(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnFinishTrade_Long(data, fxBrick) # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next # ignore cancel event #fxBrick.cancel_event_ignore() # ********************************************************* # * LONG - TRADE RULES REGION TRADE RULES (CUSTOM / END) * # ********************************************************* # **************************************************** # * SHORT - TRADE RULES REGION (CUSTOM / BEGIN) * # **************************************************** # override # ------------------------------------------------------------------------------------------------------------- def OnTrigger_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnTrigger_Short(data, fxBrick) # go! (custom part) # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next pass # override # ------------------------------------------------------------------------------------------------------------- def OnEntry_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnEntry_Short(data, fxBrick) # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next # pay attention to the cancel events #fxBrick.cancel_event_attention() # ------------------------------------------------------------------------------------------------------------- def OnTradeContinue_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnTradeContinue_Short(data, fxBrick) # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next pass # override # ------------------------------------------------------------------------------------------------------------- def OnStopLoss_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnStopLoss_Short(data, fxBrick) # cancel opened takeprofit and/or stop loss orders #fxBrick.cancel_limits() # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next pass # ------------------------------------------------------------------------------------------------------------- def OnExit_1_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # init exit_trailing = self.qcAlgo.exit_strategy_trailing_exit # calc rest order size old_order_size = fxBrick.roundedOrderSize close_rate = fxBrick.exit_1_rate close_order_size = fxBrick.GetRoundedOrderSize(old_order_size * close_rate) rest_order_size = old_order_size - close_order_size fxBrick.roundedOrderSize = rest_order_size # calc by PIP rounded price take_profit = self.pip_round(fxBrick.trade_take_profit) stop_loss = self.pip_round(fxBrick.stop_loss_level) # buy part of the equity (short part close) if close_order_size > 0: self.qcAlgo.Buy(fxBrick.symbol, close_order_size) #fxBrick.veto_cancel_orders() # Update Take Profit order #fxBrick.update_take_profit(take_profit, rest_order_size) ''' if exit_trailing: # cancel take profit order in trailing mode overrule_veto = True fxBrick.cancel_take_profit(overrule_veto) else: # Update Take Profit order fxBrick.update_take_profit(take_profit, rest_order_size) ''' # Update Stop Loss order #fxBrick.update_stop_loss(stop_loss, rest_order_size) # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next # ------------------------------------------------------------------------------------------------------------- def OnExit_2_Short(self, data, fxBrick, exit_trailing): # ------------------------------------------------------------------------------------------------------------- # cancel opened takeprofit and/or stop loss orders #fxBrick.cancel_limits() # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next # finally self.OnExit_Short(data, fxBrick) # override # ------------------------------------------------------------------------------------------------------------- def OnStopLossAndTakeProfit_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnStopLossAndTakeProfit_Short(data, fxBrick) # cancel opened takeprofit and/or stop loss orders #fxBrick.cancel_limits() # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next # i.e.: if fxBrick.trade_state == fxBrick.TRIGGER_LONG: ... etc. for all states except of the STAND_BY-Step (if ) # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next pass # override # ------------------------------------------------------------------------------------------------------------- def OnExit_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnExit_Short(data, fxBrick) # go! (custom part) # ignore cancel event #fxBrick.cancel_event_ignore() # override # ------------------------------------------------------------------------------------------------------------- def OnFinishTrade_Short(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnFinishTrade_Short(data, fxBrick) # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next # ignore cancel event #fxBrick.cancel_event_ignore() # ********************************************************* # * SHORT - TRADE RULES REGION TRADE RULES (CUSTOM / END) * # ********************************************************* # ****************************************************** # * TRADE-ACTION RULES REGION TRADE RULES (BASE / BEGIN) * # ****************************************************** # override # ------------------------------------------------------------------------------------------------------------- def OnTradeOpen_Long(self, data, fxBrick, set_limits=True): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnTradeOpen_Long(data, fxBrick, set_limits) # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next pass # override # ------------------------------------------------------------------------------------------------------------- def OnTradeOpen_Short(self, data, fxBrick, set_limits=True): # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnTradeOpen_Short(data, fxBrick, set_limits) # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next pass # override # ------------------------------------------------------------------------------------------------------------- def OnTradeClose_Long(self, data, fxBrick, closeRatio = 1): # closeRatio = 1 - close all holdings, 0.5 - close 50% of holdings, 0 - nothing to close # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnTradeClose_Long(data, fxBrick, closeRatio) # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next pass # override # ------------------------------------------------------------------------------------------------------------- def OnTradeClose_Short(self, data, fxBrick, closeRatio = 1): # closeRatio = 1 - close all holdings, 0.5 - close 50% of holdings, 0 - nothing to close # ------------------------------------------------------------------------------------------------------------- # call base method super(StrategyFxRedBird_South, self).OnTradeClose_Short(data, fxBrick, closeRatio) # go! (custom part) # TODO 1: Execute Rule # TODO 2: Plot Data if executed # Attention!!! Check "Brick-State" first (fxBrick.trade_state) in order to decide what to do next pass # ****************************************************** # * TRADE-ACTION RULES REGION TRADE RULES (BASE / END) * # ****************************************************** # custom / override # ********************************* # * PLOT REGION (BEGIN) * # ********************************* # ------------------------------------------------------------------------------------------------------------- def plot_scalp_chart(self, fxBrick, bar): # ------------------------------------------------------------------------------------------------------------- self.init_scalp_indicators(fxBrick) self.plot_price_chart(fxBrick.scalp_chart.Name, fxBrick, bar) self.plot(fxBrick.scalp_chart.Name, self.scalp_ema_8_ticker, self.scalp_ema_8.Current.Value) self.plot(fxBrick.scalp_chart.Name, self.scalp_ema_13_ticker, self.scalp_ema_13.Current.Value) self.plot(fxBrick.scalp_chart.Name, self.scalp_ema_21_ticker, self.scalp_ema_21.Current.Value) # custom / override # ------------------------------------------------------------------------------------------------------------- def plot_anchor_chart(self, fxBrick, bar): # ------------------------------------------------------------------------------------------------------------- self.init_anchor_indicators(fxBrick) self.plot_price_chart(fxBrick.anchor_chart.Name, fxBrick, bar) self.plot(fxBrick.anchor_chart.Name, self.anchor_ema_8_ticker, self.anchor_ema_8.Current.Value) self.plot(fxBrick.anchor_chart.Name, self.anchor_ema_21_ticker, self.anchor_ema_21.Current.Value) # ********************************* # * PLOT REGION (END) * # ********************************* # ------------------------------------------------------------------------------------------------------------- def init_scalp_indicators(self, fxBrick): # ------------------------------------------------------------------------------------------------------------- self.scalp_ema_8_ticker = fxBrick.scalp_ticker("ema",8) self.scalp_ema_13_ticker = fxBrick.scalp_ticker("ema",13) self.scalp_ema_21_ticker = fxBrick.scalp_ticker("ema",21) self.scalp_ema_8 = fxBrick.scalpIndicators[self.scalp_ema_8_ticker] self.scalp_ema_13 = fxBrick.scalpIndicators[self.scalp_ema_13_ticker] self.scalp_ema_21 = fxBrick.scalpIndicators[self.scalp_ema_21_ticker] # ------------------------------------------------------------------------------------------------------------- def init_anchor_indicators(self, fxBrick): # ------------------------------------------------------------------------------------------------------------- self.anchor_ema_8_ticker = fxBrick.anchor_ticker("ema",8) self.anchor_ema_21_ticker = fxBrick.anchor_ticker("ema",21) self.anchor_ema_8 = fxBrick.anchorIndicators[self.anchor_ema_8_ticker] self.anchor_ema_21 = fxBrick.anchorIndicators[self.anchor_ema_21_ticker] # ------------------------------------------------------------------------------------------------------------- def init_indicators(self, fxBrick): # ------------------------------------------------------------------------------------------------------------- self.init_scalp_indicators(fxBrick) self.init_anchor_indicators(fxBrick) # custom (override) # ------------------------------------------------------------------------------------------------------------- def RunFxScalp(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # base # call base run super(StrategyFxRedBird_South, self).RunFxScalp(data, fxBrick) # Go! # update and plot ema crosses - scalp self.UpdateScalpCross(data, fxBrick, True) # finally # ------------------------------------------------------------------------------------------------------------- def UpdateScalpCross(self, data, fxBrick, doPlot = True): # ------------------------------------------------------------------------------------------------------------- if self.qcAlgo.plot_ema_cross: # update EMA labels - scalp cross_scalp = fxBrick.IsNarrowScalpEMA(self.scalp_ema_8.Current.Value, self.scalp_ema_21.Current.Value) # plot scalp EMA if cross event happened if doPlot and cross_scalp and fxBrick.IsChartHour(data.Time): scalp_ema_mean = (self.scalp_ema_8.Current.Value + self.scalp_ema_21.Current.Value) / 2 self.plot_scalp_ema_cross(fxBrick, scalp_ema_mean) #self.plot_scalp_ema_cross(fxBrick, self.scalp_ema_8.Current.Value) # custom (override) # ------------------------------------------------------------------------------------------------------------- def RunFxAnchor(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # call base run super(StrategyFxRedBird_South, self).RunFxAnchor(data, fxBrick) # update and plot ema crosses - anchor self.UpdateAnchorCross(data, fxBrick, True) # Go! pass # ------------------------------------------------------------------------------------------------------------- def UpdateAnchorCross(self, data, fxBrick, doPlot = True): # ------------------------------------------------------------------------------------------------------------- if self.qcAlgo.plot_ema_cross: # update EMA labels - anchor cross_anchor = fxBrick.IsNarrowAnchorEMA(self.anchor_ema_8.Current.Value, self.anchor_ema_21.Current.Value) # plot anchor EMA if cross event happened if doPlot and cross_anchor and fxBrick.IsChartHour(data.Time): anchor_ema_mean = (self.anchor_ema_8.Current.Value + self.anchor_ema_21.Current.Value) / 2 self.plot_anchor_ema_cross(fxBrick, anchor_ema_mean) #self.plot_anchor_ema_cross(fxBrick, self.anchor_ema_8.Current.Value) # custom (override) # ------------------------------------------------------------------------------------------------------------- def RunFx(self, data, fxBrick): # ------------------------------------------------------------------------------------------------------------- # init self.init_indicators(fxBrick) # call base run super(StrategyFxRedBird_South, self).RunFx(data, fxBrick) # Go! # check if all indicators are ready if not fxBrick.all_indicators_ready: return # validation if data contains ticker #if not data.ContainsKey(fxBrick.symbol): # return # ********** BEGIN: Strategy ****************** # update and plot ema crosses - anchor #self.UpdateAnchorCross(data, fxBrick, True) #self.UpdateScalpCross(data, fxBrick, True) p1 = 0.67699 p2 = 0.65027 i = self.qcAlgo.pip_diff(p1, p2) j = self.qcAlgo.add_pip(p2, -i/2) return ''' # go! stopLoss = atr.Current.Value * 0.1 profitTarget = atr.Current.Value * 0.15 currentPrice = data[fxBrick.symbol].Price signal_macd = macd.Signal.Current.Value delta = (macd.Current.Value - signal_macd) / macd.Fast.Current.Value #if not self.Portfolio.Invested \ if macd.Current.Value > 0 \ and macd.Current.Value > macd.Signal.Current.Value \ and rsi.Current.Value > 0.7 \ and bb.UpperBand.Current.Value > fxBrick.bbUpperPrevious: stopLossPrice = currentPrice - stopLoss profitTargetPrice = currentPrice + profitTarget limitPrice = bb.UpperBand.Current.Value # if not self.Portfolio.Invested: #if self.buy_flag < 1: # -------------------------------- self.buy_flag = 1 self.sell_flag = 0 # def emit_insight(self, time_delta, direction, magnitude=None, confidence=None, model=None, weight=None): fxBrick.emit_insight(self.scalp_period, InsightDirection.Up, signal_macd, delta, "Forex Scalp Sampler 5 min (UP)", .7) #self.qcAlgo.SetHoldings(fxBrick.symbol, self.fxHoldingCoeff) #self.qcAlgo.LimitOrder(fxBrick.symbol, trade_units, profitTargetPrice) #self.qcAlgo.StopMarketOrder(fxBrick.symbol, trade_units, stopLossPrice) #self.qcAlgo.SetHoldings(fxBrick.symbol, 0.9) self.qcAlgo.Buy(fxBrick.symbol, trade_units) self.qcAlgo.LimitOrder(fxBrick.symbol, -trade_units, profitTargetPrice) self.qcAlgo.StopMarketOrder(fxBrick.symbol, -trade_units, stopLossPrice) # -------------------------------- else: stopLossPrice = currentPrice - stopLoss profitTargetPrice = currentPrice + profitTarget limitPrice = bb.LowerBand.Current.Value # if self.Portfolio.Invested: #if self.sell_flag < 1: # -------------------------------- self.buy_flag = 0 self.sell_flag = 1 fxBrick.emit_insight(self.scalp_period, InsightDirection.Down, signal_macd, delta, "Forex Scalp Sampler 5 min (DOWN)", .7) #self.qcAlgo.SetHoldings(fxBrick.symbol, -self.fxHoldingCoeff) #self.qcAlgo.LimitOrder(fxBrick.symbol, -trade_units, profitTargetPrice) #self.qcAlgo.StopMarketOrder(fxBrick.symbol, -trade_units, stopLossPrice) #self.qcAlgo.SetHoldings(fxBrick.symbol, 0) self.qcAlgo.Sell(fxBrick.symbol, trade_units) self.qcAlgo.LimitOrder(fxBrick.symbol, -trade_units, profitTargetPrice) self.qcAlgo.StopMarketOrder(fxBrick.symbol, -trade_units, stopLossPrice) # -------------------------------- fxBrick.updated_bb_prev() ''' # ********** END: Test-Strategy ******************
''' To use this library place this at the top: from ForexTrendBase import ForexTrendBase Then define a fx strategy class class ForexCustomStrategy(ForexTrendBase): ... ''' from clr import AddReference AddReference("System") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Indicators") AddReference("QuantConnect.Common") from System import * from QuantConnect import * from QuantConnect.Algorithm import * from QuantConnect.Indicators import * from datetime import datetime # from Risk.MaximumDrawdownPercentPerSecurity import MaximumDrawdownPercentPerSecurity from ForexGalaxyBay import ForexGalaxyBay from AlgoToolbox import AlgoToolbox import datetime # ************************************* class ForexTrendBase(QCAlgorithm): # ************************************* # ------------------------------------------------------------------------------------------------------------- def Initialize(self): # ------------------------------------------------------------------------------------------------------------- # init self.csv_sep_chr = ";" #self.last_week = 0 #self.last_year = 0 #self.allow_strategy_run = False # test shift # self.min_scalp_shift = 2 # self.min_scalp_shift_offset = 1 # galaxy of bricks self.selected_galaxy = None # main shift! self.min_scalp_shift = 1 # main! self.min_scalp_shift_offset = 0 self.show_debug = self.get_bool_param("show_debug", False, False) self.show_log = self.get_bool_param("show_log", False, False) self.toolbox = AlgoToolbox(self, self.show_debug, self.show_log) self.toolbox.show_log("ENVIRONMENT:") self.toolbox.show_log("========================================") self.resolution = Resolution.Minute self.anchorResolution = Resolution.Hour # set Start/End Dates/Hours for main Algo and Charts self.setDateMargins() self.anchor_period = self.get_int_param("anchor_period") self.min_anchor_count = self.anchor_period - 1 #self.anchor_period self.scalp_period = self.get_int_param("scalp_period") self.min_scalp_count = self.scalp_period - self.min_scalp_shift #self.scalp_period self.anchor_max_slots = self.get_int_param("anchor_max_slots") self.scalp_max_slots = self.get_int_param("scalp_max_slots") self.chart_disable = self.get_bool_param("chart_disable") self.plot_ema_cross = False #self.get_bool_param("plot_ema_cross") #self.trade_units = self.get_int_param("trade_units") self.bar_touch_margins = self.get_str_param("bar_touch_margins") # delta settings self.anchor_delta_min_pips = self.get_int_param("anchor_delta_min_pips") self.scalp_delta_min_pips = self.get_int_param("scalp_delta_min_pips") # trigger settings self.touch_trigger_pip_tolerance = self.get_float_param("touch_trigger_pip_tolerance") self.pullback_trigger_pips_up = self.get_float_param("pullback_trigger_pips_up") self.pullback_trigger_pips_down = self.get_float_param("pullback_trigger_pips_down") # confidence properties try: self.confidence_trade_enabled_main = self.get_float_param("confidence_te_0") self.confidence_trade_enabled_hist = self.get_float_param("confidence_te_hist") self.confidence_indicator_delta_anchor = self.get_float_param("confidence_ind_a") self.confidence_indicator_delta_scalp = self.get_float_param("confidence_ind_s") except: self.confidence_trade_enabled_main = self.get_float_param("confid_te_0") self.confidence_trade_enabled_hist = self.get_float_param("confid_te_hist") self.confidence_indicator_delta_anchor = self.get_float_param("confid_ind_a") self.confidence_indicator_delta_scalp = self.get_float_param("confid_ind_s") # get "orange risk"-level try: self.orange_risk = self.get_float_param("orange_risk") except: self.orange_risk = 100 self.exit_1_rate = self.get_int_param("exit_1_rate") / 100 self.exit_1_close = self.exit_1_rate > 0 self.exit_strategy_trailing_exit = self.get_bool_param("trailing") self.exit_strategy_break_even_exit = not self.exit_strategy_trailing_exit self.anchor_lookback_for_trade_enabled = self.get_int_param("anchor_lookback_trade_enabled") self.direction_lookback = self.get_bool_param("direction_lookback") self.indicator_lookback = self.get_bool_param("indicator_lookback") self.drawdown_on_trade_start = self.get_bool_param("drawdown_on_trade_start") self.exit_1_profit_guaranteed = self.get_int_param("exit1_garant") self.trailing_exit_stop_loss_bars = self.get_int_param("trailing_exit_stop_loss_bars") self.engulf = self.get_bool_param("engulf") if self.engulf: self.engulf_ratio = self.get_float_param("engulf") else: self.engulf_ratio = 0 self.reverse_trade = self.get_bool_param("reverse_trade") # to show DEBUG-Message: self.toolbox.show_debug(<message>,<prefix>="",<suffix>="") # to show LOG-Message: self.toolbox.show_log(<message>,<prefix>="",<suffix>="") self.toolbox = AlgoToolbox(self, self.show_debug, self.show_log) # trade settings self.SetCash(self.get_int_param("cash_book")) self.forex_leverage = self.get_float_param("forex_leverage") self.trade_magnitude_amplifier = self.get_float_param("trade_magnitude_amplifier") self.emit_trades = self.get_bool_param("emit_trades") self.emit_insights = self.get_bool_param("emit_insights") self.emit_info_insights = self.get_bool_param("emit_info_insights") self.cash_reserve_ratio = self.get_int_param("cash_reserve_ratio_percent") / 100 self.min_cash_reserve_ratio = self.get_int_param("min_cash_reserve_ratio_percent") / 100 self.max_cash_reserve_ratio = self.get_int_param("max_cash_reserve_ratio_percent") / 100 self.take_profit = self.get_float_param("take_profit_percent") / 100 self.stop_loss = self.get_float_param("stop_loss_percent") / 100 # max 50% of cash reserve if self.cash_reserve_ratio > self.max_cash_reserve_ratio: self.cash_reserve_ratio = self.max_cash_reserve_ratio else: # min 10% of cash reserve if self.cash_reserve_ratio < self.min_cash_reserve_ratio: self.cash_reserve_ratio = self.min_cash_reserve_ratio self.cash_max_ratio = 1 - self.cash_reserve_ratio # drawdown = self.get_float_param("max_drawdown_pps") # self.SetRiskManagement(MaximumDrawdownPercentPerSecurity(drawdown)) self.AddRiskManagement(NullRiskManagementModel()) # setup forex brokerages self.Broker = self.get_str_param("Broker") if self.Broker == "FXCM": self.SetBrokerageModel(BrokerageName.FxcmBrokerage) self.Market = Market.FXCM else: self.SetBrokerageModel(BrokerageName.OandaBrokerage) self.Market = Market.Oanda # create fx galaxy of major forex booster pairs self.forex_galaxy = self.selectGalaxyStars() # create fx sample strategy self.forex_strategy = self.selectStrategy() # assign strategy to all stars in galaxy self.fusionGalaxyStrategy() self.SetWarmUp(timedelta(self.get_int_param("warmup_days"))) self.show_csv_header = True # self.get_bool_param("show_csv_header") self.toolbox.show_log("========================================") # show csv-header if any if self.show_csv_header: self.toolbox.show_csv_log(self.csv_sep_chr \ + "Trade-Time" + self.csv_sep_chr \ + "Currency-Pair" + self.csv_sep_chr \ + "Pair-Weight" + self.csv_sep_chr \ + "Data-Time" + self.csv_sep_chr \ + "Trade-Type" + self.csv_sep_chr \ + "Trend-Direction" + self.csv_sep_chr \ + "Model" + self.csv_sep_chr \ + "Confidence" + self.csv_sep_chr \ + "Magnitude" + self.csv_sep_chr \ + "Current-Level" + self.csv_sep_chr \ + "Entry-Level" + self.csv_sep_chr \ + "StopLoss-Level" + self.csv_sep_chr \ + "StopLoss-Purple" + self.csv_sep_chr \ + "Trade-Risk" + self.csv_sep_chr \ + "Break-Even" + self.csv_sep_chr \ + "Trade-Exit" + self.csv_sep_chr \ + "Trade-TakeProfit" + self.csv_sep_chr \ + "Start-Level" + self.csv_sep_chr \ + "Orange Risk-Level" + self.csv_sep_chr \ + "Given StopLoss" + self.csv_sep_chr \ + "Given TakeProfit" + self.csv_sep_chr \ + "Symbol Last Trade Profit" + self.csv_sep_chr \ + "Symbol unrealized Profit" + self.csv_sep_chr \ + "Symbol unrealized Profit %" + self.csv_sep_chr \ + "Portfolio Cash" + self.csv_sep_chr \ + "Portfolio Total-Profit" + self.csv_sep_chr \ + "Portfolio Total unrealized Profit") self.toolbox.show_log("========================================") # Optional: Be notified when securities change def OnSecuritiesChanged(self, changes): pass # ----------------------------------------------------------------------------------------------------------- def get_bool_param(self, param, default=False, show_log=True): # ----------------------------------------------------------------------------------------------------------- result = bool(self.get_parameter(param, default)) if show_log: self.log_param(param, result) return result # ----------------------------------------------------------------------------------------------------------- def get_int_param(self, param, default=0, show_log=True): # ----------------------------------------------------------------------------------------------------------- result = int(self.get_parameter(param, default)) if show_log: self.log_param(param, result) return result # ----------------------------------------------------------------------------------------------------------- def get_float_param(self, param, default=0.0, show_log=True): # ----------------------------------------------------------------------------------------------------------- result = float(self.get_parameter(param, default)) if show_log: self.log_param(param, result) return result # ----------------------------------------------------------------------------------------------------------- def get_str_param(self, param, default="", show_log=True): # ----------------------------------------------------------------------------------------------------------- result = self.get_parameter(param, default) if show_log: self.log_param(param, result) return result # ----------------------------------------------------------------------------------------------------------- def get_parameter(self, param, default = None): # ----------------------------------------------------------------------------------------------------------- result = str(default) try: result = self.GetParameter(param) except: err_msg = param + " not found!" self.toolbox.show_log(err_msg) self.Debug(err_msg) return result # ----------------------------------------------------------------------------------------------------------- def log_param(self, param, value): # ----------------------------------------------------------------------------------------------------------- self.toolbox.show_log(param + "=" + str(value)) # ----------------------------------------------------------------------------------------------------------- def setDateMargins(self): # ----------------------------------------------------------------------------------------------------------- # set start date start_date = self.toolbox.get_date(self.get_str_param("start_date"),"-") if start_date[0] > 0: self.SetStartDate(start_date[0], start_date[1], start_date[2]) # set end date of not empty end_date = self.toolbox.get_date(self.get_str_param("end_date"),"-") if end_date[0] > 0: self.SetEndDate(end_date[0], end_date[1], end_date[2]) # set chart start date chart_date_from = self.toolbox.get_date(self.get_str_param("chart_date_from"),"-") if chart_date_from[0] > 0: self.ChartStartDate = datetime(chart_date_from[0], chart_date_from[1], chart_date_from[2]) else: self.ChartStartDate = self.StartDate # set chart start hour chart_hour_from = self.get_str_param("chart_hour_from") if chart_hour_from: self.ChartStartHour = int(chart_hour_from) else: self.ChartStartHour = 0 # set chart end date chart_date_to = self.toolbox.get_date(self.get_str_param("chart_date_to"),"-") if chart_date_to[0] > 0: self.ChartEndDate = datetime(chart_date_to[0], chart_date_to[1], chart_date_from[2]) else: self.ChartEndDate = self.EndDate # set chart end hour chart_hour_to = self.get_str_param("chart_hour_to") if chart_hour_to: self.ChartEndHour = int(chart_hour_to) else: self.ChartEndHour = 0 # adjust chart end/start dates if self.ChartStartDate.replace(tzinfo=None) < self.StartDate.replace(tzinfo=None): self.ChartStartDate = self.StartDate if self.ChartEndDate.replace(tzinfo=None) > self.EndDate.replace(tzinfo=None): self.ChartEndDate = self.EndDate if self.ChartStartDate.replace(tzinfo=None) > self.ChartEndDate.replace(tzinfo=None): self.ChartEndDate = self.ChartStartDate # ----------------------------------------------------------------------------------------------------------- def selectGalaxy(self, galaxy_type): # ----------------------------------------------------------------------------------------------------------- galaxy = ForexGalaxyBay() return galaxy.selectGalaxy(galaxy_type) # base (override) # ----------------------------------------------------------------------------------------------------------- def selectStrategy(self): # ----------------------------------------------------------------------------------------------------------- return None # base (override) # ----------------------------------------------------------------------------------------------------------- def selectGalaxyStars(self): # ----------------------------------------------------------------------------------------------------------- return None # ----------------------------------------------------------------------------------------------------------- def fusionGalaxyStrategy(self): # ----------------------------------------------------------------------------------------------------------- for fxTickerStar in self.forex_galaxy.values(): fxTickerStar.strategy = self.forex_strategy # ------------------------------------------------------------------------------------------------------------- def OnData(self, data): # ------------------------------------------------------------------------------------------------------------- # init self.last_data = data # saving last data # Go! if not self.IsWarmingUp: # run each time self.forex_strategy.Run(data) # run on scalp edge (call Srategy Scalp-Run via Main-Algo) if self.scalp_time_elapsed(): # pass self.forex_strategy.Run(data, True) # run on anchor edge (call Srategy Anchor-Run via Main-Algo) if self.anchor_time_elapsed(): # pass self.forex_strategy.Run(data, False, True) else: return # ------------------------------------------------------------------------------------------------------------- def OnOrderEvent(self, orderEvent): # ------------------------------------------------------------------------------------------------------------- order = self.Transactions.GetOrderById(orderEvent.OrderId) if order.Status == OrderStatus.Filled: if order.Type == OrderType.Limit or order.Type == OrderType.StopMarket: self.Transactions.CancelOpenOrders(order.Symbol) if order.Status == OrderStatus.Canceled: self.Log("Storno Order: " + str(orderEvent)) #-------------------------------------------------- # ----------------------------------------------------------------------------------------------------------- def scalp_time_elapsed(self): # ----------------------------------------------------------------------------------------------------------- # exit if not end of anchor time frame count = self.min_scalp_count + self.min_scalp_shift - self.min_scalp_shift_offset if count == self.scalp_period: self.min_scalp_count = 0 return True else: self.min_scalp_count = count return False # ----------------------------------------------------------------------------------------------------------- def anchor_time_elapsed(self): # ----------------------------------------------------------------------------------------------------------- # exit if not end of anchor time frame count = self.min_anchor_count + 1 if count == self.anchor_period: self.min_anchor_count = 0 return True else: self.min_anchor_count = count return False # ------------------------------------------------------------------------------------------------------------- def pip_diff(self, open, close): # ------------------------------------------------------------------------------------------------------------- return self.toolbox.pip_diff(open, close) # ------------------------------------------------------------------------------------------------------------- def add_pip(self, price, pip): # ------------------------------------------------------------------------------------------------------------- return self.toolbox.add_pip(price, pip)
# ************************************* class ForexGalaxyBay: # ************************************* ''' To use this library place this at the top: from ForexGalaxyBay import ForexGalaxyBay Then instantiate the function: fx = ForexGalaxyBay() for fx_ticker in fx.selectGalaxy("MajorTen"): self.AddForex(fx_ticker, resolution, market) ... ''' # ---------------------------------------------------------------------------- def __init__(self): # ---------------------------------------------------------------------------- # Currency-Pair Symbol: Weight self.fxPairs_MajorForexBooster_Orig = { \ "EURUSD": .27 ,"USDJPY": .13 ,"GBPUSD": .11 ,"AUDUSD": .09 ,"USDCAD": .06 ,"USDCHF": .06 ,"NZDUSD": .04 ,"EURJPY": .04 ,"GBPJPY": .04 ,"EURGBP": .03 ,"AUDJPY": .03 ,"EURAUD": .02 ,"EURCAD": .02 ,"AUDCAD": .02 ,"USDHKD": .01 ,"EURNZD": .01 ,"AUDNZD": .01 ,"USDMXN": .01 } self.fxPairs_MajorForexBooster = { \ "EURUSD": .27 ,"USDJPY": .13 ,"GBPUSD": .11 ,"AUDUSD": .09 ,"USDCAD": .06 ,"USDCHF": .06 ,"NZDUSD": .04 ,"EURJPY": .04 ,"GBPJPY": .04 ,"EURGBP": .03 ,"AUDJPY": .03 ,"EURAUD": .02 ,"EURCAD": .02 ,"AUDCAD": .02 ,"USDHKD": .01 ,"EURNZD": .01 ,"AUDNZD": .01 ,"USDMXN": .01 } self.fxPairs_MajorForexBooster_Equal = { \ "EURUSD": .05 ,"USDJPY": .05 ,"GBPUSD": .05 ,"AUDUSD": .05 ,"USDCAD": .05 ,"USDCHF": .05 ,"NZDUSD": .05 ,"EURJPY": .05 ,"GBPJPY": .05 ,"EURGBP": .05 ,"AUDJPY": .05 ,"EURAUD": .05 ,"EURCAD": .05 ,"AUDCAD": .05 ,"USDHKD": .05 ,"EURNZD": .05 ,"AUDNZD": .05 ,"USDMXN": .05 ,"CADJPY": .05 ,"CADHKD": .05 } self.fxPairs_MajorForexBooster_Cool = { \ "EURUSD": .27 ,"USDJPY": .13 ,"GBPUSD": .11 ,"AUDUSD": .09 ,"USDCAD": .06 ,"USDCHF": .06 ,"NZDUSD": .04 ,"EURJPY": .04 ,"GBPJPY": .04 ,"EURGBP": .03 ,"AUDJPY": .03 ,"EURAUD": .02 ,"EURCAD": .02 ,"AUDCAD": .02 ,"USDHKD": .01 ,"EURNZD": .01 ,"AUDNZD": .01 ,"EURMXN": .01 } self.fxPairs_MajorForexBooster_Cool_Variant = { \ "EURUSD": .27 ,"USDJPY": .12 ,"GBPUSD": .12 ,"AUDUSD": .11 ,"USDCAD": .06 ,"USDCHF": .06 ,"NZDUSD": .04 ,"EURJPY": .04 ,"GBPJPY": .04 ,"EURGBP": .03 ,"AUDJPY": .03 ,"EURAUD": .02 ,"EURCAD": .02 ,"AUDCAD": .02 ,"USDHKD": .01 ,"EURNZD": .01 ,"AUDNZD": .01 #"USDMXN": .01 } self.fxPairs_MajorForexBooster_Dude = { \ "EURUSD": .27 ,"USDJPY": .13 ,"GBPUSD": .11 ,"AUDUSD": .10 ,"USDCAD": .07 ,"USDCHF": .07 ,"NZDUSD": .05 ,"EURGBP": .04 ,"EURAUD": .03 ,"EURCAD": .03 ,"AUDCAD": .03 ,"EURNZD": .02 ,"AUDNZD": .02 ,"USDMXN": .02 ,"USDHKD": .01 } self.fxPairs_MajorForexBooster_BigDude = { \ "EURUSD": .23 ,"USDJPY": .11 ,"GBPUSD": .10 ,"AUDUSD": .10 ,"USDMXN": .10 ,"USDCAD": .07 ,"USDCHF": .07 ,"EURCAD": .04 ,"AUDCAD": .04 ,"NZDUSD": .04 ,"EURGBP": .03 ,"EURAUD": .02 ,"EURNZD": .02 ,"AUDNZD": .02 ,"USDHKD": .01 } self.fxPairs_MagicTrinity = { \ "EURUSD": .5 ,"GBPUSD": .3 ,"USDJPY": .2 } self.fxPairs_MajorFive = { \ "EURUSD": .4 ,"USDJPY": .2 ,"GBPUSD": .2 ,"AUDUSD": .1 ,"USDCAD": .1 } self.fxPairs_MajorTen_Once = { \ "EURUSD": .1 ,"USDJPY": .1 ,"GBPUSD": .1 ,"AUDUSD": .1 ,"USDCAD": .1 ,"USDCHF": .1 ,"NZDUSD": .1 ,"EURJPY": .1 ,"GBPJPY": .1 ,"EURGBP": .1 } self.fxPairs_MajorTen_Double = { \ "EURUSD": .2 ,"USDJPY": .2 ,"GBPUSD": .2 ,"AUDUSD": .2 ,"USDCAD": .2 ,"USDCHF": .2 ,"NZDUSD": .2 ,"EURJPY": .2 ,"GBPJPY": .2 ,"EURGBP": .2 } self.fxPairs_MajorTen_Orig = { \ "EURUSD": .33 ,"USDJPY": .16 ,"GBPUSD": .13 ,"AUDUSD": .07 ,"USDCAD": .06 ,"USDCHF": .06 ,"NZDUSD": .05 ,"EURJPY": .05 ,"GBPJPY": .05 ,"EURGBP": .04 } self.fxPairs_MajorTen_Ext1 = { \ "EURUSD": .3 ,"USDJPY": .1 ,"AUDNZD": .05 ,"AUDUSD": .05 ,"USDCAD": .1 ,"USDCHF": .1 ,"NZDUSD": .05 ,"EURJPY": .1 ,"GBPJPY": .1 ,"EURGBP": .05 } self.fxPairs_EurUsd = { \ "EURUSD": 1 } self.fxPairs_EurGbp = { \ "EURGBP": 1 } self.fxPairs_EURUSD_USDCHF = { \ "EURUSD": .5 ,"USDCHF": .5 } self.fxPairs_EURUSD_GBPUSD = { \ "EURUSD": .7 ,"GBPUSD": .3 } self.fxPairs_EURUSD_GBPUSD_EQUAL = { \ "EURUSD": .5 ,"GBPUSD": .5 } self.fxPairs_EurUsd_Orig = { \ "EURUSD": 1 } self.fxPairs_MajorForexBooster_JPY = { \ "EURUSD": .05 ,"USDJPY": .05 ,"GBPUSD": .05 ,"AUDUSD": .05 ,"USDCAD": .05 ,"USDCHF": .05 ,"NZDUSD": .05 ,"EURJPY": .05 ,"GBPJPY": .05 ,"EURGBP": .05 ,"AUDCAD": .05 ,"AUDJPY": .05 ,"AUDNZD": .05 ,"CADJPY": .05 ,"EURNZD": .05 ,"GBPNZD": .05 ,"SGDJPY": .05 ,"NZDJPY": .05 ,"USDJPY": .05 } self.fxPairs_MajorForexBooster_Asia_Ext = { \ "EURUSD": .03125 ,"USDJPY": .03125 ,"GBPUSD": .03125 ,"AUDUSD": .03125 ,"USDCAD": .03125 ,"USDCHF": .03125 ,"NZDUSD": .03125 ,"EURJPY": .03125 ,"GBPJPY": .03125 ,"EURGBP": .03125 ,"AUDCAD": .03125 ,"AUDCHF": .03125 ,"AUDHKD": .03125 ,"AUDJPY": .03125 ,"AUDNZD": .03125 ,"CADHKD": .03125 ,"CADJPY": .03125 ,"CHFHKD": .03125 ,"CHFJPY": .03125 ,"EURHKD": .03125 ,"EURNZD": .03125 ,"GBPHKD": .03125 ,"GBPNZD": .03125 ,"HKDJPY": .03125 ,"NZDHKD": .03125 ,"NZDJPY": .03125 ,"SGDHKD": .03125 ,"SGDJPY": .03125 ,"TRYJPY": .03125 ,"USDHKD": .03125 ,"USDJPY": .03125 ,"ZARJPY": .03125 } self.fxPairs_MajorForexBooster_Asia = { \ "USDJPY": .037 ,"AUDUSD": .037 ,"NZDUSD": .037 ,"EURJPY": .037 ,"GBPJPY": .037 ,"AUDCAD": .037 ,"AUDCHF": .037 ,"AUDHKD": .037 ,"AUDJPY": .037 ,"AUDNZD": .037 ,"CADHKD": .037 ,"CADJPY": .037 ,"CHFHKD": .037 ,"CHFJPY": .037 ,"EURHKD": .037 ,"EURNZD": .037 ,"GBPHKD": .037 ,"GBPNZD": .037 ,"HKDJPY": .037 ,"NZDHKD": .037 ,"NZDJPY": .037 ,"SGDHKD": .037 ,"SGDJPY": .037 ,"TRYJPY": .037 ,"USDHKD": .037 ,"USDJPY": .037 ,"ZARJPY": .037 } self.fxPairs_MajorTen = { \ "EURUSD": .1 ,"USDJPY": .1 ,"GBPUSD": .1 ,"AUDUSD": .1 ,"USDCAD": .1 ,"USDCHF": .1 ,"NZDUSD": .1 ,"EURJPY": .1 ,"GBPJPY": .1 ,"EURGBP": .1 } self.fxPairs_MajorTen_Main = { \ "EURUSD": .1 ,"USDJPY": .1 ,"GBPUSD": .1 ,"AUDUSD": .1 ,"USDCAD": .1 ,"USDCHF": .1 ,"NZDUSD": .1 ,"EURJPY": .1 ,"GBPJPY": .1 ,"EURGBP": .1 } self.fxPairs_MajorTen_OldStyle = { \ "EURUSD": .1 ,"EURCAD": .1 ,"CHFUSD": .1 ,"EURAUD": .1 ,"GBPNZD": .1 ,"NZDEUR": .1 ,"GBPEUR": .1 ,"USDCAD": .1 ,"AUDCAD": .1 ,"AUDNZD": .1 } self.fxPairs_MajorForexBooster_All = { \ "AUDCAD": .01429 ,"AUDCHF": .01429 ,"AUDHKD": .01429 ,"AUDJPY": .01429 ,"AUDNZD": .01429 ,"AUDUSD": .01429 ,"CADCHF": .01429 ,"CADHKD": .01429 ,"CADJPY": .01429 ,"CADSGD": .01429 ,"CHFHKD": .01429 ,"CHFJPY": .01429 ,"CHFZAR": .01429 ,"EURAUD": .01429 ,"EURCAD": .01429 ,"EURCHF": .01429 ,"EURCZK": .01429 ,"EURDKK": .01429 ,"EURGBP": .01429 ,"EURHKD": .01429 ,"EURHUF": .01429 ,"EURJPY": .01429 ,"EURNOK": .01429 ,"EURNZD": .01429 ,"EURPLN": .01429 ,"EURSEK": .01429 ,"EURSGD": .01429 ,"EURTRY": .01429 ,"EURUSD": .04289 ,"EURZAR": .01429 ,"GBPAUD": .01429 ,"GBPCAD": .01429 ,"GBPCHF": .01429 ,"GBPHKD": .01429 ,"GBPJPY": .01429 ,"GBPNZD": .01429 ,"GBPPLN": .01429 ,"GBPSGD": .01429 ,"GBPUSD": .01429 ,"GBPZAR": .01429 ,"HKDJPY": .01429 ,"NZDCAD": .01429 ,"NZDCHF": .01429 ,"NZDHKD": .01429 ,"NZDJPY": .01429 ,"NZDSGD": .01429 ,"NZDUSD": .01429 ,"SGDCHF": .01429 ,"SGDHKD": .01429 ,"SGDJPY": .01429 ,"TRYJPY": .01429 ,"USDCAD": .01429 ,"USDCHF": .01429 ,"USDCNH": .01429 ,"USDCZK": .01429 ,"USDDKK": .01429 ,"USDHKD": .01429 ,"USDHUF": .01429 ,"USDJPY": .01429 ,"USDMXN": .01429 ,"USDNOK": .01429 ,"USDPLN": .01429 ,"USDSEK": .01429 ,"USDSGD": .01429 ,"USDTHB": .01429 ,"USDTRY": .01429 ,"USDZAR": .01429 ,"ZARJPY": .01429 } self.fxPairs_Fx_Agile_Six = { \ # selected (green) "EURUSD": .5 ,"GBPUSD": .2 ,"AUDUSD": .1 ,"EURGBP": .1 ,"HKDJPY": .05 ,"USDJPY": .05 } self.fxPairs_Fx_Agile_Six_Even = { \ # selected (green) "EURUSD": .4 ,"GBPUSD": .2 ,"AUDUSD": .1 ,"EURGBP": .1 ,"HKDJPY": .1 ,"USDJPY": .1 } self.fxPairs_Fx_Agile_Six_Equal = { \ # selected (green) "EURUSD": .5 ,"GBPUSD": .1 ,"AUDUSD": .1 ,"EURGBP": .1 ,"HKDJPY": .1 ,"USDJPY": .1 } self.fxPairs_Fx_Agile_Five_Equal = { \ "EURUSD": .5 ,"GBPUSD": .2 ,"AUDUSD": .1 ,"HKDJPY": .1 ,"USDJPY": .1 } self.fxPairs_Fx_Agile_Quattro = { \ "EURUSD": .4 ,"GBPUSD": .3 ,"AUDUSD": .2 ,"HKDJPY": .1 } self.fxPairs_Fx_Agile_Trident = { \ "EURUSD": .5 ,"GBPUSD": .3 ,"AUDUSD": .2 } self.fxPairs_Fx_Test = { \ "EURUSD": 1 #"GBPUSD": 1 #"AUDUSD": 1 #"EURGBP": 1 #"HKDJPY": 1 #"USDJPY": 1 #"USDCAD": 1 #"USDCHF": 1 #"EURNZD": 1 #"EURAUD": 1 #"AUDCAD": 1 #"AUDCHF": 1 #"AUDHKD": 1 #"AUDJPY": 1 #"AUDNZD": 1 #"CADCHF": 1 #"CADHKD": 1 #"CADJPY": 1 #"CADSGD": 1 #"CHFHKD": 1 #"CHFJPY": 1 #"CHFZAR": 1 #"EURCAD": 1 #"EURCHF": 1 #"EURCZK": 1 #"EURDKK": 1 #"EURHKD": 1 #"EURHUF": 1 #"EURJPY": 1 #"EURNOK": 1 #"EURPLN": 1 #"EURSEK": 1 #"EURSGD": 1 #"EURTRY": 1 #"EURZAR": 1 #"GBPAUD": 1 #"GBPCAD": 1 #"GBPCHF": 1 #"GBPHKD": 1 #"GBPJPY": 1 #"GBPNZD": 1 #"GBPPLN": 1 #"GBPSGD": 1 #"GBPZAR": 1 #"NZDCAD": 1 #"NZDCHF": 1 #"NZDHKD": 1 #"NZDJPY": 1 #"NZDSGD": 1 #"NZDUSD": 1 #"SGDCHF": 1 #"SGDHKD": 1 #"SGDJPY": 1 #"TRYJPY": 1 #"USDCNH": 1 #"USDCZK": 1 #"USDDKK": 1 #"USDHKD": 1 #"USDHUF": 1 #"USDMXN": 1 #"USDNOK": 1 #"USDPLN": 1 #"USDSEK": 1 #"USDSGD": 1 #"USDTHB": 1 #"USDTRY": 1 #"USDZAR": 1 #"ZARJPY": 1 } self.fxPairs_Fx_Agile_Trident = { \ "EURUSD": .5 ,"GBPUSD": .3 ,"AUDUSD": .2 } # ---------------------------------------------------------------------------- def selectGalaxy(self, galaxy_type = None): # ---------------------------------------------------------------------------- if galaxy_type.strip().upper() == "AgileTrident".strip().upper(): return self.fxPairs_Fx_Agile_Trident if galaxy_type.strip().upper() == "AgileQuattro".strip().upper(): return self.fxPairs_Fx_Agile_Quattro if galaxy_type.strip().upper() == "Test".strip().upper(): return self.fxPairs_Fx_Test if galaxy_type.strip().upper() == "EurUsd".strip().upper(): return self.fxPairs_EurUsd if galaxy_type.strip().upper() == "EurUsd_GbpUsd".strip().upper(): return self.fxPairs_EURUSD_GBPUSD if galaxy_type.strip().upper() == "EurUsd_GbpUsd_E".strip().upper(): return self.fxPairs_EURUSD_GBPUSD_EQUAL if galaxy_type.strip().upper() == "MajorFive".strip().upper(): return self.fxPairs_MajorFive if galaxy_type.strip().upper() == "AgileSix".strip().upper(): return self.fxPairs_Fx_Agile_Six if galaxy_type.strip().upper() == "AgileSixEven".strip().upper(): return self.fxPairs_Fx_Agile_Six_Even if galaxy_type.strip().upper() == "AgileSixEqual".strip().upper(): return self.fxPairs_Fx_Agile_Six_Equal if galaxy_type.strip().upper() == "AgileFiveEqual".strip().upper(): return self.fxPairs_Fx_Agile_Five_Equal if galaxy_type.strip().upper() == "MagicTrinity".strip().upper(): return self.fxPairs_MagicTrinity if galaxy_type.strip().upper() == "EurGbp".strip().upper(): return self.fxPairs_EurGbp if galaxy_type.strip().upper() == "EurUsd_Orig".strip().upper(): return self.fxPairs_EurUsd_Orig if galaxy_type.strip().upper() == "EURUSD_USDCHF".strip().upper(): return self.fxPairs_EURUSD_USDCHF if galaxy_type.strip().upper() == "MajorForexBooster".strip().upper(): return self.fxPairs_MajorForexBooster if galaxy_type.strip().upper() == "MajorForexBooster_Equal".strip().upper(): return self.fxPairs_MajorForexBooster_Equal if galaxy_type.strip().upper() == "MFB_Equal".strip().upper(): return self.fxPairs_MajorForexBooster_Equal if galaxy_type.strip().upper() == "MajorForexBooster_All".strip().upper(): return self.fxPairs_MajorForexBooster_All if galaxy_type.strip().upper() == "MajorForexBooster_Asia".strip().upper(): return self.fxPairs_MajorForexBooster_Asia if galaxy_type.strip().upper() == "MajorForexBooster_Asia_Ext".strip().upper(): return self.fxPairs_MajorForexBooster_Asia_Ext if galaxy_type.strip().upper() == "MajorForexBooster_Cool".strip().upper(): return self.fxPairs_MajorForexBooster_Cool if galaxy_type.strip().upper() == "MFB_Cool".strip().upper(): return self.fxPairs_MajorForexBooster_Cool if galaxy_type.strip().upper() == "MFB_Cool_Variant".strip().upper(): return self.fxPairs_MajorForexBooster_Cool_Variant if galaxy_type.strip().upper() == "MajorForexBooster_Dude".strip().upper(): return self.fxPairs_MajorForexBooster_Dude if galaxy_type.strip().upper() == "MFB_Dude".strip().upper(): return self.fxPairs_MajorForexBooster_Dude if galaxy_type.strip().upper() == "MajorForexBooster_BigDude".strip().upper(): return self.fxPairs_MajorForexBooster_BigDude if galaxy_type.strip().upper() == "MFB_BigDude".strip().upper(): return self.fxPairs_MajorForexBooster_BigDude if galaxy_type.strip().upper() == "MajorForexBooster_JPY".strip().upper(): return self.fxPairs_MajorForexBooster_JPY if galaxy_type.strip().upper() == "MajorForexBooster_Orig".strip().upper(): return self.fxPairs_MajorForexBooster_Orig if galaxy_type.strip().upper() == "MajorTen".strip().upper(): return self.fxPairs_MajorTen if galaxy_type.strip().upper() == "MajorTen_Double".strip().upper(): return self.fxPairs_MajorTen_Double if galaxy_type.strip().upper() == "MajorTen_Ext1".strip().upper(): return self.fxPairs_MajorTen_Ext1 if galaxy_type.strip().upper() == "MajorTen_Main".strip().upper(): return self.fxPairs_MajorTen_Main if galaxy_type.strip().upper() == "MajorTen_OldStyle".strip().upper(): return self.fxPairs_MajorTen_OldStyle if galaxy_type.strip().upper() == "MajorTen_Once".strip().upper(): return self.fxPairs_MajorTen_Once if galaxy_type.strip().upper() == "MajorTen_Orig".strip().upper(): return self.fxPairs_MajorTen_Orig # default galaxy return self.fxPairs_EurUsd
''' To use this library place this at the top: from AlgoToolbox import AlgoToolbox Then instantiate the class: toolbox = AlgoToolbox(self, True, True) toolbox.show_log(...) ''' # ******************************** class AlgoToolbox: # ******************************** # ------------------------------------------------------------------------------------------------------------- def __init__(self, qcAlgo, showDebug = False, showLog = False): # ------------------------------------------------------------------------------------------------------------- self.qcAlgo = qcAlgo self.showDebug = showDebug self.showLog = showLog # ------------------------------------------------------------------------------------------------------------- def Log(self, msg, prefix = "", suffix = ""): # ------------------------------------------------------------------------------------------------------------- self.qcAlgo.Log("LOG: " + prefix + " : " + str(self.qcAlgo.Time) + " - " + msg + suffix) # ------------------------------------------------------------------------------------------------------------- def show_log(self, msg, prefix = "", suffix = ""): # ------------------------------------------------------------------------------------------------------------- if self.showLog: self.Log(msg, prefix, suffix) # ------------------------------------------------------------------------------------------------------------- def show_csv_log(self, msg, sep_char = ";", hide_prefix = True): # ------------------------------------------------------------------------------------------------------------- if self.showLog: if hide_prefix: self.qcAlgo.Log(str(msg)) else: self.qcAlgo.Log("LOG" + sep_char + str(msg)) # ------------------------------------------------------------------------------------------------------------- def Debug(self, msg, prefix = "", suffix = ""): # ------------------------------------------------------------------------------------------------------------- self.qcAlgo.Debug("DEBUG: " + prefix + " : " + str(self.qcAlgo.Time) + " - " + msg + suffix) # ------------------------------------------------------------------------------------------------------------- def show_debug(self, msg, prefix = "", suffix = ""): # ------------------------------------------------------------------------------------------------------------- if self.showLog: self.Debug(msg, prefix, suffix) # ------------------------------------------------------------------------------------------------------------- def pip_diff(self, open, close): # ------------------------------------------------------------------------------------------------------------- multiplier = self.pip_multiplier(open) pips = round((close - open) * multiplier) return int(pips) # ------------------------------------------------------------------------------------------------------------- def add_pip(self, price, pip): # ------------------------------------------------------------------------------------------------------------- divider = self.pip_divider(price) pip_price = pip * divider result_price = price + pip_price return result_price # ------------------------------------------------------------------------------------------------------------- def pip_multiplier(self, price): # ------------------------------------------------------------------------------------------------------------- pip_sign = 5 dec_pos = str(price).index('.') return 10 ** (pip_sign - dec_pos) # ------------------------------------------------------------------------------------------------------------- def pip_divider(self, price): # ------------------------------------------------------------------------------------------------------------- multiplier = self.pip_multiplier(price) return 1 / multiplier # ------------------------------------------------------------------------------------------------------------- def pip_round(self, price): # ------------------------------------------------------------------------------------------------------------- pip_size = 5 if price > 10: pip_size = 3 result = round(price, pip_size) return result # ----------------------------------------------------------------------------------------------------------- def get_date(self, strDate, splitChar): # ----------------------------------------------------------------------------------------------------------- if strDate and (not strDate.isspace()): str_date_parts = strDate.split(splitChar) year = int(str_date_parts[0]) month = int(str_date_parts[1]) day = int(str_date_parts[2]) return year, month, day else: return 0, 0, 0 # ----------------------------- def cut_by_zero_one(self, level): # ----------------------------- if level > 1: return 1 else: if level < 0: return 0 else: return level # ----------------------------- def cut_by_one_minusone(self, level): # ----------------------------- if level > 1: return 1 else: if level < -1: return -1 else: return level # ----------------------------- def normalize_percent(self, value): # ----------------------------- return self.cut_by_one_minusone(value/100) # ----------------------------- def normalize_percent_abs(self, value): # ----------------------------- return abs(self.cut_by_one_minusone(value/100))
from AlgoToolbox import AlgoToolbox from QuantConnect import * from numpy import diff import numpy as np # =================================== class ForexSymbolBrick: # =================================== # --------------------- def __init__(self,qcAlgo, ticker, weight, resolution, anchorResolution, scalpPeriod, anchorPeriod, showDebug = False, showLog = False, anchor_max_slots = 24, scalp_max_slots = 10): # --------------------- self.qcAlgo = qcAlgo self.strategy = None self.toolbox = qcAlgo.toolbox self.data = None self.csv_sep_chr = self.qcAlgo.csv_sep_chr self.StopLoss = None self.ProfitTarget = None self.anchor_lookback_for_trade_enabled = self.qcAlgo.anchor_lookback_for_trade_enabled self.direction_lookback = self.qcAlgo.direction_lookback self.indicator_lookback = self.qcAlgo.indicator_lookback self.drawdown_on_trade_start = self.qcAlgo.drawdown_on_trade_start self.exit_1_profit_guaranteed = self.qcAlgo.exit_1_profit_guaranteed # scalp ema props self.scalp_ema_fast = 0 self.scalp_ema_slow = 0 # anchor ema props self.anchor_ema_fast = 0 self.anchor_ema_slow = 0 # fast-/slow-ema inter-delta props (pips) self.anchor_emas_pips_delta = 0 self.scalp_emas_pips_delta = 0 # trade control props self.anchor_warmed_up = False self.check_trade_allowed = False # machine states self.STAND_BY = 0 self.TRIGGER_LONG = 1 self.TRIGGER_SHORT = -1 self.ENTRY_LONG = 10 self.ENTRY_SHORT = -10 self.EXIT_SHORT = -100 self.EXIT_LONG = 100 self.EXIT_1_SHORT_BASE = -101 self.EXIT_1_LONG_BASE = 101 self.EXIT_2_SHORT_BASE = -102 self.EXIT_2_LONG_BASE = 102 self.TRADE_CONTINUE_SHORT_1 = -201 self.TRADE_CONTINUE_LONG_1 = 201 self.TRADE_CONTINUE_SHORT_2 = -202 self.TRADE_CONTINUE_LONG_2 = 202 self.TRADE_SKIP_SHORT_1 = -301 self.TRADE_SKIP_LONG_1 = 301 self.TRADE_SKIP_SHORT_2 = -302 self.TRADE_SKIP_LONG_2 = 302 self.STOP_LOSS_SHORT = -401 self.STOP_LOSS_LONG = 401 self.STOP_LOSS_TAKE_PROFIT_SHORT = -402 self.STOP_LOSS_TAKE_PROFIT_LONG = 402 self.TREND_REVERSION_SHORT_TO_LONG = -403 self.TREND_REVERSION_LONG_TO_SHORT = 403 self.DROP_TRIGGER_SHORT = -404 self.DROP_TRIGGER_LONG = 404 self.trade_state = self.STAND_BY # trade business props self.trade_magnitude_scalp = 0 self.trade_magnitude_anchor = 0 self.trade_diff = 0 self.trade_risk = 0 self.trade_enter = 0 self.trade_break_even = 0 self.trade_stop_loss = 0 self.trade_take_profit = 0 self.trade_exit = 0 self.trade_start_level = 0 self.trade_take_profit_level = 0 self.trade_given_stop_loss = 0 self.trade_orange_risk_level = 0 self.stop_loss_level = 0 self.stop_loss_purple_level = 0 self.trade_lowest_low = 0 self.entry_level = 0 self.trade_take_profit = 0 self.trade_abs_start_level = 0 self.trade_abs_stop_level = 0 # order limit props self.Veto_CancelOrders = False self.Ignore_Cancel_Event = False self.ProfitTargetCanceled = False self.ProfitTarget_LastUpdate = None self.StopLossCanceled = False self.StopLoss_LastUpdate = None # semafor props self.IsLevel_TradeEnabled_Semafors = {} self.Direction_Semafors = {} self.Indicator_Deltas = {} self.IsLevel_Trigger_Semafor = False self.IsLevel_Entry_Semafor = False self.IsLevel_Exit_1_Semafor = False self.IsLevel_Exit_2_Semafor = False self.IsLevel_StopLoss_Semafor = False self.IsLevel_OrangeRisk_Semafor = False # trend props # self.is_trend_changed = False self.is_narrow_ema_anchor = False self.is_narrow_ema_scalp = False self.is_short_trade = False self.is_long_trade = False self.anchor_fast_indicator_margin = 0 self.anchor_slow_indicator_margin = 0 self.scalp_fast_indicator_margin = 0 self.scalp_mid_indicator_margin = 0 self.scalp_slow_indicator_margin = 0 # scalp fluent props self.scalp_fluent_time = 0 self.scalp_fluent_open = 0 self.scalp_fluent_high = 0 self.scalp_fluent_low = 0 self.scalp_fluent_close= 0 self.scalp_new_fluent_data = True # anchor fluent props self.anchor_fluent_time = 0 self.anchor_fluent_open = 0 self.anchor_fluent_high = 0 self.anchor_fluent_low = 0 self.anchor_fluent_close= 0 self.anchor_new_fluent_data = True # trade size props self.trade_units = 0 self.lot_size = 0 # trade props self.ticker = ticker self.resolution = resolution self.anchorResolution = anchorResolution self.direction_trade = InsightDirection.Flat self.forex = self.qcAlgo.AddForex(ticker, self.resolution, self.qcAlgo.Market) # trade insight props self.symbol = self.forex.Symbol self.weight = weight self.scalpPeriod = scalpPeriod self.direction_trend = InsightDirection.Flat self.trade_model = "STAND_BY" self.trade_confidence = 0 self.trade_magnitude = 0 # order lot size props self.lotSize = 1 self.lotsCount = 0 self.orderSize = 0 self.roundedOrderSize = 0 # profit benchmarks self.LastTradeProfit = 0 self.UnrealizedProfit = 0 self.UnrealizedProfitPercent = 0 self.Portfolio_Cash = 0 self.Portfolio_TotalProfit = 0 self.Portfolio_TotalUnrealizedProfit = 0 self.scalp_update_count = {} self.scalp_periods = [] self.anchorPeriod = anchorPeriod self.anchor_update_count = {} self.anchor_periods = [] self.scalp_max_slots = scalp_max_slots self.anchor_max_slots = anchor_max_slots # self.scalp_double_period = self.scalpPeriod ] 2 self.bbUpperPrevious = 0 self.scalpQuoteBar_RollingWindow = RollingWindow[QuoteBar](self.scalp_max_slots) self.anchorQuoteBar_RollingWindow = RollingWindow[QuoteBar](self.anchor_max_slots) self.scalpIndicators = {} self.anchorIndicators = {} # scalp Rate of Change indicator self.scalp_ROC = self.qcAlgo.ROC(self.symbol, scalpPeriod, self.resolution) # anchor Rate of Change indicator self.anchor_ROC = self.qcAlgo.ROC(self.symbol, anchorPeriod, self.anchorResolution) self.scalpIndicators_RollingWindows = {} self.anchorIndicators_RollingWindows = {} self.showDebug = showDebug self.showLog = showLog self.toolbox = AlgoToolbox(self.qcAlgo, self.showDebug, self.showLog) self.create_indicators() self.create_consolidators() self.scalp_chart = Chart(self.ticker + "-Scalp") self.anchor_chart = Chart(self.ticker + "-Anchor") # agnostic series (anchor / scalp) self.price_chart_serial_open = "Open" self.price_chart_serial_close = "Close" self.price_chart_serial_close_consolidated = "Close-Bar" self.price_chart_serial_open_price_point = "Open-PT" self.price_chart_serial_close_price_point = "Close-PT" self.price_chart_serial_high_price_point = "High-PT" self.price_chart_serial_low_price_point = "Low-PT" self.price_chart_serial_ema_cross_point = "EMA-Cross" # scalp series shorts (lines) self.price_chart_serial_short_entry = "Entry-S" self.price_chart_serial_short_stop_loss = "StopL-S" self.price_chart_serial_short_exit_1 = "Exit1-S" self.price_chart_serial_short_exit_2 = "Exit2-S" # scalp series shorts (points) self.price_chart_serial_short_trigger_point = "Trigger-SPT" self.price_chart_serial_short_entry_point = "Entry-SPT" self.price_chart_serial_short_stop_loss_point = "StopL-SPT" self.price_chart_serial_short_exit_1_point = "Exit1-SPT" self.price_chart_serial_short_exit_2_point = "Exit2-SPT" # scalp series longs (lines) self.price_chart_serial_long_entry = "Entry-L" self.price_chart_serial_long_stop_loss = "StopL-L" self.price_chart_serial_long_exit_1 = "Exit1-L" self.price_chart_serial_long_exit_2 = "Exit2-L" # scalp series longs (points) self.price_chart_serial_long_trigger_point = "Trigger-LPT" self.price_chart_serial_long_entry_point = "Entry-LPT" self.price_chart_serial_long_stop_loss_point = "StopL-LPT" self.price_chart_serial_long_exit_1_point = "Exit1-LPT" self.price_chart_serial_long_exit_2_point = "Exit2-LPT" # Define Scalp-Series: z.B. self.scalp_ticker("ema", 8) # Define Anchor-Series: z.B. self.anchor_ticker("ema", 8) self.create_scalp_chart() self.create_anchor_chart() # [ PREDICTIONS REGION (BEGIN) ] # --------------------- def Emit_Insight(self): # --------------------- self.emit_insight( self.scalpPeriod, \ self.direction_trend, \ self.trade_magnitude, \ self.trade_confidence, \ self.trade_model, \ self.weight) # --------------------- def emit_insight(self, time_delta_min, direction, magnitude=None, confidence=None, model=None, weight=None): # --------------------- # validation if not self.qcAlgo.emit_insights: return # init vars insight_timedelta = timedelta(minutes=time_delta_min) # Creates an insight for the current symbol, predicting that it will move up/down within given timedelta if (direction == InsightDirection.Flat): self.qcAlgo.EmitInsights( Insight.Price(self.symbol, insight_timedelta, InsightDirection.Flat)) else: insight = Insight( \ self.symbol, insight_timedelta, InsightType.Price, \ direction, magnitude, confidence, model, weight) self.qcAlgo.EmitInsights(insight) # [ PREDICTIONS REGION (END) ] # [ QUOTE BARS REGION (BEGIN) ] # --------------------- def create_consolidators(self): # --------------------- # create scalp onsolidator self.scalpConsolidator = QuoteBarConsolidator(timedelta(minutes=self.scalpPeriod)) # create anchor consolidator self.anchorConsolidator = QuoteBarConsolidator(timedelta(minutes=self.anchorPeriod)) # attach our event handlers self.scalpConsolidator.DataConsolidated += self.ScalpBarsHandler self.anchorConsolidator.DataConsolidated += self.AnchorBarsHandler # add consolidators to the manager to receive updates from the engine self.qcAlgo.SubscriptionManager.AddConsolidator(self.symbol, self.scalpConsolidator) self.qcAlgo.SubscriptionManager.AddConsolidator(self.symbol, self.anchorConsolidator) # --------------------- def ScalpBarsHandler(self, sender, quoteBar): # --------------------- #self.toolbox.show_debug(str(quoteBar), "Adding Scalp-Bar: ") # update RW Bars self.scalpQuoteBar_RollingWindow.Add(quoteBar) # update scalp ROC self.scalp_ROC.Update(quoteBar.EndTime, quoteBar.Close) # update RW Indicators for ind_key in self.scalpIndicators.keys(): indicator = self.scalpIndicators[ind_key] indicator_rw = self.scalpIndicators_RollingWindows[ind_key] indicator.Update(quoteBar.EndTime, quoteBar.Close) indicator_rw.Add(indicator.Current) # plot scalp chart if not self.qcAlgo.IsWarmingUp: if self.IsChartTime(quoteBar.Time): if self.qcAlgo.ChartStartHour == 0 or (quoteBar.Time.hour >= self.qcAlgo.ChartStartHour and quoteBar.Time.hour <= self.qcAlgo.ChartEndHour): self.strategy.plot_scalp_chart(self, quoteBar) # Call Scalp-Run (call Srategy Scalp-Run via Brick-Scalp Event-Handler) # self.strategy.RunScalp(self) # --------------------- def AnchorBarsHandler(self, sender, quoteBar): # --------------------- #self.toolbox.show_debug(str(quoteBar), "Adding Anchor-Bar: ") # update RW Bars self.anchorQuoteBar_RollingWindow.Add(quoteBar) # update anchor ROC self.anchor_ROC.Update(quoteBar.EndTime, quoteBar.Close) # update RW Indicators for ind_key in self.anchorIndicators.keys(): indicator = self.anchorIndicators[ind_key] indicator_rw = self.anchorIndicators_RollingWindows[ind_key] indicator.Update(quoteBar.EndTime, quoteBar.Close) indicator_rw.Add(indicator.Current) # plot anchor chart if not self.qcAlgo.IsWarmingUp: if self.IsChartTime(quoteBar.Time): self.strategy.plot_anchor_chart(self, quoteBar) # Call Anchor-Run (call Srategy Anchor-Run via Brick-Achor Event-Handler) # self.strategy.RunAnchor(self) # [ QUOTE BARS REGION (END) ] # [ TRADE RULES/EVENTS REGION (BASE / BEGIN) ] # base # --------------------- def Check_Trade_Rules(self, data): # --------------------- self.check_trade_allowed = self.AllowCheckTrade() # Go! # TODO: Check Trade Rules (Trigger/Entry/StopLoss/Exit) here # and call self.strategy.OnTrigger/OnEntry/OnStopLoss/OnExit if needed # get profit benchmarks self.get_profit_benchmarks() # --------------------- def get_profit_benchmarks(self): # --------------------- self.Symbol_LastTradeProfit = self.qcAlgo.Portfolio[self.symbol].LastTradeProfit self.Symbol_UnrealizedProfit = self.qcAlgo.Portfolio[self.symbol].UnrealizedProfit self.Symbol_UnrealizedProfitPercent = self.qcAlgo.Portfolio[self.symbol].UnrealizedProfitPercent self.Portfolio_Cash = self.qcAlgo.Portfolio.Cash self.Portfolio_TotalProfit = self.qcAlgo.Portfolio.TotalProfit self.Portfolio_TotalUnrealizedProfit = self.qcAlgo.Portfolio.TotalUnrealizedProfit # --------------------- def Check_Trade_Direction(self, ind_fast, ind_slow, o,h,l,c, tolerance = 0, touch_margins = "open_close"): # --------------------- self.trade_direction_flattening() self.Set_Anchor_Indicators_Margins(ind_fast, ind_slow, tolerance) return InsightDirection.Flat # --------------------- def trade_direction_flattening(self): # --------------------- self.direction_trade = InsightDirection.Flat # --------------------- def trend_direction_flattening(self): # --------------------- self.direction_trend = InsightDirection.Flat # --------------------- def trade_direction_str(self): # --------------------- if self.direction_trade == InsightDirection.Up: return "LONG" else: if self.direction_trade == InsightDirection.Down: return "SHORT" else: return "WAIT" # --------------------- def set_trend_direction(self): # --------------------- if self.trade_magnitude > 0: self.direction_trend = InsightDirection.Up else: if self.trade_magnitude < 0: self.direction_trend = InsightDirection.Down else: self.trend_direction_flattening() return self.direction_trend # --------------------- def trend_direction_str(self): # --------------------- if self.direction_trend == InsightDirection.Up: return "UP" else: if self.direction_trend == InsightDirection.Down: return "DOWN" else: return "FLAT" # --------------------- def Set_Anchor_Indicators_Margins(self, ind_fast, ind_slow, tolerance = 0): # --------------------- self.anchor_fast_indicator_margin = ind_fast self.anchor_slow_indicator_margin = ind_slow if ind_fast < ind_slow: self.anchor_fast_indicator_margin = self.minus_pip(ind_fast, tolerance) self.anchor_slow_indicator_margin = self.plus_pip(ind_slow, tolerance) if ind_fast > ind_slow: self.anchor_fast_indicator_margin = self.plus_pip(ind_fast, tolerance) self.anchor_slow_indicator_margin = self.minus_pip(ind_slow, tolerance) # --------------------- def Set_Scalp_Indicators_Margins(self, ind_fast, ind_mid, ind_slow, tolerance = 0): # --------------------- self.scalp_fast_indicator_margin = ind_fast self.scalp_mid_indicator_margin = ind_mid self.scalp_slow_indicator_margin = ind_slow if ind_fast < ind_slow: self.scalp_fast_indicator_margin = self.minus_pip(ind_fast, tolerance) self.scalp_slow_indicator_margin = self.plus_pip(ind_slow, tolerance) if ind_fast > ind_slow: self.scalp_fast_indicator_margin = self.plus_pip(ind_fast, tolerance) self.scalp_slow_indicator_margin = self.minus_pip(ind_slow, tolerance) # [ TRADE RULES/EVENTS REGION (BASE / BEGIN) ] # [ TRADE DECISION FACTORS REGION (BEGIN) ] # --------------------- def IsNarrowScalpEMA(self, fast, slow): # --------------------- self.UpdateScalpEMA(fast, slow) self.is_narrow_ema_scalp = self.scalp_emas_pips_delta < self.qcAlgo.scalp_delta_min_pips return self.is_narrow_ema_scalp # --------------------- def IsNarrowAnchorEMA(self, fast, slow): # --------------------- self.UpdateAnchorEMA(fast, slow) self.is_narrow_ema_anchor = self.anchor_emas_pips_delta < self.qcAlgo.anchor_delta_min_pips return self.is_narrow_ema_anchor # --------------------- def AllowCheckTrade(self): # --------------------- return not self.is_narrow_ema_anchor # [ TRADE DECISION FACTORS REGION (END) ] # [ TRADE FACTORS REGION (BEGIN) ] # --------------------- def Switch_Model(self, mode): # --------------------- self.trade_model = mode # --------------------- def UpdateScalpEMA(self, fast, slow): # --------------------- self.scalp_ema_fast = fast self.scalp_ema_slow = slow self.scalp_emas_pips_delta = self.pip_diff_abs(fast, slow) # --------------------- def UpdateAnchorEMA(self, fast, slow): # --------------------- self.anchor_ema_fast = fast self.anchor_ema_slow = slow self.anchor_emas_pips_delta = self.pip_diff_abs(fast, slow) # --------------------- def UpdateAnchorFluentData(self, bigData): # --------------------- data = bigData[self.symbol] self.data = data self.anchor_fluent_time = data.Time if self.anchor_new_fluent_data or data.High > self.anchor_fluent_high: self.anchor_fluent_high = data.High if self.anchor_new_fluent_data or data.Low < self.anchor_fluent_low: self.anchor_fluent_low = data.Low self.anchor_fluent_close= data.Close if self.anchor_new_fluent_data: self.anchor_fluent_open = data.Open self.anchor_new_fluent_data = False # --------------------- def UpdateScalpFluentData(self, bigData): # --------------------- data = bigData[self.symbol] self.scalp_fluent_time = data.Time if self.scalp_new_fluent_data or data.High > self.scalp_fluent_high: self.scalp_fluent_high = data.High if self.scalp_new_fluent_data or data.Low < self.scalp_fluent_low: self.scalp_fluent_low = data.Low self.scalp_fluent_close= data.Close if self.scalp_new_fluent_data: self.scalp_fluent_open = data.Open self.scalp_new_fluent_data = False # --------------------- def AnchorIsWarmedUp(self): # --------------------- if not self.anchor_warmed_up: self.anchor_warmed_up = True # --------------------- def ResetAnchorFluentData(self): # --------------------- self.anchor_new_fluent_data = True # --------------------- def ResetScalpFluentData(self): # --------------------- self.scalp_new_fluent_data = True # --------------------- def cancel_limits(self): # --------------------- self.reset_limits() self.cancel_take_profit(True) self.cancel_stop_loss(True) self.reset_limits() # --------------------- def match_order(self, ticket, order_id): # --------------------- if ticket is not None: return ticket.OrderId == order_id else: return False # --------------------- def allow_cancel_orders(self): # --------------------- self.Veto_CancelOrders = False # --------------------- def veto_cancel_orders(self): # --------------------- self.Veto_CancelOrders = True # --------------------- def cancel_event_ignore(self): # --------------------- self.Ignore_Cancel_Event = True # --------------------- def cancel_event_attention(self): # --------------------- self.Ignore_Cancel_Event = False # --------------------- def reset_limits(self): # --------------------- self.allow_cancel_orders() self.ProfitTargetCanceled = False self.ProfitTarget_LastUpdate = None self.StopLossCanceled = False self.StopLoss_LastUpdate = None # --------------------- def cancel_enabled_state(self): # --------------------- return \ self.trade_state != self.ENTRY_SHORT and self.trade_state != self.ENTRY_LONG #and self.trade_state != self.EXIT_1_SHORT_BASE and self.trade_state != self.EXIT_1_LONG_BASE # --------------------- def cancel_take_profit(self, overrule_veto = False, show_action = True, state_reset = False): # --------------------- # init result = False # cancel take profit order if self.cancel_enabled_state(): if overrule_veto or (not self.Veto_CancelOrders and not self.ProfitTargetCanceled): if self.ProfitTarget is not None: self.ProfitTarget.Cancel() result = True self.ProfitTargetCanceled = True if show_action: self.trade_action_cancel_tp() # state machine reset if state_reset: self.reset_state() # finally return result # --------------------- def cancel_stop_loss(self, overrule_veto = False, show_action = True, state_reset = False): # --------------------- # init result = False # cancel stop loss order if self.cancel_enabled_state(): if overrule_veto or (not self.Veto_CancelOrders and not self.StopLossCanceled): if self.StopLoss is not None: self.StopLoss.Cancel() result = True self.StopLossCanceled = True if show_action: self.trade_action_cancel_sl() # state machine reset if state_reset: self.reset_state() # finally return result # --------------------- def update_take_profit(self, price, quantity = 0, allow_lower_profit = False): # --------------------- # init updated = False allow_update = True # Go! # Update Take Profit order if not self.ProfitTargetCanceled and self.ProfitTarget is not None: if self.ProfitTarget_LastUpdate is None: self.ProfitTarget_LastUpdate = UpdateOrderFields() if quantity != 0 and self.ProfitTarget_LastUpdate.Quantity != quantity: self.ProfitTarget_LastUpdate.Quantity = quantity updated = True if self.ProfitTarget_LastUpdate.LimitPrice != price: last_limit_price = self.ProfitTarget_LastUpdate.LimitPrice if last_limit_price is not None: if self.is_long_trade: allow_update = price > last_limit_price or allow_lower_profit if self.is_short_trade: allow_update = price < last_limit_price or allow_lower_profit else: allow_update = True if allow_update: self.ProfitTarget_LastUpdate.LimitPrice = self.pip_round(price) updated = True else: updated = False if updated: self.ProfitTarget.Update(self.ProfitTarget_LastUpdate) # --------------------- def update_stop_loss(self, price, quantity = 0, allow_bigger_loss = False): # --------------------- # init updated = False allow_update = True # Go! # Update Take Profit order if not self.StopLossCanceled and self.StopLoss is not None: if self.StopLoss_LastUpdate is None: self.StopLoss_LastUpdate = UpdateOrderFields() if quantity != 0 and self.StopLoss_LastUpdate.Quantity != quantity: self.StopLoss_LastUpdate.Quantity = quantity updated = True if self.StopLoss_LastUpdate.LimitPrice != price: last_limit_price = self.StopLoss_LastUpdate.LimitPrice if last_limit_price is not None: if self.is_long_trade: allow_update = price > last_limit_price or allow_bigger_loss if self.is_short_trade: allow_update = price < last_limit_price or allow_bigger_loss else: allow_update = True if allow_update: self.StopLoss_LastUpdate.LimitPrice = self.pip_round(price) updated = True else: updated = False if updated: self.StopLoss.Update(self.StopLoss_LastUpdate) # --------------------- def reset_state(self): # --------------------- # reset levels self.drop_all_levels() # reset machine-state self.trade_state = self.STAND_BY # --------------------- def drop_all_levels(self): # --------------------- self.trade_risk = 0 self.touch_level = 0 self.entry_level = 0 self.exit1_level = 0 self.exit2_level = 0 self.stop_loss_level = 0 self.stop_loss_purple_level = 0 self.trade_magnitude_scalp = 0 self.trade_magnitude_anchor = 0 self.trade_diff = 0 self.trade_enter = 0 self.trade_break_even = 0 self.trade_stop_loss = 0 self.trade_take_profit = 0 self.trade_exit = 0 self.trade_start_level = 0 self.trade_take_profit_level = 0 self.trade_given_stop_loss = 0 self.trade_orange_risk_level = 0 self.trade_lowest_low = 0 self.trade_abs_start_level = 0 # self.trade_abs_stop_level = 0 # [ TRADE FACTORS REGION (END) ] # [ INDICATORS REGION (BEGIN) ] # --------------------- def create_indicators(self): # --------------------- self.create_scalp_indicators() self.create_anchor_indicators() # --------------------- def new_scalp_indicators(self): # --------------------- pass # --------------------- def new_anchor_indicators(self): # --------------------- pass # --------------------- def create_scalp_indicators(self): # --------------------- indicators = self.new_scalp_indicators() for ticker in indicators.keys(): self.register_scalp_indicator(ticker, indicators[ticker]) # --------------------- def create_anchor_indicators(self): # --------------------- indicators = self.new_anchor_indicators() for ticker in indicators.keys(): self.register_anchor_indicator(ticker, indicators[ticker]) # --------------------- def register_scalp_indicator(self, ind_key, indicator): # --------------------- self.register_indicator(self.scalpIndicators, indicator, ind_key, self.scalpIndicators_RollingWindows, self.scalp_max_slots + 1) # --------------------- def register_anchor_indicator(self, ind_key, indicator): # --------------------- self.register_indicator(self.anchorIndicators, indicator, ind_key, self.anchorIndicators_RollingWindows, self.anchor_max_slots + 1) # --------------------- def register_indicator(self, indicators, indicator, ind_key, indicators_windows, ind_wind_len): # --------------------- indicators[ind_key] = indicator indicators_windows[ind_key] = RollingWindow[IndicatorDataPoint](ind_wind_len) # --------------------- def scalp_indicators_ready(self): # --------------------- result = True for indicator in self.scalpIndicators.values(): result &= indicator.IsReady if not result: return result # finally return result # --------------------- def anchor_indicators_ready(self): # --------------------- result = True for indicator in self.anchorIndicators.values(): result &= indicator.IsReady if not result: return result for indicator in self.quarterIndicators.values(): result &= indicator.IsReady if not result: return result # finally return result # --------------------- def all_indicators_ready(self): # --------------------- return self.scalp_indicators_ready() and self.anchor_indicators_ready() # --------------------- def plot_scalp_indicator(self, ind_key): # --------------------- pass # indicator = self.scalpIndicators[ind_key] # self.qcAlgo.PlotIndicator("scalp_" + ind_key + "_" + self.symbol, True, indicator) # --------------------- def plot_anchor_indicator(self, ind_key): # --------------------- pass #indicator = self.anchorIndicators[ind_key] #self.qcAlgo.PlotIndicator("anchor_" + ind_key + "_" + self.symbol, True, indicator) # [ INDICATORS REGION (END) ] # [ INSIGHT CALC REGION (BEGIN) ] # --------------------- def Get_Confidence(self): # --------------------- # main operation - calc confidence self.trade_confidence = self.Calc_Insight_Confidence(self.IsLevel_TradeEnabled_Semafors) # co-operations - calc Diff # self.Get_Diff() # co-operations - calc ROCs (anchor/scalp), Magnitude self.Get_Magnitude() return self.trade_confidence # --------------------- def Get_Magnitude(self): # --------------------- self.trade_magnitude_scalp = float(self.scalp_ROC.Current.Value) self.trade_magnitude_anchor = float(self.scalp_ROC.Current.Value) # finally return weighted magnitude (50% for anchor and 50% for scalp) self.trade_magnitude = self.trade_magnitude_scalp * .5 + self.trade_magnitude_anchor * .5 # apply magnitude amplifier self.trade_magnitude = self.trade_magnitude * self.qcAlgo.trade_magnitude_amplifier self.set_trend_direction() return self.trade_magnitude # --------------------- def Get_Diff(self): # --------------------- self.trade_diff = self.Calc_Insight_Diff() return self.trade_diff # --------------------- def Calc_Insight_Confidence(self, trade_enabled_semafors): # --------------------- # init confidence_offset = 0 wconf_indicator_delta_anchor = 0 wconf_indicator_delta_scalp = 0 wconf_trade_enabled_live = 0 wconf_trade_enabled_hist = 0 # get indicator rolling windows rw_ai_fast = self.anchorIndicators_RollingWindows["ema_8_anchor"] rw_ai_slow = self.anchorIndicators_RollingWindows["ema_21_anchor"] rw_si_fast = self.scalpIndicators_RollingWindows["ema_8_scalp"] rw_si_slow = self.scalpIndicators_RollingWindows["ema_21_scalp"] live_ai_fast = rw_ai_fast[0].Value live_ai_slow = rw_ai_slow[0].Value live_si_fast = rw_si_fast[0].Value live_si_slow = rw_si_slow[0].Value # get confidence properties weight_confidence_trade_enabled_live = self.qcAlgo.confidence_trade_enabled_main weight_confidence_trade_enabled_hist = self.qcAlgo.confidence_trade_enabled_hist weight_confidence_indicator_delta_anchor = self.qcAlgo.confidence_indicator_delta_anchor weight_confidence_indicator_delta_scalp = self.qcAlgo.confidence_indicator_delta_scalp # calc indicators delta (anchor) ai_delta_narrow = self.Get_Rolling_Indicators_Delta_Narrow(rw_ai_fast, rw_ai_slow) ai_delta_wide = self.Get_Rolling_Indicators_Delta_Wide(rw_ai_fast, rw_ai_slow) delta_max_ai = abs(ai_delta_wide - ai_delta_narrow) # calc indicators delta (scalp) si_delta_narrow = self.Get_Rolling_Indicators_Delta_Narrow(rw_si_fast, rw_si_slow) si_delta_wide = self.Get_Rolling_Indicators_Delta_Wide(rw_si_fast, rw_si_slow) delta_max_si = abs(si_delta_wide - si_delta_narrow) # Go calc! # get anchor indicator confidence diff_live_ai = abs(live_ai_slow - live_ai_fast) delta_live_ai = abs(diff_live_ai - ai_delta_narrow) if (delta_max_ai > 0): rate_indicator_delta_anchor = delta_live_ai / delta_max_ai else: rate_indicator_delta_anchor = 0 wconf_indicator_delta_anchor = weight_confidence_indicator_delta_anchor * rate_indicator_delta_anchor # get scalp indicator confidence diff_live_si = abs(live_si_slow - live_si_fast) delta_live_si = abs(diff_live_si - si_delta_narrow) if delta_max_si > 0: rate_indicator_delta_scalp = delta_live_si / delta_max_si else: rate_indicator_delta_scalp = 0 wconf_indicator_delta_scalp = weight_confidence_indicator_delta_scalp * rate_indicator_delta_scalp if trade_enabled_semafors is not None: # get live trade-enabled confidence live_idx = 0 rate_trade_enabled_live = 0 if trade_enabled_semafors[live_idx]: rate_trade_enabled_live = 1 wconf_trade_enabled_live = weight_confidence_trade_enabled_live * rate_trade_enabled_live # get history trade-enabled history confidence trade_enabled_hist_len = len(trade_enabled_semafors) trade_enabled_hist_count = 0 for idx in range(1, trade_enabled_hist_len): if trade_enabled_semafors[idx]: trade_enabled_hist_count = trade_enabled_hist_count + 1 if trade_enabled_hist_len > 1: rate_trade_enabled_hist = trade_enabled_hist_count / (trade_enabled_hist_len - 1) else: rate_trade_enabled_hist = 0 wconf_trade_enabled_hist = weight_confidence_trade_enabled_hist * rate_trade_enabled_hist else: confidence_offset = 0.5 # finally return confidence sum total_confidence = confidence_offset + \ wconf_indicator_delta_anchor + \ wconf_indicator_delta_scalp + \ wconf_trade_enabled_live + \ wconf_trade_enabled_hist # return sum of all confidences self.trade_confidence = total_confidence return total_confidence # --------------------- def Get_Rolling_Indicators_Delta_Narrow(self, rw_i_fast, rw_i_slow): # --------------------- # init i_delta_narrow = 0 # go! for idx in range(rw_i_fast.Size): i_fast = self.value(rw_i_fast[idx]) i_slow = self.value(rw_i_slow[idx]) curr_delta = abs(i_slow - i_fast) if i_delta_narrow == 0 or curr_delta < i_delta_narrow: i_delta_narrow = curr_delta # finally return i_delta_narrow # --------------------- def Get_Rolling_Indicators_Delta_Wide(self, rw_i_fast, rw_i_slow): # --------------------- # init i_delta_wide = 0 # go! for idx in range(rw_i_fast.Size): i_fast = self.value(rw_i_fast[idx]) i_slow = self.value(rw_i_slow[idx]) curr_delta = abs(i_slow - i_fast) if i_delta_wide == 0 or curr_delta > i_delta_wide: i_delta_wide = curr_delta # finally return i_delta_wide # --------------------- def Calc_Insight_Diff(self): # --------------------- # init # get indicator rolling windows rw_ai_fast = self.anchorIndicators_RollingWindows["ema_8_anchor"] rw_ai_slow = self.anchorIndicators_RollingWindows["ema_21_anchor"] rw_si_fast = self.scalpIndicators_RollingWindows["ema_8_scalp"] rw_si_slow = self.scalpIndicators_RollingWindows["ema_21_scalp"] # Go! # calc mean derivative (anchor) ai_mid_diff = self.Get_Hist_Diff(rw_ai_fast, rw_ai_slow) # calc mean derivative (scalp) si_mid_diff = self.Get_Hist_Diff(rw_si_fast, rw_si_slow) # finally return weighted derivative (70% for anchor and 30% for scalp) weighted_mid_diff = ai_mid_diff * .7 + si_mid_diff * .3 # return result return weighted_mid_diff # --------------------- def Get_Hist_Diff(self, rw_i_fast, rw_i_slow): # --------------------- # init dx = 1 rw_i_fast_values = self.ind_values(rw_i_fast) rw_i_slow_values = self.ind_values(rw_i_slow) # calc derivatives of fast/slow indicators dy_rw_i_fast = diff(rw_i_fast_values)/dx dy_rw_i_slow = diff(rw_i_fast_values)/dx # calc mean derivative dy_rw_i_fast_mean = np.mean(dy_rw_i_fast) dy_rw_i_slow_mean = np.mean(dy_rw_i_slow) dy_rw_i_mean = (dy_rw_i_fast_mean + dy_rw_i_slow_mean) / 2 if dy_rw_i_mean > 1: pass # finally return dy_rw_i_mean # --------------------- def ind_values(self, indicators): # --------------------- result = [] for idx in range(indicators.Size): result.append(self.value(indicators[idx])) return result # [ INSIGHT CALC REGION (END) ] # [ PLOT REGION (BEGIN) ] # --------------------- def create_scalp_chart(self): # --------------------- self.update_price_chart(self.scalp_chart) self.update_scalp_indicator_chart() self.qcAlgo.AddChart(self.scalp_chart) # --------------------- def create_anchor_chart(self): # --------------------- self.update_price_chart(self.anchor_chart) self.update_anchor_indicator_chart() self.qcAlgo.AddChart(self.anchor_chart) # --------------------- def update_scalp_indicator_chart(self): # --------------------- # scalp series shorts (lines) self.scalp_chart.AddSeries(Series(self.price_chart_serial_short_entry, SeriesType.Line, 0)) self.scalp_chart.AddSeries(Series(self.price_chart_serial_short_stop_loss, SeriesType.Line, 0)) self.scalp_chart.AddSeries(Series(self.price_chart_serial_short_exit_1, SeriesType.Line, 0)) self.scalp_chart.AddSeries(Series(self.price_chart_serial_short_exit_2, SeriesType.Line, 0)) # scalp series shorts (points) self.scalp_chart.AddSeries(Series(self.price_chart_serial_short_trigger_point, SeriesType.Scatter, 0)) self.scalp_chart.AddSeries(Series(self.price_chart_serial_short_entry_point, SeriesType.Scatter, 0)) self.scalp_chart.AddSeries(Series(self.price_chart_serial_short_stop_loss_point, SeriesType.Scatter, 0)) self.scalp_chart.AddSeries(Series(self.price_chart_serial_short_exit_1_point, SeriesType.Scatter, 0)) self.scalp_chart.AddSeries(Series(self.price_chart_serial_short_exit_2_point, SeriesType.Scatter, 0)) # scalp series longs (lines) self.scalp_chart.AddSeries(Series(self.price_chart_serial_long_entry, SeriesType.Line, 0)) self.scalp_chart.AddSeries(Series(self.price_chart_serial_long_stop_loss, SeriesType.Line, 0)) self.scalp_chart.AddSeries(Series(self.price_chart_serial_long_exit_1, SeriesType.Line, 0)) self.scalp_chart.AddSeries(Series(self.price_chart_serial_long_exit_2, SeriesType.Line, 0)) # scalp series longs (points) self.scalp_chart.AddSeries(Series(self.price_chart_serial_long_trigger_point, SeriesType.Scatter, 0)) self.scalp_chart.AddSeries(Series(self.price_chart_serial_long_entry_point, SeriesType.Scatter, 0)) self.scalp_chart.AddSeries(Series(self.price_chart_serial_long_stop_loss_point, SeriesType.Scatter, 0)) self.scalp_chart.AddSeries(Series(self.price_chart_serial_long_exit_1_point, SeriesType.Scatter, 0)) self.scalp_chart.AddSeries(Series(self.price_chart_serial_long_exit_2_point, SeriesType.Scatter, 0)) # --------------------- def update_anchor_indicator_chart(self): # --------------------- pass # --------------------- def update_price_chart(self, chart): # --------------------- # On the Trade Plotter Chart we want 2 series: open and close: chart.AddSeries(Series(self.price_chart_serial_open, SeriesType.Line, 0)) chart.AddSeries(Series(self.price_chart_serial_close, SeriesType.Line, 0)) chart.AddSeries(Series(self.price_chart_serial_close_consolidated, SeriesType.Candle, 0)) chart.AddSeries(Series(self.price_chart_serial_open_price_point, SeriesType.Scatter, 0)) chart.AddSeries(Series(self.price_chart_serial_high_price_point, SeriesType.Scatter, 0)) chart.AddSeries(Series(self.price_chart_serial_low_price_point, SeriesType.Scatter, 0)) chart.AddSeries(Series(self.price_chart_serial_close_price_point, SeriesType.Scatter, 0)) chart.AddSeries(Series(self.price_chart_serial_ema_cross_point, SeriesType.Scatter, 0)) return chart # --------------------- def update_indicator_chart(self, chart, chart_type, ind_type, ind_periods): # --------------------- for period in ind_periods: if chart_type == "anchor": ticker = self.anchor_ticker(ind_type, period) else: ticker = self.scalp_ticker(ind_type, period) chart.AddSeries(Series(ticker, SeriesType.Line, 0)) return chart # [ PLOT REGION (END) ] # [ HELPERS REGION (BEGIN) ] # --------------------- def GetRoundedOrderSize(self, orderQuantity): # --------------------- # init # reset lot size self.lotSize = self.qcAlgo.Securities[self.ticker].SymbolProperties.LotSize if self.lotSize == 0: self.Debug("Lot Size of " + self.symbol + " is 0 !!! Assuming LotSize=1 instead.") self.lotSize = 1 # reset order size self.orderSize = orderQuantity # calc rounded order size self.lotsCount = round(self.orderSize / self.lotSize) self.roundedOrderSize = self.lotsCount * self.lotSize # get result return self.roundedOrderSize # --------------------- def IsChartHour(self, time): # --------------------- if not self.qcAlgo.IsWarmingUp: if self.IsChartTime(time): if self.qcAlgo.ChartStartHour == 0 or (time.hour >= self.qcAlgo.ChartStartHour and time.hour <= self.qcAlgo.ChartEndHour): return True return False # --------------------- def IsChartTime(self, time): # --------------------- cond_general = self.IsChartEnabled() cond_date_start = time.replace(tzinfo=None) >= self.qcAlgo.ChartStartDate.replace(tzinfo=None) cond_date_end = time.replace(tzinfo=None) <= self.qcAlgo.ChartEndDate.replace(tzinfo=None) cond_hour = time.hour >= self.qcAlgo.ChartStartHour and time.hour <= self.qcAlgo.ChartEndHour return cond_general & cond_date_start & cond_date_end & cond_hour # --------------------- def IsChartEnabled(self): # --------------------- return not self.qcAlgo.chart_disable # --------------------- def scalp_ticker(self, prefix, period): # --------------------- return prefix + "_" + str(period) + "_scalp" # --------------------- def anchor_ticker(self, prefix, period): # --------------------- return prefix + "_" + str(period) + "_anchor" # --------------------- def current_value(self, container): # --------------------- return container.Current.Value # --------------------- def value(self, container): # --------------------- return container.Value # --------------------- def anchor_ema_current_value(self, period): # --------------------- return self.current_value(self.anchorIndicators[self.anchor_ticker("ema", period)]) # --------------------- def scalp_ema_current_value(self, period): # --------------------- return self.current_value(self.scalpIndicators[self.scalp_ticker("ema", period)]) # --------------------- def scalp_elapsed(self, count_key): # --------------------- # exit if not end of scalp time frame count = self.scalp_update_count[count_key] if count < self.scalpPeriod - 1: self.scalp_update_count[count_key] = count + 1 return False else: self.scalp_update_count[count_key] = 0 return True # --------------------- def anchor_elapsed(self, count_key): # --------------------- # exit if not end of anchor time frame count = self.anchor_update_count[count_key] if count < self.anchorPeriod - 1: self.anchor_update_count[count_key] = count + 1 return False else: self.anchor_update_count[count_key] = 0 return True # ------------------------------------------------------------------------- def pip_round(self, price): # ------------------------------------------------------------------------- return self.toolbox.pip_round(price) # --------------------- def plus_pip(self, price, pip): # --------------------- return self.add_pip(price, pip) # --------------------- def minus_pip(self, price, pip): # --------------------- return self.add_pip(price, -1 * pip) # --------------------- def add_pip(self, price, pip): # --------------------- return self.toolbox.add_pip(price, pip) # --------------------- def pip_diff(self, a, b): # --------------------- return self.toolbox.pip_diff(a, b) # --------------------- def pip_diff_abs(self, a, b): # --------------------- return abs(self.pip_diff(a, b)) # --------------------- def get_limits_as_str(self): # --------------------- return \ "CURR:" + str(self.pip_round(self.scalp_fluent_close)) + \ " STRT:" + str(self.pip_round(self.trade_start_level)) + \ " ORANGE-STOP:" + str(self.pip_round(self.trade_orange_risk_level)) + \ " STOP:" + str(self.pip_round(self.trade_given_stop_loss)) + \ " TAKE:" + str(self.pip_round(self.trade_take_profit_level)) # --------------------- def trade_action_insight_benchmark(self, mode): # --------------------- mode_text = mode# + ". " + self.get_limits_as_str() self.trade_action(mode_text, True, True) # --------------------- def trade_action_insight_nobenchmark(self, mode): # --------------------- mode_text = mode# + ". " + self.get_limits_as_str() self.trade_action(mode_text, True, False) # --------------------- def trade_action_noinsight_benchmark(self, mode): # --------------------- mode_text = mode# + ". " + self.get_limits_as_str() self.trade_action(mode_text, False, True) # --------------------- def trade_action_noinsight_nobenchmark(self, mode): # --------------------- mode_text = mode# + ". " + self.get_limits_as_str() self.trade_action(mode_text, False, False) # --------------------- def trade_action_cancel_sl(self): # --------------------- msg = "CANCEL_STOPLOSS" self.trade_action_noinsight_nobenchmark(msg) # --------------------- def trade_action_cancel_tp(self): # --------------------- msg = "CANCEL_TAKEPROFIT" self.trade_action_noinsight_nobenchmark(msg) # --------------------- def trade_action_filled_tp_cancel_sl(self): # --------------------- msg = "FILLED_TAKEPROFIT_CANCEL_STOPLOSS" self.trade_action_noinsight_nobenchmark(msg) # --------------------- def trade_action_filled_sl_cancel_tp(self): # --------------------- msg = "FILLED_STOPLOSS_CANCEL_TAKEPROFIT" self.trade_action_noinsight_nobenchmark(msg) # --------------------- def trade_action_cancel_stoploss(self, mode): # --------------------- msg = str(self.symbol) + ": > filled TP, cancel SL" self.trade_action_noinsight_nobenchmark(msg) # --------------------- def trade_action(self, mode, emit_insight = False, log_profit_benchmarks=True): # --------------------- self.Switch_Model(mode) self.log_trade(log_profit_benchmarks) if emit_insight: self.Emit_Insight() # --------------------- def log_trade(self, log_profit_benchmarks): # --------------------- # init trade_direction = self.trade_direction_str() trend_direction = self.trend_direction_str() # go! if log_profit_benchmarks: self.toolbox.show_csv_log(self.csv_sep_chr + str(self.symbol) + self.csv_sep_chr \ + str(self.weight) + self.csv_sep_chr \ + str(self.data.Time) + self.csv_sep_chr \ + trade_direction + self.csv_sep_chr \ + trend_direction + self.csv_sep_chr \ + str(self.trade_model) + self.csv_sep_chr \ + str(self.trade_confidence) + self.csv_sep_chr \ + str(self.trade_magnitude) + self.csv_sep_chr \ + str(self.pip_round(self.scalp_fluent_close)) + self.csv_sep_chr \ + str(self.pip_round(self.entry_level)) + self.csv_sep_chr \ + str(self.pip_round(self.stop_loss_level)) + self.csv_sep_chr \ + str(self.pip_round(self.stop_loss_purple_level)) + self.csv_sep_chr \ + str(self.pip_round(self.trade_risk)) + self.csv_sep_chr \ + str(self.pip_round(self.trade_break_even)) + self.csv_sep_chr \ + str(self.pip_round(self.trade_exit)) + self.csv_sep_chr \ + str(self.pip_round(self.trade_take_profit)) + self.csv_sep_chr \ + str(self.pip_round(self.trade_start_level)) + self.csv_sep_chr \ + str(self.pip_round(self.trade_orange_risk_level)) + self.csv_sep_chr \ + str(self.pip_round(self.trade_given_stop_loss)) + self.csv_sep_chr \ + str(self.pip_round(self.trade_take_profit_level)) + self.csv_sep_chr \ + str(self.Symbol_LastTradeProfit) + self.csv_sep_chr \ + str(self.Symbol_UnrealizedProfit) + self.csv_sep_chr \ + str(self.Symbol_UnrealizedProfitPercent) + self.csv_sep_chr \ + str(self.Portfolio_Cash) + self.csv_sep_chr \ + str(self.Portfolio_TotalProfit) + self.csv_sep_chr \ + str(self.Portfolio_TotalUnrealizedProfit) ) else: self.toolbox.show_csv_log(self.csv_sep_chr + str(self.symbol) + self.csv_sep_chr \ + str(self.weight) + self.csv_sep_chr \ + str(self.data.Time) + self.csv_sep_chr \ + trade_direction + self.csv_sep_chr \ + trend_direction + self.csv_sep_chr \ + str(self.trade_model) + self.csv_sep_chr \ + str(self.trade_confidence) + self.csv_sep_chr \ + str(self.trade_magnitude) + self.csv_sep_chr \ + str(self.pip_round(self.scalp_fluent_close)) + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" + self.csv_sep_chr \ + "" ) # [ HELPERS REGION (END) ]