In this algorithmic trading with Python tutorial, we're going to consider the topic of stop-loss. Stop-loss is a method used by traders to "cut their losses" at a certain point. Say you bought a company for $100, expecting it to go to $125. Instead, it just keeps dropping. With stop-loss, you can set a limit, say $89. If price falls below $89, then you want to just cut your losses. That's what we'll be covering next.
Before we make that addition to our trading algorithm, I would first like to bring up the algorithm-saving feature built into Quantopian when you run your full backtests. Every time you run a full backtest, everything is saved, from the results to the code in your algorithm that generated those returns. This allows you to run a full backtest, make some changes, and then run again to compare results. You can view all backtests by choosing the "backtest" tab from your editing of an algorithm:
If you click that, then choose the "all backtests" button, you should see a table of all of your backtests for that specific trading algorithm. They are saved back #, date run, the date range, trade frequency, the overall return, and whether or not it completed (you can stop them, or an error might stop them).
You can then click on any of these previous back-tests to see them, then comes the cool part:
Clicking that button in the top right, lets you then view the code that generated that specific backtest. This lets you continue to modify your code, and, if you want to revert back to an older version, you can grab the older code and start again.
Back to our trading algorithm, we want to add a stop-loss to our logic. To do this, you just need to add one more parameter to your order, called style.
So, now our order looks something like:
order(stock, share_amount, style=StopOrder(stop_price))
We use the following to calculate the stop_price:
stop_price = stock_price - (stock_price*0.005)
Full code is now:
def initialize(context): context.limit = 10 schedule_function(rebalance, date_rule = date_rules.every_day(), time_rule = time_rules.market_open()) def rebalance(context, data): for stock in context.portfolio.positions: if stock not in context.fundamentals and stock in data: order_target_percent(stock, 0) # Will be called on every trade event for the securities you specify. def before_trading_start(context): context.fundamentals = get_fundamentals( query( fundamentals.valuation_ratios.pb_ratio, fundamentals.valuation_ratios.pe_ratio, ) .filter( fundamentals.valuation_ratios.pe_ratio < 14 ) .filter( fundamentals.valuation_ratios.pb_ratio < 2 ) .order_by( fundamentals.valuation.market_cap.desc() ) .limit(context.limit) ) update_universe(context.fundamentals.columns.values) def handle_data(context, data): cash = context.portfolio.cash current_positions = context.portfolio.positions for stock in data: current_position = context.portfolio.positions[stock].amount stock_price = data[stock].price plausible_investment = cash / context.limit stop_price = stock_price - (stock_price*0.005) share_amount = int(plausible_investment / stock_price) try: if stock_price < plausible_investment: if current_position == 0: if context.fundamentals[stock]['pe_ratio'] < 11: order(stock, share_amount, style=StopOrder(stop_price)) except Exception as e: print(str(e))