look please look over it whats your thoughts
look please look over it whats your thoughts
You used very old code, maybe one of the earliest on Quantopian.
The following shows how it might look for the current version of Quantopian.
def initialize(context):
schedule_function(trade, date_rules.every_day(), time_rules.market_open(minutes = 65))
context.aapl = sid(24)
def trade(context, data):
if get_open_orders(): return
price = data.current(context.aapl, 'price')
mavg = data.history(context.aapl, 'price', 30, '1d').mean()
if data.can_trade(context.aapl):
if price < mavg * 0.995:
order_target_percent(context.aapl, 0)
elif price > mavg * 1.005:
order_target_percent(context.aapl, 1.0)
record(leverage = context.account.net_leverage)
The original code jumps to very high leverage (margin, borrowing), and that appears as if profit in the chart. Todd, note that trades are entered in one minute and not executed until the next.
Vladamir's version is well-behaved keeping leverage at 1 so that's great.
Here are some things to keep in mind as the algo becomes more complex ...
The main reason I decided to write is kind of side-note:
One nuance for efficiency is that get_open_orders() does some work, looping through orders. Here is the code in zipline:
def get_open_orders(self, asset=None):
"""Retrieve all of the current open orders.
Parameters
----------
asset : Asset
If passed and not None, return only the open orders for the given
asset instead of all open orders.
Returns
-------
open_orders : dict[list[Order]] or list[Order]
If no asset is passed this will return a dict mapping Assets
to a list containing all the open orders for the asset.
If an asset is passed then this will return a list of the open
orders for this asset.
"""
if asset is None:
return {
key: [order.to_api_obj() for order in orders]
for key, orders in iteritems(self.blotter.open_orders)
if orders
}
if asset in self.blotter.open_orders:
orders = self.blotter.open_orders[asset]
return [order.to_api_obj() for order in orders]
return []
So then, while this point doesn't matter in the algo above, since it is a single stock, as soon as a loop through multiple stocks is introduced, get_open_orders() can be called once prior to the loop, and then each time through the loop merely check to see if the security id is present as a key in the result, gathered once.
And a similar route with data.history() collecting history for all stocks all at once and then indexing into the results for each individual stock usually pretty easy to do yet often overlooked in code out there.
In this algo, context.stocks can be enabled for more than one stock and then the points above become relevant as the loop is executed more than once. Also a couple of other best practices in this code for efficiency. Commented, hopefully educational.