market order of | 69.0 SPY sell | with status error did not go through. The following error occured: {“code”:40310000,“existing_order_id”:“96d0e1e0-2dd1-4d88-a661-eea1aabf31d2”,“message”:“potential wash trade detected. use complex orders”,“reject_reason”:“opposite side market/stop order exists”}
I am doing paper trading
@python_stuff The order is being rejected because it could result in a a ‘wash trade’. A was trade (not to be confused with a wash sale) is when one trades with oneself. This is when one’s buy order fills against one’s sell order. The SEC looks very unfavorably on that and imposes harsh penalties for repeat offenders.
Because of that, Alpaca puts in place protections which reject any order where there is an existing open order having the opposite side. In general, one’s algo should be either increasing a position or decreasing a position (ie buying or selling) and not be doing those simultaneously.
In this specific case, you are trying to sell SPY while at the same time have an existing stop order to buy SPY. That could result in a wash trade and is therefore rejected.
I do not have a stop order
sell:
order = self.create_order(
self.symbol,
quantity,
“sell”,
,
)
buy:
order = self.create_order(
self.symbol,
quantity,
“buy”,
type=“market”,
)
could I use self.sell_all()
@Dan_Whitnable_Alpaca , also I can buy sell from alpaca the second it says sell rejected on my screen
@python_stuff I may have misinterpreted the error which was received, but fundamentally, if you are submitting a sell order, ensure there is not an existing buy order open. And yes, the open buy and sell orders are real time and the protection logic checks orders in real time.
thank you I will try
My full code
from lumibot.brokers import Alpaca
from lumibot.backtesting import YahooDataBacktesting
from lumibot.strategies.strategy import Strategy
from lumibot.traders import Trader
from datetime import datetime
from alpaca_trade_api import REST
from timedelta import Timedelta
from finbert_utils import estimate_sentiment
from lumibot.backtesting import PandasDataBacktesting, BacktestingBroker
import pandas as pd
import yfinance as yf
API_KEY = "PKMMVS2BIGSY6IS3QQTT"
API_SECRET = "hqXKKFibOkomIqlfNfRtKY0xJ1Kyr6fjNklVgNFy"
BASE_URL = "https://paper-api.alpaca.markets"
from lumibot.entities import Asset, Data
ALPACA_CREDS = {
"API_KEY":API_KEY,
"API_SECRET": API_SECRET,
"PAPER": True
}
import time
class MLTrader(Strategy):
def initialize(self, symbol:str="SPY", cash_at_risk:float=.1):
self.symbol = symbol
self.sleeptime = "5M"
self.last_trade = None
self.cash_at_risk = cash_at_risk
self.api = REST(base_url=BASE_URL, key_id=API_KEY, secret_key=API_SECRET)
self.q1 = 0
self.si=0
def position_sizing(self):
cash = self.get_cash()
last_price = self.get_last_price(self.symbol)
quantity = round(cash * self.cash_at_risk / last_price,0)
return cash, last_price, quantity
def before_market_closes(self):
self.minutes_before_closing=1
self.sell_all()
def is_doji(open, high, low, close):
body_size = abs(close - open)
upper_shadow = high - max(open, close)
lower_shadow = min(open, close) - low
return body_size < 0.1 * max(body_size, upper_shadow, lower_shadow)
def is_hammer(open, high, low, close):
body_size = abs(close - open)
upper_shadow = high - max(open, close)
lower_shadow = min(open, close) - low
return (lower_shadow >= 2 * body_size) and (upper_shadow <= 0.1 * body_size)
def is_inverted_hammer(open, high, low, close):
body_size = abs(close - open)
upper_shadow = high - max(open, close)
lower_shadow = min(open, close) - low
return (upper_shadow >= 2 * body_size) and (lower_shadow <= 0.1 * body_size)
def is_shooting_star(open, high, low, close):
body_size = abs(close - open)
upper_shadow = high - max(open, close)
lower_shadow = min(open, close) - low
return (upper_shadow >= 2 * body_size) and (lower_shadow >= 2 * body_size)
def is_morning_star(row):
if len(row) != 3:
return False
first = row.iloc[0]
second = row.iloc[1]
third = row.iloc[2]
# Bullish reversal pattern
if first['Close'] > first['Open'] and third['Close'] > third['Open']:
# First candle is a long bearish candle
if first['Close'] - first['Open'] > 2 * (first['High'] - first['Low']):
# Third candle is a bullish candle
if third['Close'] - third['Open'] > 0 and third['Open'] < first['Close'] and third['Close'] > first['Open']:
# Second candle is a small-bodied candle, often with a gap down
if second['High'] < first['Low'] and second['Low'] > third['Close']:
return True
return False
def is_evening_star(row):
if len(row) != 3:
return False
first = row.iloc[0]
second = row.iloc[1]
third = row.iloc[2]
# Bearish reversal pattern
if first['Close'] < first['Open'] and third['Close'] < third['Open']:
# First candle is a long bullish candle
if first['Open'] - first['Close'] > 2 * (first['High'] - first['Low']):
# Third candle is a bearish candle
if third['Open'] - third['Close'] > 0 and third['Close'] < first['Open'] and third['Open'] > first['Close']:
# Second candle is a small-bodied candle, often with a gap up
if second['Low'] > first['High'] and second['High'] < third['Open']:
return True
return False
# def is_red_candle(self,row):
# return float(row['Close']) < float(row['Open'])
# def is_green_candle(self,row):
# return float(row['Close']) > float(row['Open'])
# def swinghigh(row,df,max_index,min_index,index,row_before,row_after,self):
# try:
# if max_index>index > min_index:
# if row_before['High']<row['High']:
# if row_after['High']<row['High']:
# return True
# except:
# pass
# def swinglow(row,df,min_index,max_index,index,row_before,row_after,self):
# try:
# if max_index>index > min_index:
# if row_before['High']>row['High']:
# if row_after['High']>row['High']:
# return True
# except:
# pass
def on_trading_iteration(self):
stock = yf.Ticker(self.symbol)
historical_prices = stock.history(period='1d', interval='5m')
# print(historical_prices)
df = pd.DataFrame(historical_prices)
df['index'] = df.reset_index().index
df['Candlestick_Close'] = df['Close'] - df['Open']
# # Save the dataframe to a CSV file
df.to_csv('hs.csv')
# # Get the latest price and time
# latest_price = historical_prices['High'].iloc[-3]
# print(latest_price)
df = pd.read_csv('hs.csv')
cash, last_price, quantity = self.position_sizing()
# # Get the data of the stock
if cash > last_price:
print("h")
if len(df) >= 3:
print("ih")
# # Get the historical prices for Apple stock
# Initialize a list to store the data of the candles
green_candles_data = []
red_candles_data = []
# Calculate candlestick closes
# Initialize a counter for consecutive green candlesticks
consecutive_green = 0
red = 0
# Iterate through each row in the DataFrame
for index, row in df.iloc[self.si:].iterrows():
print(self.si)
self.si+=1
index=row['index']
try:
row_before = df.iloc[index - 1] # Row before
row_after = df.iloc[index + 1]
except:
pass
min_index = df['index'].idxmin()
max_index = df['index'].idxmax()
prev_candles = df.iloc[max(0, index - 3):index]
body_size = abs(row['Close'] - row['Open'])
upper_shadow = row['High'] - max(row['Open'], row['Close'])
lower_shadow = min(row['Open'], row['Close']) - row['Low']
try:
if max_index>index > min_index:
if row_before['High']<row['High']:
if row_after['High']<row['High']:
print("singhigh")
oorder = self.create_order(
self.symbol,
self.q1,
"sell")
self.submit_order(oorder)
self.q1=0
if row_before['High']>row['High']:
if row_after['High']>row['High']:
print("singlow")
#for candle_data in green_candles_data:
# print(candle_data)
order = self.create_order(
self.symbol,
quantity,
"buy"
)
self.q1+=quantity
self.submit_order(order)
time.sleep(1)
# print("Buy")
# print(row_before['Datetime'],row['Datetime'],row_after['Datetime'])
except:
pass
#print("ihf")
# If the candlestick close is positive (green)
if row['Candlestick_Close'] > 0:
# Increment the counter
consecutive_green += 1
red=0
red_candles_data.clear()
# Append the data of the green candle to the list
green_candles_data.append(row)
elif row['Candlestick_Close'] < 0:
# Increment the counter
red += 1
consecutive_green = 0
green_candles_data.clear()
# Append the data of the green candle to the list
red_candles_data.append(row)
else:
green_candles_data.clear()
# Reset the counter and clear the list if the candlestick is not green
consecutive_green = 0
red=0
# if self.is_red_candle(row_before) and self.is_green_candle(row_after):
# if body_size < 0.1 * max(body_size, upper_shadow, lower_shadow):
# #for candle_data in green_candles_data:
# # print(candle_data)
# order = self.create_order(
# self.symbol,
# quantity,
# "buy",
# type="market"
# )
# self.q1+=quantity
# self.submit_order(order)
# if self.is_green_candle(row_before) and self.is_red_candle(row_after):
# if body_size < 0.1 * max(body_size, upper_shadow, lower_shadow):
# oorder = self.create_order(
# self.symbol,
# self.q1,
# "sell")
# self.submit_order(oorder)
# self.q1=0
# if all(self.is_red_candle(prev) for prev in prev_candles[:3]):
# if (lower_shadow >= 2 * body_size) and (upper_shadow <= 0.1 * body_size):
# #for candle_data in green_candles_data:
# # print(candle_data)
# order = self.create_order(
# self.symbol,
# quantity,
# "buy",
# type="market"
# )
# self.q1+=quantity
# self.submit_order(order)
# if all(self.is_red_candle(prev) for prev in prev_candles[:3]):
# if (upper_shadow >= 2 * body_size) and ( lower_shadow <= 0.1 * body_size):
# #for candle_data in green_candles_data:
# # print(candle_data)
# order = self.create_order(
# self.symbol,
# quantity,
# "buy",
# type="market"
# )
# self.q1+=quantity
# self.submit_order(order)
# if all(self.is_green_candle(prev) for prev in prev_candles[:3]):
# if (upper_shadow >= 2 * body_size) and (lower_shadow >= 2 * body_size):
# oorder = self.create_order(
# self.symbol,
# self.q1,
# "sell")
# self.submit_order(oorder)
# self.q1=0
# If we have three consecutive green candlesticks
if consecutive_green >= 3:
#print("Three consecutive green candlesticks found:")
# Print the data of the green candles
# Calculate the difference between the high of the first candle and the low of the third candle
high_first_candle = green_candles_data[0]['High']
low_third_candle = green_candles_data[2]['Low']
difference = low_third_candle-high_first_candle
# print(f"Difference between the high of the first candle and the low of the third candle: {difference}")
# If the difference is positive, print "buy"
if difference > (last_price*0.025):
#for candle_data in green_candles_data:
# print(candle_data)
order = self.create_order(
self.symbol,
quantity,
"buy"
)
self.q1+=quantity
self.submit_order(order)
consecutive_green = consecutive_green-1
green_candles_data.pop(0)
time.sleep(1)
else:
consecutive_green = consecutive_green-1
green_candles_data.pop(0)
elif red >= 3:
#print("Three consecutive red candlesticks found:")
# Print the data of the green candles
# Calculate the difference between the high of the first candle and the low of the third candle
low_first_candle = red_candles_data[0]['Low']
high_third_candle = red_candles_data[2]['High']
ddifference = low_first_candle-high_third_candle
#print(f"Difference between the high of the first candle and the low of the third candle: {ddifference}")
# If the difference is positive, print "buy"
if ddifference > (last_price*0.025):
# for ccandle_data in red_candles_data:
#print(ccandle_data)
oorder = self.create_order(
self.symbol,
self.q1,
"sell")
self.submit_order(oorder)
self.q1=0
red = red-1
red_candles_data.pop(0)
else:
red = red-1
red_candles_data.pop(0)
broker = Alpaca(ALPACA_CREDS)
strategy = MLTrader(name='mlstrat', broker=broker,
parameters={"symbol":"SPY",
"cash_at_risk":.1})
# strategy.backtest(
# YahooDataBacktesting,
# datetime(2024,2,12),
# datetime(2024,3,12),
# parameters={"symbol":"SPY", "cash_at_risk":.1}
# )
trader = Trader()
trader.add_strategy(strategy)
trader.run_all()```
still the same error
@python_stuff Quickly looking a the code, there doesn’t seem to be anything either implicitly or explicitly keeping the algo from submitting a sell order while there is an existing buy order (or vice versa). Another issue you will probably have at some time is the position_sizing
function doesn’t look at buying power. There is the potential you may try to open a position but not have enough buying power.
i fixed it was because there was a buy order open I just had to put time.sleep(2) before the order was created