| Overall Statistics |
|
Total Trades 916 Average Win 4.04% Average Loss -2.37% Compounding Annual Return 117.376% Drawdown 27.500% Expectancy 0.133 Net Profit 153.266% Sharpe Ratio 1.467 Probabilistic Sharpe Ratio 54.249% Loss Rate 58% Win Rate 42% Profit-Loss Ratio 1.70 Alpha 0.825 Beta -0.327 Annual Standard Deviation 0.565 Annual Variance 0.319 Information Ratio 1.397 Tracking Error 0.601 Treynor Ratio -2.534 Total Fees $13427.00 Estimated Strategy Capacity $500000.00 Lowest Capacity Asset QQQ 31YOV01PL5K2U|QQQ RIWIV7K5Z9LX |
#region imports
from AlgorithmImports import *
#endregion
import math
class OptionTradeManagement:
def __init__(self, algorithm, symbol_call, symbol_put):
self.algorithm = algorithm
self.symbol_call = symbol_call
self.quantity_call = None
self.entry_price_call = None
self.stop_loss_call_ = None
self.first_take_profit_call = None
self.updated_first_take_profit_call = None
self.second_take_profit_call = None
self.third_take_profit_call = None
self.fourth_take_profit_call = None
self.fifth_take_profit_call = None
self.sixth_take_profit_call = None
self.seventh_take_profit_call = None
self.trailing_call = False
self.trailing_call_updated = False
self.trailing_call_second = False
self.trailing_call_third = False
self.trailing_call_fourth = False
self.trailing_call_fifth = False
self.trailing_call_sixth = False
self.trailing_call_seventh = False
self.peak_price_call = None # for trailing purposes
self.doubled_call = False
self.doubled_put = False
self.symbol_put = symbol_put
self.quantity_put = None
self.entry_price_put = None
self.stop_loss_put = None
self.first_take_profit_put = None
self.updated_first_take_profit_put = None
self.second_take_profit_put = None
self.third_take_profit_put = None
self.fourth_take_profit_put = None
self.fifth_take_profit_put = None
self.sixth_take_profit_put = None
self.seventh_take_profit_put = None
self.trailing_put = False
self.trailing_put_updated = False
self.trailing_put_second = False
self.trailing_put_third = False
self.trailing_put_fourth = False
self.trailing_put_fifth = False
self.trailing_put_sixth = False
self.trailing_put_seventh = False
self.peak_price_put = None # for trailing purposes
def create_entry(self, size_call, size_put):
self.quantity_call = size_call
self.quantity_put = size_put
self.algorithm.MarketOrder(self.symbol_call, size_call)
self.algorithm.MarketOrder(self.symbol_put, size_put)
self.entry_price_call = self.algorithm.Securities[self.symbol_call].AskPrice
self.entry_price_put = self.algorithm.Securities[self.symbol_put].AskPrice
self.first_take_profit_call = 10 * self.entry_price_call
self.updated_first_take_profit_call = 10 * self.entry_price_call
self.second_take_profit_call = 10 * self.entry_price_call
self.updated_first_take_profit_put = 10 * self.entry_price_put
self.first_take_profit_put = 10 * self.entry_price_put
self.second_take_profit_put = 10 * self.entry_price_put
self.third_take_profit_call = 10 * self.entry_price_call
self.third_take_profit_put = 10 * self.entry_price_put
self.fourth_take_profit_put = 10 * self.entry_price_put
self.fourth_take_profit_call = 10 * self.entry_price_call
self.fifth_take_profit_put = 10 * self.entry_price_put
self.fifth_take_profit_call = 10 * self.entry_price_call
self.sixth_take_profit_put = 10 * self.entry_price_put
self.sixth_take_profit_call = 10 * self.entry_price_call
self.seventh_take_profit_call = 10 * self.entry_price_call
self.seventh_take_profit_put = 10 * self.entry_price_put
self.doubled_metric_call = 2 * self.entry_price_call
self.doubled_metric_put = 2 * self.entry_price_put
self.stop_loss_call = 0.25 * self.entry_price_call
self.stop_loss_put = 0.25 * self.entry_price_put
self.peak_price_call = self.entry_price_call
self.peak_price_put = self.entry_price_put
self.algorithm.Debug(f"{self.algorithm.Time} - Entering CALL: {self.symbol_call} @ entry: {self.entry_price_call} @ first_take_profit: {self.first_take_profit_call} @updated_take_profit:{self.updated_first_take_profit_call} @second_take_profit: {self.second_take_profit_call} @third_take_profit: {self.third_take_profit_call} @fourth_take_profit: {self.fourth_take_profit_call} @fifth_take_profit: {self.fifth_take_profit_call} @sixth_take_profit: {self.sixth_take_profit_call} @seventh_take_profit: {self.seventh_take_profit_call} stop_loss: {self.stop_loss_call}")
self.algorithm.Debug(f"{self.algorithm.Time} - Entering PUT: {self.symbol_put} @ entry: {self.entry_price_put} @ first_take_profit: {self.first_take_profit_put} @updated_take_profit: {self.updated_first_take_profit_put} @second_take_profit: {self.second_take_profit_put} @third_take_profit: {self.third_take_profit_put} @fourth_take_profit: {self.fourth_take_profit_put} @fifth_take_profit: {self.fifth_take_profit_put} @sixth_take_profit: {self.sixth_take_profit_put} @seventh_take_profit: {self.seventh_take_profit_put} stop_loss: {self.stop_loss_put}")
self.size = (self.entry_price_call * 100 * self.quantity_call) + (self.entry_price_put * 100 * self.quantity_put)
self.algorithm.Debug("Total asset size: " + str(self.size))
def doubled(self):
call_price = self.algorithm.Securities[self.symbol_call].BidPrice
put_price = self.algorithm.Securities[self.symbol_put].BidPrice
if call_price >= self.doubled_metric_call:
self.doubled_call = True
if put_price >= self.doubled_metric_put:
self.doubled_put = True
if not self.doubled_call and not self.doubled_put:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug("Liquidating positions due to 7:30 PST rule")
def check_and_update_position(self):
call_price = self.algorithm.Securities[self.symbol_call].BidPrice
put_price = self.algorithm.Securities[self.symbol_put].BidPrice
''' Update Peak Prices'''
## Updates Peak Incase we are trailing
if call_price > self.peak_price_call:
self.peak_price_call = call_price
if put_price > self.peak_price_put:
self.peak_price_put = put_price
'''============== Check Take Profit and Start Trailing ==========='''
# If we aren't trailing and we've hit our take profit
# Start trailing and sell half
if not self.trailing_call and call_price >= self.first_take_profit_call:
if self.algorithm.Portfolio[self.symbol_call].Invested and self.algorithm.Portfolio[self.symbol_call].Quantity == self.quantity_call:
self.trailing_call = True
sell_quantity = (self.quantity_call * .75 + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.first_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking First 25% Profit Call {self.symbol_call} @ {call_price}")
if not self.trailing_put and put_price >= self.first_take_profit_put:
if self.algorithm.Portfolio[self.symbol_put].Invested and self.algorithm.Portfolio[self.symbol_put].Quantity == self.quantity_put:
self.trailing_put = True
sell_quantity = (self.quantity_put * .75 + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.first_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking First 25% Profit PUT {self.symbol_put} @ {put_price}")
if not self.trailing_call_updated and call_price >= self.updated_first_take_profit_call:
if self.algorithm.Portfolio[self.symbol_call].Invested:
self.trailing_call_updated = True
sell_quantity = (self.quantity_call * .75 + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.updated_first_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking First Updated 100% Profit Call {self.symbol_call} @ {call_price}")
if not self.trailing_put_updated and put_price >= self.updated_first_take_profit_put:
self.trailing_put_updated = True
sell_quantity = (self.quantity_put *.75 + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.updated_first_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking First Updated 100% Profit Put {self.symbol_put} @ {put_price}")
if not self.trailing_call_second and call_price >= self.second_take_profit_call:
self.trailing_call_second = True
if self.algorithm.Portfolio[self.symbol_call].Invested and self.quantity_call == 1:
sell_quantity = (self.quantity_call // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.second_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Second 100% Profit Call {self.symbol_call} @ {call_price}")
elif self.algorithm.Portfolio[self.symbol_call].Invested:
sell_quantity = (self.quantity_call * .25 + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.second_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Second 100% Profit Call {self.symbol_call} @ {call_price}")
if not self.trailing_put_second and put_price >= self.second_take_profit_put:
self.trailing_put_second = True
if self.algorithm.Portfolio[self.symbol_put].Invested and self.algorithm.Portfolio[self.symbol_put].Quantity == 1:
sell_quantity = (self.quantity_put // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.second_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Second 100% Profit PUT {self.symbol_put} @ {put_price}")
elif self.algorithm.Portfolio[self.symbol_put].Invested:
sell_quantity = (self.quantity_put * .25 + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.second_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Second 100% Profit PUT {self.symbol_put} @ {put_price}")
if not self.trailing_call_third and call_price >= self.third_take_profit_call:
self.trailing_call_third = True
if self.algorithm.Portfolio[self.symbol_call].Invested and self.quantity_call == 1:
sell_quantity = (self.quantity_call // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.third_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Third Profit CALL {self.symbol_put} @ {call_price}")
elif self.algorithm.Portfolio[self.symbol_call].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.third_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Third Profit CALL {self.symbol_put} @ {call_price}")
if not self.trailing_put_third and put_price >= self.third_take_profit_put:
self.trailing_put_third = True
if self.algorithm.Portfolio[self.symbol_put].Invested and self.quantity_put == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.third_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Third Profit PUT {self.symbol_put} @ {put_price}")
elif self.algorithm.Portfolio[self.symbol_put].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.third_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Third Profit PUT {self.symbol_put} @ {put_price}")
if not self.trailing_call_fourth and call_price >= self.fourth_take_profit_call:
self.trailing_call_fourth = True
if self.algorithm.Portfolio[self.symbol_call].Invested and self.algorithm.Portfolio[self.symbol_call].Quantity == 1:
sell_quantity = (self.quantity_call // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.fourth_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fourth Profit CALL {self.symbol_call} @ {call_price}")
elif self.algorithm.Portfolio[self.symbol_call].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.fourth_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fourth Profit CALL {self.symbol_put} @ {call_price}")
if not self.trailing_put_fourth and put_price >= self.fourth_take_profit_put:
self.trailing_put_fourth = True
if self.algorithm.Portfolio[self.symbol_put].Invested and self.quantity_put == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.fourth_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fourth Profit PUT {self.symbol_put} @ {put_price}")
elif self.algorithm.Portfolio[self.symbol_put].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.fourth_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fourth Profit PUT {self.symbol_put} @ {put_price}")
if not self.trailing_call_fifth and call_price >= self.fifth_take_profit_call:
self.trailing_call_fifth = True
if self.algorithm.Portfolio[self.symbol_call].Invested and self.quantity_call == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.fifth_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fifth Profit Call {self.symbol_call} @ {call_price}")
elif self.algorithm.Portfolio[self.symbol_call].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.fifth_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fifth Profit CALL {self.symbol_put} @ {call_price}")
if not self.trailing_put_fifth and put_price >= self.fifth_take_profit_put:
self.trailing_put_fifth = True
if self.algorithm.Portfolio[self.symbol_put].Invested and self.quantity_put == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.fifth_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fifth Profit PUT {self.symbol_put} @ {put_price}")
elif self.algorithm.Portfolio[self.symbol_put].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.fifth_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fifth Profit PUT {self.symbol_put} @ {put_price}")
if not self.trailing_call_sixth and call_price >= self.sixth_take_profit_call:
self.trailing_call_sixth = True
if self.algorithm.Portfolio[self.symbol_call].Invested and self.quantity_call == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.sixth_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Sixth Profit Call {self.symbol_call} @ {call_price}")
elif self.algorithm.Portfolio[self.symbol_call].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.sixth_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Sixth Profit CALL {self.symbol_put} @ {call_price}")
if not self.trailing_put_sixth and put_price >= self.sixth_take_profit_put:
self.trailing_put_sixth = True
if self.algorithm.Portfolio[self.symbol_put].Invested and self.quantity_put == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.sixth_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Sixth Profit PUT {self.symbol_put} @ {put_price}")
elif self.algorithm.Portfolio[self.symbol_put].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.sixth_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Sixth Profit PUT {self.symbol_put} @ {put_price}")
if not self.trailing_call_seventh and call_price >= self.seventh_take_profit_call:
self.trailing_call_seventh = True
if self.algorithm.Portfolio[self.symbol_call].Invested and self.quantity_call == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.seventh_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Seventh Profit Call {self.symbol_call} @ {call_price}")
elif self.algorithm.Portfolio[self.symbol_call].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.seventh_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Seventh Profit CALL {self.symbol_put} @ {call_price}")
if not self.trailing_put_seventh and put_price >= self.seventh_take_profit_put:
self.trailing_put_seventh = True
if self.algorithm.Portfolio[self.symbol_put].Invested and self.quantity_put == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.seventh_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Seventh Profit PUT {self.symbol_put} @ {put_price}")
elif self.algorithm.Portfolio[self.symbol_put].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.seventh_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Seventh Profit PUT {self.symbol_put} @ {put_price}")
'''=============== STOP LOSS ======================='''
### If we are trailing, Liquidate on stop loss hit
if self.trailing_call:
stop_dist = 3 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
### If we are trailing, Liquidate on stop loss hit
if self.trailing_put:
stop_dist = 3 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_call_updated:
stop_dist = 3 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
if self.trailing_put_updated:
stop_dist = 3 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_call_second:
stop_dist = 10 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
if self.trailing_put_second:
stop_dist = 10 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_call_third:
stop_dist = .5 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
if self.trailing_put_third:
stop_dist = .5 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_put_fourth:
stop_dist = 3 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_call_fourth:
stop_dist = 3 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
if self.trailing_put_fifth:
stop_dist = 3 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_call_fifth:
stop_dist = 3 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
if self.trailing_put_sixth:
stop_dist = 3 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_call_sixth:
stop_dist = 3 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
if self.trailing_put_seventh:
stop_dist = 3 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_call_seventh:
stop_dist = 3 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
@property
def is_active(self):
return self.algorithm.Portfolio[self.symbol_call].Invested or \
self.algorithm.Portfolio[self.symbol_put].Invested
def liquid_limit(self):
call_price = self.algorithm.Securities[self.symbol_call].BidPrice
put_price = self.algorithm.Securities[self.symbol_put].BidPrice
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Liquidate(self.symbol_put)
C_Price = call_price - .1
if self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.LimitOrder(self.symbol_call, -self.algorithm.Portfolio[self.symbol_call].Quantity, C_Price)
self.algorithm.Debug("Call Limit price liquidation: " + str(C_Price))
P_Price = put_price - .1
if self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.LimitOrder(self.symbol_put, -self.algorithm.Portfolio[self.symbol_put].Quantity, P_Price)
self.algorithm.Debug("Put Limit price liquidation: " + str(P_Price))
#region imports
from AlgorithmImports import *
#endregion
import math
class OptionTradeManagement2:
def __init__(self, algorithm, symbol_call, symbol_put):
self.algorithm = algorithm
self.symbol_call = symbol_call
self.quantity_call = None
self.entry_price_call = None
self.stop_loss_call_ = None
self.first_take_profit_call = None
self.updated_first_take_profit_call = None
self.second_take_profit_call = None
self.third_take_profit_call = None
self.fourth_take_profit_call = None
self.fifth_take_profit_call = None
self.sixth_take_profit_call = None
self.seventh_take_profit_call = None
self.trailing_call = False
self.trailing_call_updated = False
self.trailing_call_second = False
self.trailing_call_third = False
self.trailing_call_fourth = False
self.trailing_call_fifth = False
self.trailing_call_sixth = False
self.trailing_call_seventh = False
self.peak_price_call = None # for trailing purposes
self.doubled_call = False
self.doubled_put = False
self.symbol_put = symbol_put
self.quantity_put = None
self.entry_price_put = None
self.stop_loss_put = None
self.first_take_profit_put = None
self.updated_first_take_profit_put = None
self.second_take_profit_put = None
self.third_take_profit_put = None
self.fourth_take_profit_put = None
self.fifth_take_profit_put = None
self.sixth_take_profit_put = None
self.seventh_take_profit_put = None
self.trailing_put = False
self.trailing_put_updated = False
self.trailing_put_second = False
self.trailing_put_third = False
self.trailing_put_fourth = False
self.trailing_put_fifth = False
self.trailing_put_sixth = False
self.trailing_put_seventh = False
self.peak_price_put = None # for trailing purposes
def create_entry(self, size_call, size_put):
self.quantity_call = size_call
self.quantity_put = size_put
self.algorithm.MarketOrder(self.symbol_call, size_call)
self.algorithm.MarketOrder(self.symbol_put, size_put)
self.entry_price_call = self.algorithm.Securities[self.symbol_call].AskPrice
self.entry_price_put = self.algorithm.Securities[self.symbol_put].AskPrice
self.first_take_profit_call = 10 * self.entry_price_call
self.updated_first_take_profit_call = 10 * self.entry_price_call
self.second_take_profit_call = 10 * self.entry_price_call
self.updated_first_take_profit_put = 10 * self.entry_price_put
self.first_take_profit_put = 10 * self.entry_price_put
self.second_take_profit_put = 10 * self.entry_price_put
self.third_take_profit_call = 10 * self.entry_price_call
self.third_take_profit_put = 10 * self.entry_price_put
self.fourth_take_profit_put = 10 * self.entry_price_put
self.fourth_take_profit_call = 10 * self.entry_price_call
self.fifth_take_profit_put = 10 * self.entry_price_put
self.fifth_take_profit_call = 10 * self.entry_price_call
self.sixth_take_profit_put = 10 * self.entry_price_put
self.sixth_take_profit_call = 10 * self.entry_price_call
self.seventh_take_profit_call = 10 * self.entry_price_call
self.seventh_take_profit_put = 10 * self.entry_price_put
self.doubled_metric_call = 2 * self.entry_price_call
self.doubled_metric_put = 2 * self.entry_price_put
self.stop_loss_call = 0.25 * self.entry_price_call
self.stop_loss_put = 0.25 * self.entry_price_put
self.peak_price_call = self.entry_price_call
self.peak_price_put = self.entry_price_put
self.algorithm.Debug(f"{self.algorithm.Time} - Entering CALL: {self.symbol_call} @ entry: {self.entry_price_call} @ first_take_profit: {self.first_take_profit_call} @updated_take_profit:{self.updated_first_take_profit_call} @second_take_profit: {self.second_take_profit_call} @third_take_profit: {self.third_take_profit_call} @fourth_take_profit: {self.fourth_take_profit_call} @fifth_take_profit: {self.fifth_take_profit_call} @sixth_take_profit: {self.sixth_take_profit_call} @seventh_take_profit: {self.seventh_take_profit_call} stop_loss: {self.stop_loss_call}")
self.algorithm.Debug(f"{self.algorithm.Time} - Entering PUT: {self.symbol_put} @ entry: {self.entry_price_put} @ first_take_profit: {self.first_take_profit_put} @updated_take_profit: {self.updated_first_take_profit_put} @second_take_profit: {self.second_take_profit_put} @third_take_profit: {self.third_take_profit_put} @fourth_take_profit: {self.fourth_take_profit_put} @fifth_take_profit: {self.fifth_take_profit_put} @sixth_take_profit: {self.sixth_take_profit_put} @seventh_take_profit: {self.seventh_take_profit_put} stop_loss: {self.stop_loss_put}")
self.size = (self.entry_price_call * 100 * self.quantity_call) + (self.entry_price_put * 100 * self.quantity_put)
self.algorithm.Debug("Total asset size: " + str(self.size))
def doubled(self):
call_price = self.algorithm.Securities[self.symbol_call].BidPrice
put_price = self.algorithm.Securities[self.symbol_put].BidPrice
if call_price >= self.doubled_metric_call:
self.doubled_call = True
if put_price >= self.doubled_metric_put:
self.doubled_put = True
if not self.doubled_call and not self.doubled_put:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug("Liquidating positions due to 7:30 PST rule")
def check_and_update_position(self):
call_price = self.algorithm.Securities[self.symbol_call].BidPrice
put_price = self.algorithm.Securities[self.symbol_put].BidPrice
''' Update Peak Prices'''
## Updates Peak Incase we are trailing
if call_price > self.peak_price_call:
self.peak_price_call = call_price
if put_price > self.peak_price_put:
self.peak_price_put = put_price
'''============== Check Take Profit and Start Trailing ==========='''
# If we aren't trailing and we've hit our take profit
# Start trailing and sell half
if not self.trailing_call and call_price >= self.first_take_profit_call:
if self.algorithm.Portfolio[self.symbol_call].Invested and self.algorithm.Portfolio[self.symbol_call].Quantity == self.quantity_call:
self.trailing_call = True
sell_quantity = (self.quantity_call // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.first_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking First 25% Profit Call {self.symbol_call} @ {call_price}")
if not self.trailing_put and put_price >= self.first_take_profit_put:
if self.algorithm.Portfolio[self.symbol_put].Invested and self.algorithm.Portfolio[self.symbol_put].Quantity == self.quantity_put:
self.trailing_put = True
sell_quantity = (self.quantity_put // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.first_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking First 25% Profit PUT {self.symbol_put} @ {put_price}")
if not self.trailing_call_updated and call_price >= self.updated_first_take_profit_call:
if self.algorithm.Portfolio[self.symbol_call].Invested:
self.trailing_call_updated = True
sell_quantity = (self.quantity_call * .5 + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.updated_first_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking First Updated 100% Profit Call {self.symbol_call} @ {call_price}")
if not self.trailing_put_updated and put_price >= self.updated_first_take_profit_put:
self.trailing_put_updated = True
sell_quantity = (self.quantity_put *.5 + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.updated_first_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking First Updated 100% Profit Put {self.symbol_put} @ {put_price}")
if not self.trailing_call_second and call_price >= self.second_take_profit_call:
self.trailing_call_second = True
if self.algorithm.Portfolio[self.symbol_call].Invested and self.quantity_call == 1:
sell_quantity = (self.quantity_call // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.second_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Second 100% Profit Call {self.symbol_call} @ {call_price}")
elif self.algorithm.Portfolio[self.symbol_call].Invested:
sell_quantity = (self.quantity_call * .25 + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.second_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Second 100% Profit Call {self.symbol_call} @ {call_price}")
if not self.trailing_put_second and put_price >= self.second_take_profit_put:
self.trailing_put_second = True
if self.algorithm.Portfolio[self.symbol_put].Invested and self.algorithm.Portfolio[self.symbol_put].Quantity == 1:
sell_quantity = (self.quantity_put // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.second_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Second 100% Profit PUT {self.symbol_put} @ {put_price}")
elif self.algorithm.Portfolio[self.symbol_put].Invested:
sell_quantity = (self.quantity_put * .25 + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.second_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Second 100% Profit PUT {self.symbol_put} @ {put_price}")
if not self.trailing_call_third and call_price >= self.third_take_profit_call:
self.trailing_call_third = True
if self.algorithm.Portfolio[self.symbol_call].Invested and self.quantity_call == 1:
sell_quantity = (self.quantity_call // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.third_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Third Profit CALL {self.symbol_put} @ {call_price}")
elif self.algorithm.Portfolio[self.symbol_call].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.third_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Third Profit CALL {self.symbol_put} @ {call_price}")
if not self.trailing_put_third and put_price >= self.third_take_profit_put:
self.trailing_put_third = True
if self.algorithm.Portfolio[self.symbol_put].Invested and self.quantity_put == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.third_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Third Profit PUT {self.symbol_put} @ {put_price}")
elif self.algorithm.Portfolio[self.symbol_put].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.third_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Third Profit PUT {self.symbol_put} @ {put_price}")
if not self.trailing_call_fourth and call_price >= self.fourth_take_profit_call:
self.trailing_call_fourth = True
if self.algorithm.Portfolio[self.symbol_call].Invested and self.algorithm.Portfolio[self.symbol_call].Quantity == 1:
sell_quantity = (self.quantity_call // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.fourth_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fourth Profit CALL {self.symbol_call} @ {call_price}")
elif self.algorithm.Portfolio[self.symbol_call].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.fourth_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fourth Profit CALL {self.symbol_put} @ {call_price}")
if not self.trailing_put_fourth and put_price >= self.fourth_take_profit_put:
self.trailing_put_fourth = True
if self.algorithm.Portfolio[self.symbol_put].Invested and self.quantity_put == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.fourth_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fourth Profit PUT {self.symbol_put} @ {put_price}")
elif self.algorithm.Portfolio[self.symbol_put].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.fourth_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fourth Profit PUT {self.symbol_put} @ {put_price}")
if not self.trailing_call_fifth and call_price >= self.fifth_take_profit_call:
self.trailing_call_fifth = True
if self.algorithm.Portfolio[self.symbol_call].Invested and self.quantity_call == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.fifth_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fifth Profit Call {self.symbol_call} @ {call_price}")
elif self.algorithm.Portfolio[self.symbol_call].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.fifth_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fifth Profit CALL {self.symbol_put} @ {call_price}")
if not self.trailing_put_fifth and put_price >= self.fifth_take_profit_put:
self.trailing_put_fifth = True
if self.algorithm.Portfolio[self.symbol_put].Invested and self.quantity_put == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.fifth_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fifth Profit PUT {self.symbol_put} @ {put_price}")
elif self.algorithm.Portfolio[self.symbol_put].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.fifth_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Fifth Profit PUT {self.symbol_put} @ {put_price}")
if not self.trailing_call_sixth and call_price >= self.sixth_take_profit_call:
self.trailing_call_sixth = True
if self.algorithm.Portfolio[self.symbol_call].Invested and self.quantity_call == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.sixth_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Sixth Profit Call {self.symbol_call} @ {call_price}")
elif self.algorithm.Portfolio[self.symbol_call].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.sixth_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Sixth Profit CALL {self.symbol_put} @ {call_price}")
if not self.trailing_put_sixth and put_price >= self.sixth_take_profit_put:
self.trailing_put_sixth = True
if self.algorithm.Portfolio[self.symbol_put].Invested and self.quantity_put == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.sixth_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Sixth Profit PUT {self.symbol_put} @ {put_price}")
elif self.algorithm.Portfolio[self.symbol_put].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.sixth_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Sixth Profit PUT {self.symbol_put} @ {put_price}")
if not self.trailing_call_seventh and call_price >= self.seventh_take_profit_call:
self.trailing_call_seventh = True
if self.algorithm.Portfolio[self.symbol_call].Invested and self.quantity_call == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.seventh_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Seventh Profit Call {self.symbol_call} @ {call_price}")
elif self.algorithm.Portfolio[self.symbol_call].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_call].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_call, -sell_quantity, self.seventh_take_profit_call)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Seventh Profit CALL {self.symbol_put} @ {call_price}")
if not self.trailing_put_seventh and put_price >= self.seventh_take_profit_put:
self.trailing_put_seventh = True
if self.algorithm.Portfolio[self.symbol_put].Invested and self.quantity_put == 1:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (2.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.seventh_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Seventh Profit PUT {self.symbol_put} @ {put_price}")
elif self.algorithm.Portfolio[self.symbol_put].Invested:
sell_quantity = (self.algorithm.Portfolio[self.symbol_put].Quantity // (4.0) + .5)
self.algorithm.LimitOrder(self.symbol_put, -sell_quantity, self.seventh_take_profit_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Taking Seventh Profit PUT {self.symbol_put} @ {put_price}")
'''=============== STOP LOSS ======================='''
### If we are trailing, Liquidate on stop loss hit
if self.trailing_call:
stop_dist = 3 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
### If we are trailing, Liquidate on stop loss hit
if self.trailing_put:
stop_dist = 3 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_call_updated:
stop_dist = 3 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
if self.trailing_put_updated:
stop_dist = 3 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_call_second:
stop_dist = 10 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
if self.trailing_put_second:
stop_dist = 10 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_call_third:
stop_dist = .5 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
if self.trailing_put_third:
stop_dist = .5 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_put_fourth:
stop_dist = 3 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_call_fourth:
stop_dist = 3 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
if self.trailing_put_fifth:
stop_dist = 3 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_call_fifth:
stop_dist = 3 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
if self.trailing_put_sixth:
stop_dist = 3 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_call_sixth:
stop_dist = 3 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
if self.trailing_put_seventh:
stop_dist = 3 * self.entry_price_put
self.stop_loss_put = self.peak_price_put - stop_dist
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - Trail Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if put_price <= self.stop_loss_put and \
self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.Liquidate(self.symbol_put)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop PUT {self.symbol_put} @ {put_price} with stop: {self.stop_loss_put}")
if self.trailing_call_seventh:
stop_dist = 3 * self.entry_price_call
self.stop_loss_call = self.peak_price_call - stop_dist
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - TRAIL Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
else:
# 50% stop loss - if hit, liquidate and if other leg not trailing
## update stop loss to entry
if call_price <= self.stop_loss_call and \
self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Debug(f"{self.algorithm.Time} - 50% Stop CALL {self.symbol_call} @ {call_price} with stop: {self.stop_loss_call}")
@property
def is_active(self):
return self.algorithm.Portfolio[self.symbol_call].Invested or \
self.algorithm.Portfolio[self.symbol_put].Invested
def liquid_limit(self):
call_price = self.algorithm.Securities[self.symbol_call].BidPrice
put_price = self.algorithm.Securities[self.symbol_put].BidPrice
self.algorithm.Liquidate(self.symbol_call)
self.algorithm.Liquidate(self.symbol_put)
C_Price = call_price - .1
if self.algorithm.Portfolio[self.symbol_call].Invested:
self.algorithm.LimitOrder(self.symbol_call, -self.algorithm.Portfolio[self.symbol_call].Quantity, C_Price)
self.algorithm.Debug("Call Limit price liquidation: " + str(C_Price))
P_Price = put_price - .1
if self.algorithm.Portfolio[self.symbol_put].Invested:
self.algorithm.LimitOrder(self.symbol_put, -self.algorithm.Portfolio[self.symbol_put].Quantity, P_Price)
self.algorithm.Debug("Put Limit price liquidation: " + str(P_Price))
#region imports
from AlgorithmImports import *
#endregion
from TradeManagement import OptionTradeManagement
from TradeManagementNonOpex import OptionTradeManagement2
import math
'''
Add +-2 for QQQ
'''
class OptionStrategy(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2021, 5, 10) # Set Start Date
self.SetEndDate(2022, 7, 20) # Set End Date
self.SetCash(100000) # Set Strategy Cash
self.ath = 422.17
self.TotalUnrealizedProfit = 0
self.position_dollar_size = 1500
self.trade_managers = []
self.symbol_call = None
self.symbol_put = None
self.opexDay = False
self.tickers = ["QQQ"]
self.symbols = []
self.allAth = {}
self.allContracts = {}
self.maxGap = 3
for ticker in self.tickers:
symbol = self.AddEquity(ticker, Resolution.Minute, extendedMarketHours=True)
symbol.SetDataNormalizationMode(DataNormalizationMode.Raw)
self.symbols.append(symbol.Symbol)
history = self.History(symbol.Symbol, 1000, Resolution.Daily)
high = -1
for tuple in history.itertuples():
if tuple.close > high:
high = tuple.high
self.allAth[symbol.Symbol] = high
for symbol in self.symbols:
self.allContracts[symbol] = []
# To initialize options data as needed - needed for options
self.SetSecurityInitializer(lambda security : security.SetMarketPrice(self.GetLastKnownPrice(security)))
# DAILY MWF ENTRY
# for live trading 1 min after market open should work
self.Schedule.On(self.DateRules.EveryDay("QQQ"),
self.TimeRules.AfterMarketOpen("QQQ", 2), self.AtMarketOpen)
self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday, DayOfWeek.Wednesday, DayOfWeek.Friday),
self.TimeRules.AfterMarketOpen("QQQ", 0), self.Opex)
self.Schedule.On(self.DateRules.Every(DayOfWeek.Tuesday, DayOfWeek.Thursday),
self.TimeRules.AfterMarketOpen("QQQ", 0), self.NonOpex)
#self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday, DayOfWeek.Wednesday, DayOfWeek.Friday),
# self.TimeRules.AfterMarketOpen("SPY", 1), self.grabOpen)
self.Schedule.On(self.DateRules.EveryDay("QQQ"),
self.TimeRules.AfterMarketOpen("QQQ", .1), self.Outright_exit_loss)
self.Schedule.On(self.DateRules.EveryDay("QQQ"),
self.TimeRules.AfterMarketOpen("QQQ", .1), self.UpdateATH)
# EXIT
self.Schedule.On(self.DateRules.EveryDay("QQQ"), self.TimeRules.At(15, 57), self.BeforeMarketClose)
# liquidate if 7:30 and leg hasn't doubled
self.Schedule.On(self.DateRules.EveryDay("QQQ"), self.TimeRules.At(10, 30), self.leg_double)
#self.Schedule.On(self.DateRules.EveryDay("QQQ"), self.TimeRules.At(9, 30), self.TakeProfits)
# def grabOpen(self):
# self.spyOpening = self.Securities[self.spy].Open
def Opex(self):
self.opexDay = True
def NonOpex(self):
self.opexDay = False
def AtMarketOpen(self):
for symbol in self.symbols:
''' When switched also comment this line out '''
self.opening = self.Securities[symbol].Open
self.Debug(self.opening)
history = self.History(symbol, 1, Resolution.Daily)
try:
yesterdayClose = math.floor(float(history.loc[symbol]["close"]))
except:
try:
history = self.History(symbol, 2, Resolution.Daily)
yesterdayClose = math.floor(float(history.loc[symbol]["close"][-1]))
except:
self.Debug("Failed : " + str(symbol))
return
gapSpread = abs(self.opening - yesterdayClose)
self.Debug(str(symbol.Value) + " GAP " + str(gapSpread))
#if gapSpread >= self.maxGap:
#self.Log(f'Market GAPPED...not running')
#continue
open_price = math.floor(self.opening)
if self.opening == -1:
continue
spread = abs(((math.floor(self.allAth[symbol])) - open_price))
self.Debug(str(symbol.Value) + " OPEN: " + str(open_price) + " ATH SPREAD: " + str(spread) + " " + str(self.Time))
if spread <= 3:
self.Log(f'Market is at ATH...not running')
continue
call_symbol, put_symbol = self.select_contracts(symbol, self.opening)
if not call_symbol or not put_symbol:
self.Log(f'Return AtMarketOpen because one of the symbols is None. call_symbol is {call_symbol} and put_symbol is {put_symbol}.')
continue
call_margin = (self.Portfolio.TotalPortfolioValue) * .05
put_margin = (self.Portfolio.TotalPortfolioValue) *.05
#call_margin = self.position_dollar_size // 2
#put_margin = self.position_dollar_size // 2
self.Debug("Call Margin: " + str(call_margin))
self.Debug("Put Margin: " + str(put_margin))
# Quick fix for div by zero error
if float(self.Securities[call_symbol].BidPrice == 0.0) or (self.Securities[put_symbol].AskPrice) == 0.0:
self.Debug("Div error occured on " + str(self.Time))
return
call_size = self.calculate_leg_size(call_symbol, call_margin, "Call")
put_size = self.calculate_leg_size(put_symbol, put_margin, "Put")
# self.Debug("Call Size: " + str(call_size))
# self.Debug("Put Size: " + str(put_size))
self.symbol_call = call_symbol
self.symbol_put = put_symbol
if self.opexDay == True:
self.Log(f'Running OPEX Exits')
trade_manager = OptionTradeManagement(self, call_symbol, put_symbol)
elif self.opexDay == False:
self.Log(f'Running NON OPEX Exits -- Not running')
#continue
trade_manager = OptionTradeManagement2(self, call_symbol, put_symbol)
trade_manager.create_entry(call_size, put_size)
self.trade_managers.append(trade_manager)
morning_balance = (self.Portfolio.TotalPortfolioValue)
self.Debug(morning_balance)
self.allContracts[symbol].append(call_symbol)
self.allContracts[symbol].append(put_symbol)
def BeforeMarketClose(self):
self.Debug(f"1:10 PST/4:10 EST Liquidate")
for trade_manager in self.trade_managers:
if not trade_manager.is_active:
trade_manager = None # get rid of it
continue
trade_manager.liquid_limit()
def leg_double(self):
for trade_manager in self.trade_managers:
if not trade_manager.is_active:
trade_manager = None # get rid of it
continue
trade_manager.doubled()
def OnData(self, data):
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
Arguments:
data: Slice object keyed by symbol containing the stock data
'''
for trade_manager in self.trade_managers:
if not trade_manager.is_active:
trade_manager = None # get rid of it
continue
trade_manager.check_and_update_position()
def calculate_leg_size(self, contract_symbol, call_margin, contract_type):
x = self.Securities[contract_symbol].AskPrice
y = self.Securities[contract_symbol].BidPrice
contract_price = x + y
self.Debug("x or ask : " + str(x))
self.Debug("y or bid: " + str(y))
self.Debug("x + y or bid + ask : " + str(contract_price))
# (self.Securities[contract_symbol].AskPrice + self.Securities[contract_symbol].BidPrice) // 2
temp_price = contract_price * (.5)
self.Debug(" temp price or actual con price used in algo calculation: " + str(temp_price))
if temp_price == 0:
contract_price = contract_price * (.5)
else:
contract_price = temp_price
self.Debug("ASKKKK " + str(self.Securities[contract_symbol].AskPrice))
self.Debug("BIDDDD " + str(self.Securities[contract_symbol].BidPrice))
contract_premium = temp_price * 100.0
self.Debug("Here are the actual contract prices: ")
self.Debug(f"{contract_symbol} : {temp_price}")
#if contract_premium > 100:
#contract_premium = 100000
#self.Debug("Leg Margin " + str(call_margin))
# self.Debug("Prem " + str(contract_premium))
# self.Debug(str(call_margin) + " Prem" + str(contract_premium))
total_contracts = call_margin // contract_premium
total_contracts_divisible_by_two = math.ceil(total_contracts)
total_leg_cost = (total_contracts_divisible_by_two * contract_premium)
#if total_leg_cost > 5000:
#self.Debug("LEG COST GREATER THAN 5000 " + str(total_leg_cost))
#total_contracts_divisible_by_two = total_contracts_divisible_by_two - 5
self.Debug("Type: " + str(contract_type) + ". # of contracts: " + str(total_contracts_divisible_by_two) + ". Price: " + str(contract_price) + ". Premium: " + str(contract_premium) + ". Estimated Total leg cost: " + str(total_leg_cost))
return total_contracts_divisible_by_two
def select_option(self, contract_symbols, right, strike, expiry):
'''Picks out contract given parameters'''
# filter by right
filtered_by_right = [c for c in contract_symbols if c.ID.OptionRight == right]
if not filtered_by_right:
self.Log(f'No symbol with right: {right}')
return None
# lambda # - anonymous
sorted_expiry = sorted(contract_symbols, key=lambda c : abs(c.ID.Date - expiry))
closest_expiry_to_desired_expiry = sorted_expiry[0].ID.Date
all_contracts_with_closest_expiry = [c for c in filtered_by_right if c.ID.Date == closest_expiry_to_desired_expiry]
if not all_contracts_with_closest_expiry:
self.Log(f'No symbol with expity: {closest_expiry_to_desired_expiry}')
return None
''' Selects option '''
sorted_by_strike = sorted(all_contracts_with_closest_expiry,
key=lambda c : abs(c.ID.StrikePrice - strike), reverse = False)
if not sorted_by_strike:
self.Log(f'No symbol found for given arguments: {right} {strike} {expiry}')
return None
selected_contract = sorted_by_strike[0]
self.AddOptionContract(selected_contract, Resolution.Minute)
self.Debug("Contract Strike Price: " + str(selected_contract.ID.StrikePrice))
return selected_contract
def select_contracts(self, symbol, opening):
# Alex: I moved GetOptionContractList outside select_option so we call it just one
# then we pass the results to select_option to filter
# list of symbols (tickers) for each available contract
contract_symbols = self.OptionChainProvider.GetOptionContractList(symbol, self.Time)
if not contract_symbols:
self.Log(f'GetOptionContractList returned an empty list on {self.Time}')
return None, None
open_price = math.floor(opening)
put_strike = open_price - 1
put_expiry = self.Time
call_strike = open_price + 1
call_expiry = self.Time
countCall = len([x for x in contract_symbols if x.ID.OptionRight == OptionRight.Call])
countPut = len([x for x in contract_symbols if x.ID.OptionRight == OptionRight.Put])
self.Debug(f"SPY open price: {open_price}. Available contracts: {len(contract_symbols)} Call: {countCall} Put: {countPut}")
selected_call_symbol = self.select_option(contract_symbols, OptionRight.Call, call_strike, call_expiry)
selected_put_symbol = self.select_option(contract_symbols, OptionRight.Put, put_strike, put_expiry)
return selected_call_symbol, selected_put_symbol
#def BeforeMarketClose(self):
#self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday),
#self.TimeRules.BeforeMarketClose("QQQ", 1), self.BeforeMarketClose)
#self.Liquidate()
def Outright_exit_loss(self):
sold = []
for symbol, contracts in self.allContracts.items():
if len(contracts) < 1:
continue
if contracts[0] == None or contracts[1] == None:
continue
if (self.Portfolio[contracts[0]].UnrealizedProfitPercent + self.Portfolio[contracts[1]].UnrealizedProfitPercent) >=.25:
self.Liquidate()
self.Debug("target hit")
sold.append(symbol)
for symbol in sold:
self.allContracts[symbol] = []
# if self.symbol_put == None or self.symbol_call == None:
# return
# trading_size = self.position_dollar_size
# if self.TotalUnrealizedProfit // trading_size >= abs(.1):
# if self.Portfolio[self.symbol_call].Quantity == self.quantity_call and self.Portfolio[self.symbol_put].Quantity == self.quantity_put:
# self.Liquidate()
# self.Debug("outright loss hit")
# portfolio_profit = self.Securities[self.symbol_call].Holdings.UnrealizedProfitPercent + self.Securities[self.symbol_call].Holdings.UnrealizedProfitPercent
''' It might be better to use the self.Portfolio object for profit percent on the portfolio rather than self.Securities, due to position weighting '''
#portfolio_profit = self.Portfolio.TotalUnrealizedProfit
#self.Debug("PORT " + str(portfolio_profit))
#if portfolio_profit == -.10:
#if self.Portfolio[self.symbol_call].Quantity == self.quantity_call and self.Portfolio[self.symbol_put].Quantity == self.quantity_put:
#self.Liquidate()
#self.Debug("outright loss hit")
def UpdateATH(self):
for symbol in self.symbols:
high = self.Securities[symbol].High
self.Debug(str(symbol.Value) + " HIGH: " + str(high) + ". ATH: " + str(self.allAth[symbol]))
if high > self.allAth[symbol]:
self.allAth[symbol] = high
#def TakeProfits(self):
#self.Total_Port_Value = self.Portofolio.TotalPortfolioValue