Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Why do many transactions happen in one day, if I only wait two?

English version:
First of all, I inform you that I have three weeks reviewing Quantopian, also, I am new in the world of the financial market and in python. Therefore, I have great ignorance of many things in those fields.

On the other hand, my native language is Latin American Spanish, so for those who read this writing in English, I beg you to excuse my bad writing in English.

The point is that I am programming, in a date range of several months, the following:
1.- Only a daily short entry, which is placed three minutes after the market opens with the function called apertura_ordenes_venta. I am working with Apple stocks, just as an example.
2.- Every minute, through handle_data, it is checked whether the Take Profit or Stop Loss has occurred. In either case, the orders are closed.
I use the global variable cerrar_operacion to ensure that handle_data shows, once a day, when it occurs, that the Take Profit or the Stop Loss was reached. That is, during the day, after reaching Take Profit or Stopp Loss, nothing is done anymore.
3.- Five minutes before the market closes, through a function called terminando_el_dia, all open orders are closed.

Now, what I don't understand, and what I hope someone clarifies for me, is the following:
1.- Why, when running the Run Full Backtest, do many transactions appear every day, for example 18 transactions: several purchases and several sales?.Although I am only placing one sell order per day, three minutes after the market opens. And as I have programmed, a Take Profit or a Stop Loss should also occur. That is, I would expect only two transactions.
2.- Why sometimes the following situation occurs: “WARN Your order for -34745 shares of AAPL failed to fill by the end of day and was canceled”.
If I close all orders, 5 minutes before the market closes?

Below I show the code.

I would greatly appreciate if someone could help me clarify this situation.

Note: I'm very sorry but I couldn't add the code with attach.

Versión en español:
Primero que nada, les informo que tengo tres semanas revisando Quantopian, también, soy nuevo en el mundo del mercado financiero y en python. Por lo tanto, tengo gran desconocimiento de muchas cosas esos campos.

Por otro lado, mi idioma nativo es el español latinoamericano, entonces para quienes leen este escrito en inglés, les ruego sepan disculpar mi mala redacción en inglés.

El punto es que estoy programando, en un rango de fechas de varios meses, lo siguiente:
1.- Sólo una entrada en corto diaria, que se coloca tres minutos después que abre el mercado con la función que se llama apertura_ordenes_venta. Estoy trabajando con acciones de Apple, sólo como ejemplo.
2.- Cada minuto, a través de handle_data, se revisa si ha ocurrido el Take Profit o el Stop Loss. En cualquiera de los casos, se cierran las órdenes.
Utilizo la variable global cerrar_operacion para asegurar que handle_data muestre, una sola vez al día, cuando ocurre, que se alcanzó el Take Profit o el Stopp Loss. Es decir, que durante el día, después de alcanzar Take Profit o Stopp Loss no se hace más nada.
3.- Cinco minutos antes de que cierre el mercado, a través de una función que se llama terminando_el_dia, se cierran todas las órdenes abiertas.

Ahora, lo que no entiendo, y que espero que alguien me aclare, es lo siguiente:
1.- Por qué, al correr el Run Full Backtest, aparecen, cada día, muchas transacciones, por ejemplo 18 transacciones: varias compras y varias ventas?. Si yo, sólo estoy colocando una orden de venta al día, tres minutos después que abre el mercado. Y tal como tengo programado, debería ocurrir, también, un Take Profit o un Stop Loss. Es decir, yo esperaría sólo dos transacciones.
2.- Por qué a veces, ocurre la siguiente situación: WARN Your order for -34745 shares of AAPL failed to fill by the end of day and was canceled. Si yo cierro todas las órdenes, 5 minutos antes de que cierre el mercado?.

A continuación, muestro el código.

Mucho agradecería que alguien me pudiera ayudar a aclarar esta situación.

Nota: Lo siento mucho, pero no pude adjuntar el código con Attach.

2020-04-01 09:33 apertura_ordenes_venta:28 INFO Orden -1.0 AAPL Precio Actual 247.81 Precio Stop 247.79
2020-04-01 12:50 handle_data:57 INFO Take Profit -40353 AAPL Costo Base 247.19 Precio Actual 242.19 ratio 0.98
2020-04-02 09:33 apertura_ordenes_venta:28 INFO Orden -1.0 AAPL Precio Actual 239.15 Precio Stop 239.13
2020-04-02 10:09 handle_data:57 INFO Stop Loss -42542 AAPL Costo Base 237.93 Precio Actual 240.38 ratio 1.01
2020-04-03 09:33 apertura_ordenes_venta:28 INFO Orden -1.0 AAPL Precio Actual 244.17 Precio Stop 244.15
2020-04-06 09:33 apertura_ordenes_venta:28 INFO Orden -1.0 AAPL Precio Actual 250.33 Precio Stop 250.30
2020-04-06 09:51 handle_data:57 INFO Stop Loss -40573 AAPL Costo Base 249.89 Precio Actual 253.07 ratio 1.01
2020-04-07 09:33 apertura_ordenes_venta:28 INFO Orden -1.0 AAPL Precio Actual 268.75 Precio Stop 268.72
2020-04-07 09:56 handle_data:57 INFO Stop Loss -37285 AAPL Costo Base 267.17 Precio Actual 270.05 ratio 1.01
2020-04-08 09:33 apertura_ordenes_venta:28 INFO Orden -1.0 AAPL Precio Actual 262.89 Precio Stop 262.86
2020-04-08 11:13 handle_data:57 INFO Stop Loss -37730 AAPL Costo Base 262.30 Precio Actual 265.05 ratio 1.01
2020-04-09 09:33 apertura_ordenes_venta:28 INFO Orden -1.0 AAPL Precio Actual 268.09 Precio Stop 268.06
2020-04-13 09:33 apertura_ordenes_venta:28 INFO Orden -1.0 AAPL Precio Actual 268.00 Precio Stop 267.97
2020-04-13 14:57 handle_data:57 INFO Stop Loss -36560 AAPL Costo Base 267.28 Precio Actual 269.97 ratio 1.01
2020-04-14 09:33 apertura_ordenes_venta:28 INFO Orden -1.0 AAPL Precio Actual 279.34 Precio Stop 279.31
2020-04-14 16:00 WARN Your order for -34745 shares of AAPL failed to fill by the end of day and was canceled.
2020-04-15 09:33 apertura_ordenes_venta:28 INFO Orden -1.0 AAPL Precio Actual 282.82 Precio Stop 282.79
2020-04-15 13:19 handle_data:57 INFO Stop Loss -34317 AAPL Costo Base 282.37 Precio Actual 285.53 ratio 1.01

cerrar_operacion=0
def initialize(context):
context.stocks = [sid(24)]
context.profit_ratio = 0.98 # Límite, take profit
context.stop_ratio = 1.01 # stoploss
schedule_function(apertura_ordenes_venta, date_rules.every_day(),
time_rules.market_open(minutes=3))
# Cerrando posiciones antes del cierre del mercado
schedule_function(terminando_el_dia, date_rules.every_day(),
time_rules.market_close(minutes=5))

#####################################

Abrir posiciones en corto (ventas)####

#####################################

def apertura_ordenes_venta(context, data):
global cerrar_operacion
#log.info('Cerrar operación: {} '.format(cerrar_operacion))
cerrar_operacion=0
ordenes_abiertas = get_open_orders()
porcentaje = -1.0 # Porcentaje de la orden
for s in context.stocks:
if s in context.portfolio.positions: continue # Si hay una posición No abra órdenes
if s in ordenes_abiertas: continue # Si hay órdenes abiertas No abra otra.
precio_actual = data.current(s, 'price')
precio_stop = precio_actual * 0.9999 # Precio Stop
order_target_percent(s, porcentaje, style=StopOrder(precio_stop))
log.info('Orden {} {} Precio Actual {} Precio Stop {}'.format(
porcentaje, s.symbol, '%.2f' %precio_actual, '%.2f' % precio_stop ))

##########################################################################

Función que corre cada minuto con el fin de cerrar posiciones ####

##########################################################################

def handle_data(context, data):
#Ciclo a través de las posiciones para cerrar órdenes
# Se manejan sólo posiciones cortas en este ejemplo
global cerrar_operacion
for s in context.portfolio.positions:
# Omitir si ya existe una orden de cierre
ordenes_cerradas = 0
for o in get_open_orders(s): #Cancelar cada una de las órdenes abiertas del activo
if cancelar_ordenes_abiertas(context, o) in [0, 2]: #Si hay órdenes cerradas
ordenes_cerradas = 1
break
if ordenes_cerradas: continue
if not data.can_trade(s): continue # Cuando no se puede tradear
precio_actual = data.current(s, 'price')
costo_base = context.portfolio.positions[s].cost_basis
#log.info('Cerrar operación: {} '.format(cerrar_operacion))
if cerrar_operacion==0:
if precio_actual < costo_base * context.profit_ratio or precio_actual > costo_base * context.stop_ratio:
cantidad = context.portfolio.positions[s].amount
ratio = precio_actual / costo_base
mensaje = 'Stop Loss' if ratio > 1 else 'Take Profit'
log.info('{} {} {} Costo Base {} Precio Actual {} ratio {}'.format(
mensaje, cantidad, s.symbol, '%.2f' % costo_base, '%.2f' % precio_actual,
'%.2f' % ratio))
order_target(s, 0)
cerrar_operacion=1
#log.info('Cerrar operación: {} '.format(cerrar_operacion))

############################################################################

Cerrar (vendiendo) todas las órdenes abiertas al final de la jornada ###

############################################################################

def terminando_el_dia(context, data):
for s in context.portfolio.positions:
ordenes_abiertas = get_open_orders()
for s in ordenes_abiertas:
for o in ordenes_abiertas[s]:
cancel_order(o.id) # Cancelar todas las órdenes abiertas
# Si no hay orden de cierre, cierre.
if not get_open_orders(s):
order_target(s, 0)

##################################################################

Cerrar todas las órdenes abiertas al final de la jornada ###

##################################################################

def cancelar_ordenes_abiertas(c, o): # c = contexto o = objecto orden
# Si la orden se está cerrando, abriendo o crossover (short to long or reverse)
cantidad = c.portfolio.positions[o.sid].amount
if (cantidad - o.filled) * o.amount < 0: # close or x
if abs(o.amount) > abs(cantidad - o.filled):
if abs(cantidad) - abs(o.filled) < 0:
return 3 # crossed 0 shares and now opening
else: return 2 # x crossover
else: return 0 # close
else: return 1 # open

5 responses

I hope someone takes the trouble to clarify this for me.

@Luciano Maldonado. First off, welcome to Quantopian.

I believe what you are seeing are multiple 'fills' associated with each order. The backtester, as in live trading, may not be able to fill an entire order in a single minute and the order will fill over several minutes. This is also the reason for the error

Your order for -34745 shares of AAPL failed to fill by the end of day and was canceled

If you place an order at the very last minute of the day, there may not be enough trade volume to actually fill your order. A portion of the order will fill but the remaining will be canceled (all orders on Quantopian are placed as 'day orders').

The backtester tries to model live trading fills with the use of 'slippage models'. This is a user settable function which determines both the price at which an order fills and the quantity of shares which are filled each minute. The default slippage model limits the filled shares to 10% of volume in any one minute. By default, the maximum number of shares filled will never be more than 10% of the total shares traded in that minute. One can change this behavior by changing the slippage model. See the documentation for more on this. To have an order always fill completely at the close of the last minute, one can specify NoSlippage by putting the following line of code in initialize

    set_slippage(slippage.NoSlippage())

Another approach is to reduce the starting account value used in the backtest, The default is $10,000,000. If one is trading all of this in a single stock, even if the stock is highly liquid like AAPL, orders will not fill in a single minute. Reduce this to perhaps $100,000 and orders should fill completely and not be spread out over several minutes.

Hope that helps and may explain what you are experiencing.

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

Very grateful to you Dan.

Your observations clarify several things for me.
An additional question: So if I use "NoSlippage" I don't need the function I'm using to close open orders before the market closes?

All orders on Quantopian are placed as 'Day Orders' and will automatically be closed at the end of the day. This is independent of whether NoSlippage is used or not. So, if all you want to do is ensure the orders won't carry over to the next day, you do not need to manually close them. Whenever the backtester closes an open order at the end of the day a message will appear in the logs "Your order for XXX shares of XXX failed to fill by the end of day and was canceled" (you already saw that). One reason many users manually cancel all their orders at the end of the day is to NOT get this message. If one has many open orders this message can be quite annoying. But remember, this closes open orders. It won't close open positions.

Understood Dan,
thanks.