declare hide_on_intraday; # trade modifiers input wait_time = 10; input per_trade_cash = 100; input max_trade_cash = 1000; input buy_trigger = low; input sell_trigger = high; input buy_time = close; # display modifiers input show_profit_loss = no; input show_daily = no; input show_orders = no; input show_position = no; input show_avg_trade_price = no; input show_cash = no; input show_realized_PL = no; # event modifiers input apply_drop = no; input drop_percentage = 10; input event_percent_change = 50; input time_frame = 60; input percent_from_line = 15; #===================================================================================================== # Event identifier # # Purpose # - Determine events and remove exceptions # - Set base/rebound line # - Track time between events # - Locate reoccuring events # - Locate rebound events #===================================================================================================== def agg = AggregationPeriod.DAY; def best_change = ((Highest(high(period = agg), 2) / close(period = agg)[2]) - 1) * 100; def condition_v1 = best_change >= event_percent_change or best_change >= 100; def date_count_v1 = if condition_v1[1] == 1 then 1 else date_count_v1[1] + 1; def condition_v2 = if condition_v1 == 1 then if date_count_v1 <= 5 then 0 else 1 else 0; def date_count_v2 = if condition_v2[1] == 1 then 1 else date_count_v2[1] + 1; def base_v1 = if condition_v2 == 1 then Lowest(low, 4) else base_v1[1]; def condition_final = if condition_v2 == 1 then if low[1] >= base_v1[1] * 1.8 then if date_count_v2 >= 80 then 1 else if base_v1[1] == 0 then 1 else 0 else 1 else 0; def date_count_final = if condition_final[1] == 1 then 1 else date_count_final[1] + 1; def base_final = if condition_final == 1 then Lowest(low, 4) else if date_count_final == 60 and apply_drop == yes then base_final[1] * (1 - (drop_percentage / 100)) else base_final[1]; def continuation = if condition_final == 1 then if date_count_final <= time_frame then 1 else 0 else 0; def rebound_event = if condition_final == 1 then if AbsValue(base_final[1] - open(period = agg)[1]) <= base_final[1] * (percent_from_line / 100) then 1 else 0 else 0; def rebound_continuation = if rebound_event == 1 then if date_count_final <= time_frame then 1 else 0 else 0; #===================================================================================================== # Plotting for study on a daily aggregation period # # Purpose: # - plot arrow to indicate events # - plot rebound line #===================================================================================================== plot event_arrow = condition_final; event_arrow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN); event_arrow.SetHiding(!show_daily); plot rebound_line = base_final; rebound_line.SetDefaultColor(GetColor(4)); rebound_line.SetHiding(!show_daily); rebound_line.HideBubble(); #===================================================================================================== # Strategy #===================================================================================================== # Calculate orders and profit loss # note this does not account for a stock that is just going up and down, if this happens then there will just be a bunch of orders # Purpose: # - set conditions to place buy and sell orders # - track position size (number of shares) # - track total cash (quantity of money invested) used to limit how much money can be invested # - track average price of position #===================================================================================================== def buy_order_condition = Average(buy_trigger, 3); def sell_order_condition = sell_trigger; def ultimate_buy_condition = if date_count_final <= wait_time then 0 else if close <= 0.85 * base_final then 0 else 1; def base_p100 = base_final * 2.00; def base_p40 = base_final * 1.40; def base_p25 = base_final * 1.30; def base_p20 = base_final * 1.20; def base_p15 = base_final * 1.15; def base_p10 = base_final * 1.10; def base_p05 = base_final * 1.05; def base_n025 = base_final * 0.975; def base_n10 = base_final * 0.90; def base_n20 = base_final * 0.8; def buy_condition; if Crosses(sell_order_condition, base_p100, CrossingDirection.ABOVE) then { buy_condition = -5; } else if Crosses(sell_order_condition, base_p40, CrossingDirection.ABOVE) then { buy_condition = -4; } else if Crosses(sell_order_condition, base_p25, CrossingDirection.ABOVE) then { buy_condition = -3; } else if Crosses(sell_order_condition, base_p20, CrossingDirection.ABOVE) then { buy_condition = -2; } else if Crosses(sell_order_condition, base_p15, CrossingDirection.ABOVE) then { buy_condition = -1; } else if Crosses(sell_order_condition, base_n10, CrossingDirection.BELOW) then { buy_condition = -1; } else if Crosses(sell_order_condition, base_n20, CrossingDirection.BELOW) then { buy_condition = -5; # following are for buy orders } else if Crosses(buy_order_condition, base_p10, CrossingDirection.BELOW) and ultimate_buy_condition then { buy_condition = 1; } else if Crosses(buy_order_condition, base_p05, CrossingDirection.BELOW) and ultimate_buy_condition then { buy_condition = 2; } else if Crosses(buy_order_condition, base_final, CrossingDirection.ANY)and ultimate_buy_condition then { buy_condition = 3; } else if Crosses(buy_order_condition, base_n025, CrossingDirection.ANY) and ultimate_buy_condition then { buy_condition = 4; } else { buy_condition = 0; } def revised_buy_condition = if best_change >= 15 and buy_condition > 0 then 0 else buy_condition; def position = if revised_buy_condition == 1 then position[1] + RoundDown(per_trade_cash / buy_time, 0) else if revised_buy_condition == 2 then position[1] + RoundDown(per_trade_cash / buy_time, 0) else if revised_buy_condition == 3 then position[1] + RoundDown(per_trade_cash / buy_time, 0) else if revised_buy_condition == 4 then position[1] + RoundDown(per_trade_cash * 1.5 / buy_time, 0) else if revised_buy_condition == -1 then position[1] - RoundDown(position[1] * .5, 0) else if revised_buy_condition == -2 then position[1] - RoundDown(position[1] * .25, 0) else if revised_buy_condition == -3 then position[1] - RoundDown(position[1] * .15, 0) else if revised_buy_condition == -4 then 0 else if revised_buy_condition == -5 then 0 else position[1]; def final_buy_condition = if revised_buy_condition >= 0 then revised_buy_condition else if position[1] == 0 then 0 else revised_buy_condition; def avg_trade_price = if position == 0 then 0 else if final_buy_condition > 0 then (position[1] * avg_trade_price[1] + (position - position[1]) * buy_time) / position else avg_trade_price[1]; def total_cash = position * avg_trade_price; #===================================================================================================== # Plot orders for strategy # # Purpose: # - plot buy order indicated by a green wedge # - plot sell order indicated by a red wedge # - plot profit/loss diagram #===================================================================================================== plot buys = if (position[1] - position) < 0 then 1 else 0; buys.SetDefaultColor(GetColor(6)); buys.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_DOWN); buys.sethiding(!show_orders); plot sells = if (position[1] - position) > 0 then 1 else 0; sells.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_DOWN); sells.SetDefaultColor(GetColor(5)); sells.sethiding(!show_orders); #===================================================================================================== # Profit/Loss diagram # # Purpose: # - plot profit/loss diagram # - plot trade related figures (position, average trade price, realized profit loss) #===================================================================================================== def finalized_trade = if (position[1] - position) > 0 then (position[1] - position) * (close - avg_trade_price[1]) + finalized_trade[1] else finalized_trade[1]; def p_l = if position[1] == 0 then finalized_trade else (close - avg_trade_price) * position + finalized_trade; plot profit_loss = p_l; profit_loss.SetPaintingStrategy(paintingStrategy.SQUARED_HISTOGRAM); profit_loss.AssignValueColor(if final_buy_condition != 0 then if p_l > 0 then Color.GREEN else Color.RED else if p_l > 0 then Color.DARK_GREEN else Color.DARK_RED); profit_loss.hideBubble(); profit_loss.sethiding(!show_profit_loss); plot my_avg_trade_price = avg_trade_price; my_avg_trade_price.sethiding(!show_avg_trade_price); plot my_position = position; my_position.sethiding(!show_position); plot my_cash = total_cash; my_cash.sethiding(!show_cash); plot my_realized = finalized_trade; my_realized.sethiding(!show_realized_PL); #===================================================================================================== # Create variables used to be referenced in a scan # # Purpose: # - proximity to previous base on the day of an event #===================================================================================================== def criteria1 = average(volume,50) > 5000; def criteria2 = close >= .10 and close <= 30; def criteria3 = sum(condition_final,253) >= 5; def scan1 = criteria1 and criteria2 and criteria3; def criteria4 = lowest(p_l,253) < 0; def scan2 = criteria1 and criteria2 and criteria4;