| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
from AlgorithmImports import *
COINS = ["1INCH", "AAVE", "ADA", "ALGO", "AMPL", "ATOM", "AVAX", "BCHN", "BSV", "BTC", "COMP", "DAI", "DASH", "DOGE", "DOT",
"DUSK", "EGLD", "EOS", "ETC", "ETH", "FIL", "FTM", "ICP", "IOTA", "LEO", "LINK", "LTC", "LUNA", "MANA", "MKR",
"NEAR", "NEO", "OMG", "PNK", "REQ", "SOL", "SUSHI", "TERRAAUST", "TRX", "UNI", "VET", "XAUT", "XDC", "XLM",
"XMR", "XRP", "XTZ", "YFI", "ZEC", "ZRX"]
CURRENCY = "USD"
STOPLOSS = 10 # %
WAIT = 10 # Seconds
LIMIT_BUY_LONG = 1.000
LIMIT_SELL_LONG = 1.001
LIMIT_SELL_SHORT = 1.0005
LIMIT_BUY_SHORT = 0.999
THRESHOLD = 95 # %
SMA_PERIOD = 30
POSITION = 100
# region imports
from AlgorithmImports import *
import config
from datetime import *
# endregion
class FatSkyBlueLeopard(QCAlgorithm):
def Initialize(self):
# self.SetStartDate(2022, 5, 1) # Set Start Date
# self.SetEndDate(2022, 7, 1)
self.SetStartDate(2022, 6, 1) # Set Start Date
self.SetEndDate(2022, 7, 1)
self.SetCash("USD", 10000) # Binance doesnt have USD pairs, so the account needs to have USDT currency to trade
# self.SetCash("USDT", 10000) # Set Strategy Cash
self.SetBrokerageModel(BrokerageName.Bitfinex, AccountType.Margin)
# self.SetSecurityInitializer(lambda security: security.SetMarketPrice(self.GetLastKnownPrice(security)))
self.SetSecurityInitializer(self.CustomSecurityInitializer)
# self.Portfolio.MarginCallModel = MarginCallModel.Null
self.DefaultOrderProperties = BitfinexOrderProperties()
self.DefaultOrderProperties.TimeInForce = TimeInForce.GoodTilCanceled
self.DefaultOrderProperties.PostOnly = False
self.symbols = []
self.DataBySymbol = {}
Pairs = [x + config.CURRENCY for x in config.COINS]
for Pair in Pairs:
# self.Debug("HERE")
try:
self.symbols.append(self.AddCrypto(Pair, Resolution.Second, Market.Bitfinex).Symbol)
except:
if Pair in self.DataBySymbol.keys():
symbolData = self.DataBySymbol.pop(Pair, None)
self.SubscriptionManager.RemoveConsolidator(Pair, symbolData.Bar_Consolidator)
self.SubscriptionManager.RemoveConsolidator(Pair, symbolData.Calculation_Call)
continue
def CustomSecurityInitializer(self, security):
# self.Debug(self.Time)
security.SetMarketPrice(self.GetLastKnownPrice(security))
security.MarginModel = SecurityMarginModel(3.3)
security.SetFeeModel(ConstantFeeModel(0))
def OnData(self, data: Slice):
for symbol in self.symbols:
if not symbol in self.DataBySymbol:
history = map(lambda x: x[symbol], self.History(timedelta(40), Resolution.Minute)) #self.History(symbol, 40, Resolution.Minute)
self.DataBySymbol[symbol] = SymbolData(self, symbol, history)
# if data.ContainsKey(symbol) and self.CurrentSlice.Bars.ContainsKey(symbol):
# symbolData = self.DataBySymbol[symbol]
# if not self.Portfolio[symbol].Invested:
# quantity = 100/self.Securities[symbol].Close
# symbolData.ticket = self.MarketOrder(symbol, quantity)
for symbol in self.DataBySymbol:
symbolData = self.DataBySymbol[symbol]
symbolData.OrderHandler(data)
def OnOrderEvent(self, orderEvent: OrderEvent):
# self.Debug("ORDEREVENT")
order = self.Transactions.GetOrderById(orderEvent.OrderId)
for symbol in self.DataBySymbol:
if orderEvent.Symbol == symbol:
if orderEvent.Status == OrderStatus.Filled:
symbolData = self.DataBySymbol[symbol]
symbolData.OnOrderEvent(orderEvent)
# if orderEvent.Status == OrderStatus.Filled:
# self.Debug("{0}: {1}: {2}".format(self.Time, order.Type, orderEvent))
# def OnEndOfAlgorithm(self):
# for symbol in self.DataBySymbol:
# symbolData = self.DataBySymbol[symbol]
# self.Debug(f" {symbol} {symbolData.Orders_Sent}")
class SymbolData():
def OnOrderEvent(self, orderEvent: OrderEvent):
# self.Debug("ORDEREVENT")
order = self.Transactions.GetOrderById(orderEvent.OrderId)
def __init__(self, algorithm, symbol, history):
self.algorithm = algorithm
self.symbol = symbol
# self.data = data
# self.algorithm.Debug(algorithm.Securities[self.symbol].Price)
self.sma = SimpleMovingAverage(config.SMA_PERIOD)
algorithm.WarmUpIndicator(self.symbol, self.sma, timedelta(minutes=1))
self.count = 0
# self.OrderHandler(data)
self.Stop_Loss_Long = (1-(config.STOPLOSS/100))
self.Stop_Loss_Short = (1+(config.STOPLOSS/100))
self.Wait_After_Order = config.WAIT
self.Threshold = config.THRESHOLD/100
self.Order_Sent_Time = None
self.Limit_Sell_Time = None
self.Limit_Buy_Time_Short =None
self.Current_Order = None
self.Unfilled_Limit_Buy_Order = False
self.Unfilled_Limit_Sell_Order = False
self.Unfilled_Limit_Sell_Order_Short = False
self.Limit_Price_Buy_Long = None
self.Limit_Price_Sell_Long = None
self.Limit_Buy_Long = config.LIMIT_BUY_LONG
self.Limit_Sell_Long = config.LIMIT_SELL_LONG
self.Remaining_Quantity_Lmt_Buy_Long = None
self.Remaining_Quantity_Lmt_Sell_Short = None
self.Minimum_Order_Size = self.algorithm.Securities[self.symbol].SymbolProperties.MinimumOrderSize
self.symbol.ticket_LmtBuy = None
self.symbol.ticket_LmtSell = None
self.symbol.ticket_Stop_Long = None
self.symbol.ticket_LmtSell_Short = None
self.symbol.ticket_LmtBuyShort = None
self.symbol.ticket_Stop_Short = None
self.Long_Stop = None
self.Short_Stop = None
self.my_quantity = None
self.Abs_Long_Buy = None
self.Average_Long_Buy = None
self.Long_Fill_Distance_LmtBuy = None
self.Abs_Long_Sell = None
self.Average_Long_Sell = None
self.Long_Fill_Distance_LmtSell = None
self.Abs_Short_Sell = None
self.Average_Short_Sell = None
self.Short_Fill_Distance_LmtSell = None
self.Abs_Short_Cover = None
self.Average_Short_Cover = None
self.Short_Fill_Distance_Cover = None
self.symbol.ticket_switch_short = None
self.symbol.ticket_switch_long = None
# self.Order_Status_List = [OrderStatus.New, OrderStatus.]
self.Limit_Buy_Short= config.LIMIT_BUY_SHORT
self.Limit_Sell_Short = config.LIMIT_SELL_SHORT
# self.Order_Quantity = config.ORDER_QUANTITY_IN_USDT
self.Current_SMA = None
self.Current_Ask = None
self.Current_Bid = None
self.Minimum_Order_Size = None
self.Orders_Sent = 0
self.Bar_Consolidator = TradeBarConsolidator(timedelta(minutes=1))
algorithm.SubscriptionManager.AddConsolidator(symbol, self.Bar_Consolidator)
self.Bar_Consolidator.DataConsolidated += self.OnDataConsolidated
# for bar in history:
# # if symbol == row.Index[0]:
# bar = TradeBar(bar.EndTime - timedelta(minutes=1), symbol, bar.Open, bar.High, bar.Low, bar.Close, 10000, bar.Period)
# self.Bar_Consolidator.Update(bar)
# def OnOrderEvent(self, orderEvent: OrderEvent):
# self.Debug("ORDEREVENT")
# order = self.Transactions.GetOrderById(orderEvent.OrderId)
# if orderEvent.Status == OrderStatus.Filled:
# self.Debug("{0}: {1}: {2}".format(self.Time, order.Type, orderEvent))
self.No_Open_Long_Position = True
self.No_Open_Long_Sell_Order = True
self.No_Open_Long_Stop_Order = True
self.No_Open_Long_Buy_Order = True
self.symbol.ticket_Stop_Long = None
self.symbol.ticket_Long_Limit_Sell = None
self.symbol.ticket_Long_Limit_Buy = None
self.No_Open_Short_Position = True
self.No_Open_Short_Buy_Order = True
self.No_Open_Short_Stop_Order = True
self.No_Open_Short_Sell_Order = True
self.symbol.ticket_Stop_Short = None
self.symbol.ticket_Short_Limit_Buy = None
self.symbol.ticket_Short_Limit_Sell = None
if self.symbol == "1INCHUSD":
self.cash_symbol == "1INCH"
if self.symbol == "AAVEUSD":
self.cash_symbol == "AAVE"
if self.symbol == "ADAUSD":
self.cash_symbol == "ADA"
if self.symbol == "ALGOUSD":
self.cash_symbol == "ALGO"
if self.symbol == "AMPLUSD":
self.cash_symbol == "AMPL"
if self.symbol == "ATOMUSD":
self.cash_symbol == "ATOM"
if self.symbol == "AVAXUSD":
self.cash_symbol == "AVAX"
if self.symbol == "BCHNUSD":
self.cash_symbol == "BCHN"
if self.symbol == "BSVUSD":
self.cash_symbol == "BSV"
if self.symbol == "BTCUSD":
self.cash_symbol == "BTC"
if self.symbol == "COMPUSD":
self.cash_symbol == "COMP"
if self.symbol == "DAIUSD":
self.cash_symbol == "DAI"
if self.symbol == "DASHUSD":
self.cash_symbol == "DASH"
if self.symbol == "DOGEUSD":
self.cash_symbol == "DOGE"
if self.symbol == "DOTUSD":
self.cash_symbol == "DOT"
if self.symbol == "DUSKUSD":
self.cash_symbol == "DUSK"
if self.symbol == "EGLDUSD":
self.cash_symbol == "EGLD"
if self.symbol == "EOSUSD":
self.cash_symbol == "EOS"
if self.symbol == "ETCUSD":
self.cash_symbol == "ETC"
if self.symbol == "ETHUSD":
self.cash_symbol == "ETH"
if self.symbol == "FILUSD":
self.cash_symbol == "FIL"
if self.symbol == "FTMUSD":
self.cash_symbol == "FTM"
if self.symbol == "ICPUSD":
self.cash_symbol == "ICP"
if self.symbol == "IOTAUSD":
self.cash_symbol == "IOTA"
if self.symbol == "LEOUSD":
self.cash_symbol == "LEO"
if self.symbol == "LINKUSD":
self.cash_symbol == "LINK"
if self.symbol == "LTCUSD":
self.cash_symbol == "LTC"
if self.symbol == "LUNAUSD":
self.cash_symbol == "LUNA"
if self.symbol == "MANAUSD":
self.cash_symbol == "MANA"
if self.symbol == "MKRUSD":
self.cash_symbol == "MKR"
if self.symbol == "NEARUSD":
self.cash_symbol == "NEAR"
if self.symbol == "NEOUSD":
self.cash_symbol == "NEO"
if self.symbol == "OMGUSD":
self.cash_symbol == "OMG"
if self.symbol == "PNKUSD":
self.cash_symbol == "PNK"
if self.symbol == "REQUSD":
self.cash_symbol == "REQ"
if self.symbol == "SOLUSD":
self.cash_symbol == "SOL"
if self.symbol == "SUSHIUSD":
self.cash_symbol == "SUSHI"
if self.symbol == "TERRAUSTUSD":
self.cash_symbol == "TERRAAUST"
if self.symbol == "TRXUSD":
self.cash_symbol == "TRX"
if self.symbol == "UNIUSD":
self.cash_symbol == "UNI"
if self.symbol == "VETUSD":
self.cash_symbol == "VET"
if self.symbol == "XAUTUSD":
self.cash_symbol == "XAUT"
if self.symbol == "XDCUSD":
self.cash_symbol == "XDC"
if self.symbol == "XLMUSD":
self.cash_symbol == "XLM"
if self.symbol == "XMRUSD":
self.cash_symbol == "XMR"
if self.symbol == "XRPUSD":
self.cash_symbol == "XRP"
if self.symbol == "XTZUSD":
self.cash_symbol == "XTZ"
if self.symbol == "YFIUSD":
self.cash_symbol == "YFI"
if self.symbol == "ZECUSD":
self.cash_symbol == "ZEC"
if self.symbol == "ZRXUSD":
self.cash_symbol == "ZRX"
##########################################################################################
self.Order_Tag_List = ["LONG BUY", "LONG SELL", "LONG STOP", "SHORT SELL", "SHORT COVER", "SHORT STOP", "UNEXPECTED", "QUANTITY WITHOUT PERMISSION"]
self.User_Cancelled = False
self.Entry_Time_Long = None
self.Entry_Time_Short = None
self.Interval = timedelta(seconds=config.WAIT)
self.Long_Stop_Price = None
self.Order_Permission = True
self.Order_Dictionary = {"LONG BUY" : "NOT PLACED", "LONG SELL" : "NOT PLACED", "LONG STOP" : "NOT PLACED"}
def OnDataConsolidated(self, sender, bar):
self.sma.Update(IndicatorDataPoint(bar.EndTime, bar.Close))
# self.OrderHandler()
def OrderHandler(self, data):
self.Lot_Size = self.algorithm.Securities[self.symbol].SymbolProperties.LotSize
self.Minimum_Order_Size = (self.algorithm.Securities[self.symbol].SymbolProperties.MinimumOrderSize * self.algorithm.Securities[self.symbol].Price)
self.Current_SMA = self.sma.Current.Value
self.Current_Ask = self.algorithm.Securities[self.symbol].AskPrice
self.Current_Bid = self.algorithm.Securities[self.symbol].BidPrice
self.Minimum_Price_Variation = self.algorithm.Securities[self.symbol].SymbolProperties.MinimumPriceVariation
# if not self.Order_Permission:
# if self.cash_symbol in self.algorithm.Portfolio.CashBook:
# quantity = self.algorithm.Portfolio.CashBook[self.cash_symbol].Amount
# if quantity > 0:
# self.algorithm.MarketOrder(self.symbol, -quantity, tag = "QUANTITY WITHOUT PERMISSION")
# if quantity < 0:
# self.algorithm.MarketOrder(self.symbol, abs(quantity), tag = "QUANTITY WITHOUT PERMISSION")
if self.algorithm.Securities[self.symbol].Price > self.Current_SMA:
if self.cash_symbol in self.algorithm.Portfolio.CashBook:
quantity = self.algorithm.Portfolio.CashBook[self.cash_symbol].Amount
if quantity != 0:
return
else:
if self.algorithm.Portfolio[self.symbol].Quantity != 0:
return
if self.Order_Dictionary.get("LONG BUY") == "NOT PLACED":
if self.cash_symbol in self.algorithm.Portfolio.CashBook:
quantity = self.algorithm.Portfolio.CashBook[self.cash_symbol].Amount
if quantity != 0:
self.algorithm.Debug("WTF")
if quantity == 0:
quantity = config.POSITION / (0.99 *(self.Current_Bid * self.Limit_Buy_Long))
entry_price = self.Current_Bid * self.Limit_Buy_Long
quantity = round(quantity, 3)
entry_price = round(entry_price, 5)
if quantity * self.algorithm.Securities[self.symbol].Price > (self.Minimum_Order_Size * 1.0001):
self.algorithm.LimitOrder(self.symbol, quantity, entry_price, tag = "LONG BUY")
self.Order_Permission = False
self.Entry_Time_Long = self.algorithm.Time
self.Order_Dictionary["LONG BUY"] = "PLACED"
else:
quantity = config.POSITION / (0.99 *(self.Current_Bid * self.Limit_Buy_Long))
entry_price = self.Current_Bid * self.Limit_Buy_Long
quantity = round(quantity, 3)
entry_price = round(entry_price, 5)
if quantity > 0 and (quantity * entry_price) > self.Minimum_Order_Size:
self.algorithm.LimitOrder(self.symbol, quantity, entry_price, tag = "LONG BUY")
self.Order_Permission = False
self.Entry_Time_Long = self.algorithm.Time
self.Order_Dictionary["LONG BUY"] = "PLACED"
open_orders = self.algorithm.Transactions.GetOpenOrders(self.symbol)
for Order in open_orders:
if self.Order_Dictionary["LONG BUY"] == "PLACED":
if Order.Status == OrderStatus.Submitted or Order.Status == OrderStatus.PartiallyFilled or Order.Status == OrderStatus.UpdateSubmitted:
if Order.Quantity * self.Current_Bid > self.Minimum_Order_Size and Order.Quantity > 0:
# self.algorithm.Debug(self.algorithm.Time)
if self.algorithm.Time > (self.Entry_Time_Long + self.Interval):
order_tickets = self.algorithm.Transactions.GetOpenOrderTickets(self.symbol)
for order_ticket in order_tickets:
if order_ticket.OrderId == Order.Id:
ticket = order_ticket
entry_price = self.Current_Bid * self.Limit_Buy_Long
entry_price = round(entry_price, 5)
quantity = round(Order.Quantity, 3)
Update_Settings = UpdateOrderFields()
Update_Settings.LimitPrice= entry_price
Update_Settings.Quantity = quantity
Update_Settings.Tag = "LONG BUY"
Update_Order = order_ticket.Update(Update_Settings)
self.Entry_Time_Long = self.algorithm.Time
if Update_Order.IsSuccess:
pass
else:
self.Order_Permission = False
if self.Order_Dictionary["LONG BUY"] == "FILLED":
# self.algorithm.Debug("PERMISSION")
if self.cash_symbol in self.algorithm.Portfolio.CashBook:
# self.algorithm.Debug("IN BOOK")
quantity = self.algorithm.Portfolio.CashBook[self.cash_symbol].Amount
if quantity > 0:
# self.algorithm.Debug("QUANTITY > 0")
exit_price = self.Current_Ask * self.Limit_Sell_Long
exit_price = round(exit_price, 5)
self.algorithm.LimitOrder(self.symbol, -quantity, exit_price, tag = "LONG SELL")
self.Long_Stop_Price = self.algorithm.Portfolio[self.symbol].AveragePrice * self.Stop_Loss_Long
self.Long_Exit_Time = self.algorithm.Time
self.Order_Permission = False
self.Order_Dictionary["LONG BUY"] = "NOT PLACED"
self.Order_Dictionary["LONG SELL"] = "PLACED"
open_orders = self.algorithm.Transactions.GetOpenOrders(self.symbol)
for Order in open_orders:
if self.Order_Dictionary["LONG SELL"] == "PLACED":
if Order.Status == OrderStatus.Submitted or Order.Status == OrderStatus.PartiallyFilled or Order.Status == OrderStatus.UpdateSubmitted:
if ((abs(Order.Quantity)) * self.Current_Ask) > self.Minimum_Order_Size and Order.Quantity < 0:
if self.algorithm.Time > (self.Long_Exit_Time + self.Interval):
order_tickets = self.algorithm.Transactions.GetOpenOrderTickets(self.symbol)
for order_ticket in order_tickets:
if order_ticket.OrderId == Order.Id:
ticket = order_ticket
entry_price = self.Current_Ask * self.Limit_Sell_Long
entry_price = round(entry_price, 5)
quantity = round(Order.Quantity, 3)
Update_Settings = UpdateOrderFields()
Update_Settings.LimitPrice= entry_price
Update_Settings.Quantity = quantity
Update_Settings.Tag = "LONG SELL"
Update_Order = order_ticket.Update(Update_Settings)
self.Long_Exit_Time = self.algorithm.Time
if Update_Order.IsSuccess:
pass
else:
self.Order_Permission = False
if self.Long_Stop_Price is not None:
if self.algorithm.Securities[self.symbol].Price < self.Long_Stop_Price:
quantity = self.algorithm.Portfolio.CashBook[self.cash_symbol].Amount
self.algorithm.MarketOrder(self.symbol, -quantity, tag = "LONG STOP")
self.Order_Permission = False
self.Order_Dictionary["LONG STOP"] == "PLACED"
def OnOrderEvent(self, orderEvent):
order = self.algorithm.Transactions.GetOrderById(orderEvent.OrderId)
open_orders = self.algorithm.Transactions.GetOpenOrders(self.symbol)
# cash_book = self.algorithm.Portfolio.CashBook[self.symbol]
symbol_open_quantity = self.algorithm.Transactions.GetOpenOrdersRemainingQuantity(self.symbol)
if order.Status == OrderStatus.Filled:
if self.Order_Dictionary.get("LONG BUY") == "PLACED":
self.Order_Dictionary["LONG BUY"] = "FILLED"
if self.Order_Dictionary.get("LONG SELL") == "PLACED":
self.Order_Dictionary["LONG SELL"] = "FILLED"
if self.Order_Dictionary.get("LONG STOP") == "PLACED":
self.Order_Dictionary["LONG STOP"] = "FILLED"
self.Order_Permission = True
# if self.cash_symbol in self.algorithm.Portfolio.CashBook:
# quantity = self.algorithm.Portfolio.CashBook[self.cash_symbol].Amount
# if not quantity > 0:
# self.Order_Permission = False
# self.algorithm.Transactions.CancelOpenOrders(self.symbol)
# if quantity > 0:
# self.Order_Permission = True
# if self.cash_symbol not in self.algorithm.Portfolio.CashBook:
# if self.algorithm.Portfolio[self.symbol].Quantity == 0:
# # self.algorithm.Transactions.CancelOpenOrders(self.symbol)
# self.Order_Permission = True
if order.Status == OrderStatus.PartiallyFilled:
if (abs(order.AbsoluteFillQuantity * self.Securities[self.symbol].AskPrice)) < self.Minimum_Order_Size:
self.algorithm.Transactions.CancelOrder(order.Id)
if self.Order_Dictionary.get("LONG BUY") == "PLACED":
self.Order_Dictionary["LONG BUY"] = "FILLED"
if self.Order_Dictionary.get("LONG SELL") == "PLACED":
self.Order_Dictionary["LONG SELL"] = "FILLED"
if self.Order_Dictionary.get("LONG STOP") == "PLACED":
self.Order_Dictionary["LONG STOP"] = "FILLED"
self.User_Cancelled = True
if self.Time > (self.Entry_Time_Long + self.Interval + timedelta(seconds=10)):
self.algorithm.Transactions.CancelOrder(order.Id)
if self.Order_Dictionary.get("LONG BUY") == "PLACED":
self.Order_Dictionary["LONG BUY"] = "FILLED"
if self.Order_Dictionary.get("LONG SELL") == "PLACED":
self.Order_Dictionary["LONG SELL"] = "FILLED"
if self.Order_Dictionary.get("LONG STOP") == "PLACED":
self.Order_Dictionary["LONG STOP"] = "FILLED"
self.User_Cancelled = True