Hello guys!, I´m analyzing the results provided by the backtest environment and I am wondering how can I close a position using a strategy signal rather than closing the order in the inmediatly next day as it is doing right now the algorithm.

The strategy to open positions is just a simple moving average condition, which one consist on open the trade if the price > sma20, price < sma50 and price < sma200, with a candle pattern signal of hammer or a bullish engulfing pattern.

I´m trying to close the trade with a strategy signal that is sma50 < sma20.

When I put all of this together and run the full backtest, when I load the transaction I see that every position I take is closed inmediatly on the next day and not taking the strategy signal of close that I want.

Any idea to fix this?

Thanks a lot.

Returns | 1 Month | 3 Month | 6 Month | 12 Month |

Alpha | 1 Month | 3 Month | 6 Month | 12 Month |

Beta | 1 Month | 3 Month | 6 Month | 12 Month |

Sharpe | 1 Month | 3 Month | 6 Month | 12 Month |

Sortino | 1 Month | 3 Month | 6 Month | 12 Month |

Volatility | 1 Month | 3 Month | 6 Month | 12 Month |

Max Drawdown | 1 Month | 3 Month | 6 Month | 12 Month |

from quantopian.algorithm import order_optimal_portfolio from quantopian.algorithm import attach_pipeline, pipeline_output from quantopian.pipeline import Pipeline from quantopian.pipeline import CustomFactor from quantopian.pipeline.data.builtin import USEquityPricing from quantopian.pipeline.filters import QTradableStocksUS import quantopian.optimize as opt from quantopian.pipeline.data import Fundamentals from quantopian.pipeline import Pipeline from quantopian.pipeline.factors import SimpleMovingAverage,RSI, MACDSignal, SimpleBeta, RollingPearsonOfReturns from quantopian.pipeline.filters import Q1500US, QTradableStocksUS, Q500US, Q3000US from quantopian.pipeline.data import USEquityPricing from quantopian.pipeline.factors import CustomFactor from quantopian.pipeline import CustomFilter import pandas as pd import numpy as np class engulf(CustomFilter): # this is a class to construct a engulfing candle pattern signal. inputs = [USEquityPricing.close, USEquityPricing.low, USEquityPricing.open, USEquityPricing.high] window_length = 2 def compute(self, today, assets, out, close, low, open1, high): condition_1 = (high[-1] > high[-2]) & (low[-1]<low[-2]) condition_2 = (close[-1] > close[-2]) & (open1[-1]<open1[-2]) condition_3 = close[-1] > open1[-1] condition_4 = (close[-1] > open1[-2]) & (open1[-1]<close[-2]) result = condition_1 & condition_2 & condition_3 & condition_4 out[:] = result class volume(CustomFilter): # this is a class for build a relative volume indicator and select a particular range inputs = [USEquityPricing.volume] window_length = 6 def compute(self, today, assets, out, vol): low_condition_1 = vol[-1] / np.mean(vol, axis = 0)>=1 low_condition_2 = (vol[-1] / np.mean(vol, axis = 0))<2 out[:] = low_condition_1 & low_condition_2 def initialize(context): schedule_function( my_rebalance, date_rules.every_day(), time_rules.market_open() ) my_pipe = make_pipeline() attach_pipeline(my_pipe, 'my_pipeline') def make_pipeline(): sector = Fundamentals.morningstar_sector_code.latest industry = Fundamentals.morningstar_industry_code.latest #universe= Q3000US() & sector.element_of([206]) universe = Q3000US() & QTradableStocksUS() sma20 = SimpleMovingAverage(inputs = [USEquityPricing.close], window_length=20 ) sma50 = SimpleMovingAverage(inputs = [USEquityPricing.close], window_length=50, mask = universe ) sma200 = SimpleMovingAverage(inputs = [USEquityPricing.close], window_length=200 ) price = SimpleMovingAverage(inputs = [USEquityPricing.close], window_length=1, mask = universe ) high = SimpleMovingAverage(inputs = [USEquityPricing.high], window_length=1, mask = universe ) low = SimpleMovingAverage(inputs = [USEquityPricing.low], window_length=1, mask = universe ) close = SimpleMovingAverage(inputs = [USEquityPricing.close], window_length=1, mask = universe ) open1 = SimpleMovingAverage(inputs = [USEquityPricing.open], window_length=1, mask = universe ) rsi = RSI() macd = MACDSignal() corr = RollingPearsonOfReturns(target=symbol('SPY'),returns_length = 20, correlation_length =20 ) #1 condition_1 = rsi < 40 condition_2 = macd < -1.5 technical_condition = condition_2 & condition_1 #2 condition_1 = price > sma20 condition_2 = price < sma50 condition_3 = price < sma200 condition_4 = 5 < price <120 sma_condition = condition_1 & condition_4 & condition_3 & condition_2 #3 mid_price = (high+low)/2 box = (close-open1).abs() limit_box = (high-low)*0.25 condition_5 = close > mid_price condition_6 = open1 > mid_price condition_7 = box <= limit_box # this is way to construct a hammer candle pattern hammer = condition_5 & condition_6 & condition_7 #in order to select hammer candle pattern or engulf pattern price_action = (hammer & volume() | (engulf() ) ) indicator = sma_condition #technical_condition | longs1 = ((corr<0.4)&(corr>0.3)) & indicator & price_action #a strategy signal to close the trade exits1 = sma50 < sma20 #exits2 = rsi > 50 return Pipeline(columns={ "longs1": longs1, "exits1": exits1} ,screen = universe ) def compute_target_weights(context, data): weights = {} if context.longs1: long_weight = 1 / len(context.longs1) else: return weights for security in context.portfolio.positions: if security in context.longs1 and data.can_trade(security): weights[security] = 0 for security in context.longs1: weights[security] = long_weight #for security in context.longs2: #weights[security] = long2_weight return weights def before_trading_start(context, data): """ Get pipeline results. """ # Gets our pipeline output every day. pipe_results = pipeline_output('my_pipeline') # Go long in securities for which the 'longs' value is True, # and check if they can be traded. context.longs1 = [] for sec in pipe_results[pipe_results['longs1']].index.tolist(): if data.can_trade(sec): context.longs1.append(sec) context.exits1 = [] for sec in pipe_results[pipe_results['exits1']].index.tolist(): if data.can_trade(sec): context.exits1.append(sec) def my_rebalance(context, data): target_weights = compute_target_weights(context, data) if target_weights: order_optimal_portfolio( objective=opt.TargetWeights(target_weights), constraints=[], ) #for sec in context.portfolio.positions: # if sec in context.exits1: # order_target_percent(sec,0) # print(sec)