public static void GetStrategyId(FuturesContract futuresContract, Strategy strategy, SignalFile signalFile, SimpleLogger log) { var strategyInfo = from s in StrategyList where s.Name == signalFile.StrategyName select new { s.Id, s.Name, s.Ticker, s.OType, s.Contracts, s.MaxPosition, s.Enabled }; var symbolMaxPosition = from s in StrategyList where s.Ticker == futuresContract.Symbol group s by s.Ticker into sg orderby sg.Key select new { sg.Key, Total = sg.Sum(x => x.MaxPosition) }; foreach (var g in strategyInfo) { strategy.StrategyId = g.Id; strategy.Symbol = g.Ticker; strategy.StrategyName = g.Name; strategy.OrderType = g.OType; strategy.LotSize = g.Contracts; strategy.StrategyMaxPosition = g.MaxPosition; strategy.Status = g.Enabled; foreach (var c in symbolMaxPosition) { strategy.MaxPositionForSymbol = c.Total; } } log.Info($"[STRATEGY INFO] StrategyId:{strategy.StrategyId} StrategyName:{strategy.StrategyName}"); }
private void ValidateParsedDataForTrade(SignalFile signalFile) { const int _max = 1000000; Stopwatch s1 = Stopwatch.StartNew(); DateTime tradeDateTime = Convert.ToDateTime(string.Format("{0:MM-dd-yyyy}", signalFile.TradeDateTime.Trim()), CultureInfo.CurrentCulture); string entryDateTime = tradeDateTime.ToString("MM-dd-yyyy"); if (signalFile.TradeDate == DateToday.Today && entryDateTime == DateToday.Today) { //Map TS symbol to IB symbol and set contract details FuturesContract futuresContract = new FuturesContract(); futuresContract = futures.GetContractDetails(contract, futuresContract, signalFile); //Map TS strategies to strategies defined in application data list Strategy strategy = new Strategy(log); Strategy.GetStrategyId(futuresContract, strategy, signalFile, log); if (InitializeValues(strategy, signalFile)) { //Check if app is connected to IB Api and get current IB positions Positions positions = new Positions(); broker.UpdateIBpositions(strategy, positions, log); //Check last position for strategy in Position_Data table Transactions transactions = new Transactions(); Transactions.CheckLastPositionDataFromDB(transactions, strategy, signalFile, log); //Check if strategy has exceeded maximum position //Tuple MaxTradeFlag, dbPosConflict, strategyCurrentPosition Tuple <bool, bool, int> db = positions.GetMaxPosition(strategy, signalFile, transactions, positions, log, @params); //Display transaction conflict message Transactions.CheckLastTrade(signalFile, transactions, log, positions, db); //Set lot size based on current IB position OrderDetails orderDetails = new OrderDetails(); orderDetails = OrderDetails.GetLotSize(db, orderDetails, strategy, signalFile, positions); //Check if a limit order was never filled at the Broker and cancel any open order(s) //Tuple MaxTradeFlag, dbPosConflict, strategyCurrentPosition if (db.Item2) //db.Item1 || { bool allOpenOrder = false; CancelOpenOrders(strategy, db.Item2, orderDetails, allOpenOrder); } //If trade is for today and less than max position excute order ProcessSignalForTrade(futuresContract, signalFile, orderDetails, strategy, db, log); } } s1.Stop(); string diag = string.Format("Processed Order in: " + (s1.Elapsed.TotalMilliseconds * 1000000 / _max).ToString("0.00 ns")); log.Info(diag); }
private void UpdateDBTables(FuturesContract futuresContract, SignalFile signalFile, OrderDetails orderDetails, Strategy strategy, double limitPrice) { int currentPositionForDB = GetCurrentPositionForDB(orderDetails, strategy); DBFunctions.UpdatePositionDataToDb(log, futuresContract, signalFile, orderDetails, limitPrice); DBFunctions.UpdateStrategyPosition(log, currentPositionForDB, strategy, orderDetails); DBFunctions.CalculateProfitandLoss(log, strategy, signalFile); }
public Controller(EClientSocket clientSocket, SimpleLogger log, Parameters @params, Strategy strategy, Broker broker, Positions positions, FuturesContract futures, Prices prices, Transactions transactions, Slack slack) { this.@params = @params; this.log = log; this.clientSocket = clientSocket; this.strategy = strategy; this.broker = broker; this.futures = futures; this.prices = prices; this.transactions = transactions; this.slack = slack; }
private double GetPrices(FuturesContract futuresContract, SignalFile signalFile, Strategy strategy, OrderDetails orderDetails, Prices prices, Tuple <bool, bool, int> db) { double limitPrice = 0; if (prices.BidPrice > 0 && prices.AskPrice > 0) { limitPrice = GetBrokerLimitPrice(futuresContract, orderDetails, prices, strategy, db, signalFile); } else if (limitPrice <= 0) { limitPrice = GetSignalFileLimitPrice(futuresContract, orderDetails, signalFile, strategy, db); } return(limitPrice); }
private void ProcessSignalForTrade(FuturesContract futuresContract, SignalFile signalFile, OrderDetails orderDetails, Strategy strategy, Tuple <bool, bool, int> db, SimpleLogger log) { if (!db.Item1 && [email protected]) { slack.SendMessageToSlack($"[*{strategy.Symbol} {orderDetails.BuyOrSell}]*\n*{signalFile.LastFileLine}*", @params); //Cancel any open orders bool dbconflict = false; bool allOpenOrder = true; CancelOpenOrders(strategy, dbconflict, orderDetails, allOpenOrder); //Send order to Broker double limitPrice = ExecuteOrder(futuresContract, signalFile, orderDetails, strategy, log, db); //Used to check order status @ Broker //CheckOrderStatus(); //Update db with executed strategy order UpdateDBTables(futuresContract, signalFile, orderDetails, strategy, limitPrice); } }
public static double GetTickSize(FuturesContract futuresContract) { switch (futuresContract.Symbol) { case "ES": return(0.25); case "MES": return(0.25); case "CL": return(0.01); case "GC": return(0.10); case "MGC": return(0.10); case "QM": return(0.025); case "RTY": return(0.10); case "YM": return(1.00); default: return(0.00); } }
public static void UpdatePositionDataToDb(SimpleLogger log, FuturesContract futuresContract, SignalFile signalFile, OrderDetails orderDetails, double limitPrice) { try { var sqlite_conn = CreateConnection(); SQLiteCommand sqlite_cmd; sqlite_cmd = sqlite_conn.CreateCommand(); sqlite_cmd.CommandText = "INSERT INTO Position_Data" + " VALUES ( '" + signalFile.TradeDate + "','" + signalFile.TradeDateTime + "','" + orderDetails.OrderId + "','" + signalFile.StrategyName + "','" + futuresContract.Exchange + "','" + orderDetails.BuyOrSell + "','" + orderDetails.OrderStatus + "'," + limitPrice.ToString("0." + new string('#', 20)) + ");"; int result = sqlite_cmd.ExecuteNonQuery(); if (result > 0) { log.Db("Successfully updated Position_Data table."); } else { log.Db("Failed to update Position_Data table."); } sqlite_conn.Close(); } catch (SQLiteException ex) { log.Trace("Error " + ex.Message.ToString()); log.Trace(ex.StackTrace.ToString()); } }
public static void Main(string[] args) { EWrapperImpl ibClient = new EWrapperImpl(); EClientSocket clientSocket = ibClient.ClientSocket; Console.ForegroundColor = ConsoleColor.DarkGreen; string logo = @" /$$$$$$$ /$$ /$$ /$$$$$$ /$$ /$$ /$$ /$$$$$$ | $$__ $$| $$ | $$ /$$__ $$ |__/ | $$ | $$ |_ $$_/ | $$ \ $$| $$ /$$$$$$ /$$$$$$$| $$ /$$| $$ \__/ /$$$$$$ /$$$$$$ /$$ /$$$$$$ /$$$$$$ | $$ | $$ /$$$$$$$ /$$$$$$$ | $$$$$$$ | $$ /$$__ $$ /$$_____/| $$ /$$/| $$ |____ $$ /$$__ $$| $$|_ $$_/ |____ $$| $$ | $$ | $$__ $$ /$$_____/ | $$__ $$| $$| $$ \ $$| $$ | $$$$$$/ | $$ /$$$$$$$| $$ \ $$| $$ | $$ /$$$$$$$| $$ | $$ | $$ \ $$| $$ | $$ \ $$| $$| $$ | $$| $$ | $$_ $$ | $$ $$ /$$__ $$| $$ | $$| $$ | $$ /$$ /$$__ $$| $$ | $$ | $$ | $$| $$ | $$$$$$$/| $$| $$$$$$/| $$$$$$$| $$ \ $$| $$$$$$/| $$$$$$$| $$$$$$$/| $$ | $$$$/| $$$$$$$| $$ /$$$$$$| $$ | $$| $$$$$$$ /$$ |_______/ |__/ \______/ \_______/|__/ \__/ \______/ \_______/| $$____/ |__/ \___/ \_______/|__/ |______/|__/ |__/ \_______/|__/ | $$ | $$ |__/ "; Console.WriteLine(logo); Console.ResetColor(); Console.Write("BlockShift Trading App"); Console.Write("\n"); Console.Write("DISCLAIMER: USING THIS SOFTWARE AT MY OWN RISK\n"); Console.Write("\n"); try { ConsoleWindow.QuickEditMode(false); Parameters @params = new Parameters(Path.Combine(Environment.CurrentDirectory, "config.conf")); SimpleLogger log = new SimpleLogger(); Slack slack = new Slack(@params); Prices prices = new Prices(log, @params); FuturesContract futures = new FuturesContract(@params); Strategy strategy = new Strategy(log); Broker broker = new Broker(clientSocket, log, @params, slack); Positions positions = new Positions(log, @params, slack); Transactions transactions = new Transactions(log); Controller ctl = new Controller(clientSocket, log, @params, strategy, broker, positions, futures, prices, transactions, slack); broker.ConnectionToBroker(strategy, positions); ctl.Run(); } catch (Exception ex) { Console.Write(ex.Message.ToString()); Console.Write(ex.StackTrace.ToString()); } Console.ReadLine(); }
private double GetSignalFileLimitPrice(FuturesContract futuresContract, OrderDetails orderDetails, SignalFile signalFile, Strategy strategy, Tuple <bool, bool, int> db) { double tick; double limitPrice = signalFile.LimitPrice; switch (strategy.Symbol) { case "QM": tick = FuturesContract.GetTickSize(futuresContract); decimal nearOf = 0.025M; //tick *= (signalFile.EMAAngle < 40 && signalFile.EMAAngle > -40) ? @params.crudeSpread : 4; tick *= (signalFile.Trend < 40) ? @params.crudeSpread : 4; if (orderDetails.BuyOrSell == "BUY") { limitPrice -= tick; } else if (orderDetails.BuyOrSell == "SELL") { limitPrice += tick; } decimal _limitPrice = Convert.ToDecimal(limitPrice); _limitPrice = Precision.UltimateRoundingFunction(_limitPrice, nearOf, 0.49M); limitPrice = Convert.ToDouble(_limitPrice); return(limitPrice); case "MES": tick = FuturesContract.GetTickSize(futuresContract); tick *= (signalFile.EMAAngle <40 && signalFile.EMAAngle> -40) ? @params.sp500Spread : @params.sp500Spread / 2; if (signalFile.Adx < 15) { if (orderDetails.BuyOrSell == "BUY") { limitPrice -= tick; } else if (orderDetails.BuyOrSell == "SELL") { limitPrice += tick; } } return(limitPrice); case "MGC": tick = FuturesContract.GetTickSize(futuresContract); if (signalFile.Adx < 15) { tick *= 1; if (orderDetails.BuyOrSell == "BUY") { limitPrice -= tick; return(limitPrice); } else if (orderDetails.BuyOrSell == "SELL") { limitPrice += tick; return(limitPrice); } } else { tick *= 2; if (orderDetails.BuyOrSell == "BUY") { limitPrice += tick; return(limitPrice); } else if (orderDetails.BuyOrSell == "SELL") { limitPrice -= tick; return(limitPrice); } } break; } return(limitPrice); }
private double GetBrokerLimitPrice(FuturesContract futuresContract, OrderDetails orderDetails, Prices prices, Strategy strategy, Tuple <bool, bool, int> db, SignalFile signalFile) { double tick = FuturesContract.GetTickSize(futuresContract); double limitPrice = 0; switch (strategy.Symbol) { case "QM": //tick *= (db.Item3 == 0 || db.Item3 != 0) ? @params.crudeSpread : 1; //if (signalFile.Macd == 1) //{ // tick *= (signalFile.Trend < 40 && orderDetails.BuyOrSell == "SELL") ? @params.crudeSpread : 4; //} //else if (signalFile.Macd == 2) //{ // tick *= (signalFile.Trend < 40 && orderDetails.BuyOrSell == "SELL") ? @params.crudeSpread : 3; //} //if (signalFile.Macd == -1) //{ // tick *= (signalFile.Trend < 40 && orderDetails.BuyOrSell == "BUY") ? @params.crudeSpread : 4; //} //else if (signalFile.Macd == -2) //{ // tick *= (signalFile.Trend < 40 && orderDetails.BuyOrSell == "BUY") ? @params.crudeSpread : 3; //} if (orderDetails.BuyOrSell == "BUY") { //If Up trend than our bid is spread = 2 and offer is @params.crudeSpread = 5 //tick *= (signalFile.EMAAngle < 40 && signalFile.EMAAngle > -40) ? @params.crudeSpread : 8; tick *= (signalFile.Trend < 40) ? @params.crudeSpread : 4; limitPrice = Math.Min(prices.BidPrice, signalFile.LimitPrice); //prices.BidPrice; limitPrice -= tick; } else if (orderDetails.BuyOrSell == "SELL") { //If Down trend than our offer is spread = 2 and out bid is @params.crudeSpread = 5 //tick *= (signalFile.EMAAngle < 40 && signalFile.EMAAngle > -40) ? @params.crudeSpread : 8; tick *= (signalFile.Trend < 40) ? @params.crudeSpread : 4; limitPrice = Math.Max(prices.AskPrice, signalFile.LimitPrice); //prices.AskPrice; limitPrice += tick; } return(limitPrice); case "MES": //tick *= (db.Item3 == 0 || db.Item3 != 0) ? @params.sp500Spread : 1; //tick *= (signalFile.EMAAngle < 40 && signalFile.EMAAngle > -40) ? @params.sp500Spread : @params.sp500Spread ; tick *= (signalFile.Trend < 40) ? @params.sp500Spread : 5; if (orderDetails.BuyOrSell == "BUY") { limitPrice = Math.Min(prices.BidPrice, signalFile.LimitPrice); limitPrice -= tick; } else if (orderDetails.BuyOrSell == "SELL") { limitPrice = Math.Max(prices.AskPrice, signalFile.LimitPrice); limitPrice += tick; } return(limitPrice); } return(limitPrice); }
private double ExecuteOrder(FuturesContract futuresContract, SignalFile signalFile, OrderDetails orderDetails, Strategy strategy, SimpleLogger log, Tuple <bool, bool, int> db) { Prices prices = new Prices(); prices = prices.StartListener(clientSocket, contract, strategy, prices, log); double limitPrice = GetPrices(futuresContract, signalFile, strategy, orderDetails, prices, db); if (limitPrice <= 0) { limitPrice = signalFile.LimitPrice; log.Warning($"LimitPrice for {strategy.StrategyName} is null using signalFile price {signalFile.LimitPrice}"); } //Use market orders overnight so we don't miss getting filled //string orderType = OverNight(signalFile, db); //if (string.IsNullOrEmpty(orderType)) //{ // orderType = strategy.OrderType; //} Order parent = new Order(); Order openOrder = new Order(); List <Order> orders = new List <Order>(); if (db.Item3 != 0) //If there is a position { //Use market orders overnight so we don't miss getting filled string orderType = OverNight(signalFile, db); //if (string.IsNullOrEmpty(orderType)) //{ // orderType = strategy.OrderType; //} //Close position with market order parent = new Order() { OrderId = OrderDetails.NextOrderId++, Action = orderDetails.BuyOrSell, OrderType = (string.IsNullOrEmpty(orderType) ? strategy.OrderType : orderType), //strategy.OrderType, //"MKT", TotalQuantity = strategy.LotSize, LmtPrice = (orderDetails.BuyOrSell == "SELL") ? prices.BidPrice : prices.AskPrice, //limitPrice, AuxPrice = (orderDetails.BuyOrSell == "SELL") ? prices.BidPrice : prices.AskPrice, //limitPrice, Tif = "GTC", Transmit = true }; openOrder = new Order() { OrderId = OrderDetails.NextOrderId++, Action = orderDetails.BuyOrSell, OrderType = strategy.OrderType, //(strategy.OrderType == "MKT" ? strategy.OrderType : orderType), TotalQuantity = strategy.LotSize, LmtPrice = limitPrice, AuxPrice = limitPrice, Tif = "GTC", Transmit = true }; orders = new List <Order>() { parent, openOrder }; } else { openOrder = new Order() { OrderId = OrderDetails.NextOrderId++, Action = orderDetails.BuyOrSell, OrderType = strategy.OrderType, //(strategy.OrderType == "MKT" ? strategy.OrderType : orderType), TotalQuantity = orderDetails.LotSize, LmtPrice = limitPrice, AuxPrice = limitPrice, Tif = "GTC", Transmit = true }; orders = new List <Order>() { openOrder }; } foreach (Order o in orders) { clientSocket.placeOrder(o.OrderId, contract, o); } orderDetails.OrderId = parent.OrderId.ToString(); orderDetails.OrderStatus = "Submitted"; if (db.Item3 != 0) { log.Signal($"Sent Closing {parent.Action} {parent.OrderType} Order for {strategy.Symbol} LimitPrice:{parent.LmtPrice} LotSize:{parent.TotalQuantity} OrderId:{parent.OrderId}"); log.Signal($"Sent Opening {openOrder.Action} {openOrder.OrderType} Order for {strategy.Symbol} LimitPrice:{openOrder.LmtPrice} LotSize:{openOrder.TotalQuantity} OrderId:{openOrder.OrderId}"); } else { log.Signal($"Sent Opening {openOrder.Action} {openOrder.OrderType} Order for {strategy.Symbol} LimitPrice:{openOrder.LmtPrice} LotSize:{openOrder.TotalQuantity} OrderId:{openOrder.OrderId}"); } OrderDetails.OrderIdList.DataList.Add(orderDetails.OrderId); return(limitPrice); }
//public string OrderType { get; set; } //public int MaxPosition { get; set; } //public int LotSize { get; set; } public FuturesContract GetContractDetails(Contract contract, FuturesContract futuresContract, SignalFile signalFile) { if (signalFile.Symbol.Contains("ES")) { signalFile.Symbol = "ES"; //switch (signalFile.StrategyName) //{ // case "MES TMA_Slope Kase Bar 3.75": contract.LocalSymbol = string.Empty; contract.Symbol = "MES"; //MES ***USE MICRO CONTRACT FOR GO LIVE contract.SecType = @params.sp500SecType; contract.LastTradeDateOrContractMonth = @params.sp500Expiry; contract.Exchange = @params.sp500Exchange; contract.Currency = @params.sp500Currency; futuresContract.Symbol = contract.Symbol; futuresContract.Exchange = @params.sp500Exchange; //break; //default: // contract.LocalSymbol = string.Empty; // contract.Symbol = signalFile.Symbol; //MES ***USE MICRO CONTRACT FOR GO LIVE // contract.SecType = @params.sp500SecType; // contract.LastTradeDateOrContractMonth = @params.sp500Expiry; // contract.Exchange = @params.sp500Exchange; // contract.Currency = @params.sp500Currency; // Symbol = contract.Symbol; // Exchange = @params.sp500Exchange; // break; //} } else if (signalFile.Symbol.Contains("QM")) { signalFile.Symbol = "QM"; contract.LocalSymbol = string.Empty; contract.Symbol = signalFile.Symbol; contract.SecType = @params.crudeSecType; contract.LastTradeDateOrContractMonth = @params.crudeExpiry; contract.Exchange = @params.crudeExchange; contract.Currency = @params.crudeCurrency; futuresContract.Symbol = contract.Symbol; futuresContract.Exchange = @params.crudeExchange; } else if (signalFile.Symbol.Contains("CL")) { signalFile.Symbol = "CL"; contract.LocalSymbol = string.Empty; contract.Symbol = signalFile.Symbol; contract.SecType = @params.crudeSecType; contract.LastTradeDateOrContractMonth = @params.crudeExpiry; contract.Exchange = @params.crudeExchange; contract.Currency = @params.crudeCurrency; futuresContract.Symbol = contract.Symbol; futuresContract.Exchange = @params.crudeExchange; } else if (signalFile.Symbol.Contains("GC")) { signalFile.Symbol = "GC"; contract.LocalSymbol = string.Empty; contract.Symbol = "MGC"; //signalFile.Symbol; contract.SecType = @params.goldSecType; contract.LastTradeDateOrContractMonth = @params.goldExpiry; contract.Exchange = @params.goldExchange; contract.Currency = @params.goldCurrency; futuresContract.Symbol = contract.Symbol; futuresContract.Exchange = @params.goldExchange; } else if (signalFile.Symbol.Contains("TY")) { signalFile.Symbol = "ZN"; contract.LocalSymbol = string.Empty; contract.Symbol = signalFile.Symbol; contract.SecType = "FUT"; contract.LastTradeDateOrContractMonth = @params.crudeExpiry; contract.Exchange = "ECBOT"; contract.Currency = "USD"; futuresContract.Symbol = signalFile.Symbol; futuresContract.Exchange = "ECBOT"; } return(futuresContract); }