public Order?DecideOrder(PositionDelta delta) { OptionQuote quote = delta.Quote ?? MarketDataClient.GetOptionQuote(delta.Symbol); // TODO: Remove after testing //Log.Warning("Not getting real quote"); //OptionQuote quote = new OptionQuote(delta.Symbol, delta.Price * (float).99, delta.Price * (float)1.01, delta.Price, delta.Price * (float)1.06, (float)1.0); if (quote.Time < DateTime.Now.AddSeconds(-15)) { Log.Information("Getting new quote. Old quote- {@Quote}", quote); quote = MarketDataClient.GetOptionQuote(delta.Symbol); } Log.Information("{DeltaType} delta {@Delta}- current mark price {Mark}. Symbol {Symbol}", delta.DeltaType, delta, quote.Mark.ToString("0.00"), delta.Symbol); Position?currentPos = BrokerClient.GetPosition(delta.Symbol); if (delta.DeltaType == DeltaType.SELL) { return(DecideSell(delta, currentPos)); } else if (delta.DeltaType == DeltaType.ADD || delta.DeltaType == DeltaType.NEW) { return(DecideBuy(delta, currentPos, quote)); } else { Log.Error("Unrecognized deltaType: {type}", delta.DeltaType); return(null); } }
public async Task <List <object> > GetOptionChain(string symbol) { if (symbol == null) { throw new ArgumentNullException("symbols"); } var quotes = new List <object>(); var url = "/v1/marketdata/chains?" + "symbol=" + symbol + "&includeQuotes=true"; var text = await this.http.GetStringAsync(url); OptionQuote optionChain = JsonConvert.DeserializeObject <OptionQuote>(text); foreach (var optionDate in optionChain.callExpDateMap.Keys) { DateTime date = DateTime.ParseExact(optionDate.Substring(0, 10), "yyyy-MM-dd", null); foreach (var strikeArr in optionChain.callExpDateMap[optionDate].Values) { foreach (var strike in strikeArr) { try { strike.ExpirationDate = date; strike.Underlyer = symbol; quotes.Add(strike); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(ex.InnerException?.Message); } } } } return(quotes); }
public override OptionQuote GetOptionQuote(string symbol) { if (!OptionSymbolUtils.IsOptionSymbol(symbol)) { throw new ArgumentException("Provided symbol is not an option symbol: " + symbol); } string tdAmSymbol = OptionSymbolUtils.ConvertDateFormat(symbol, OptionSymbolUtils.StandardDateFormat, Constants.TDOptionDateFormat); RestClient client = new RestClient("https://api.tdameritrade.com/v1/marketdata/" + tdAmSymbol + "/quotes"); RestRequest request = CreateRequest(Method.GET); IRestResponse response = ExecuteRequest(client, request); if (!response.IsSuccessful || response.Content.Contains("Symbol not found")) { throw new MarketDataException("Get quote unsuccessful for symbol " + symbol); } Regex responseRegex = new Regex("{\"assetType.*?}"); Match match = responseRegex.Match(response.Content); OptionQuote quote = JsonConvert.DeserializeObject <TDOptionQuote>(match.Value); return(quote); }
protected override Position InstantiateWithSymbolOverride(string overrideSymbol, OptionQuote quote) { return(new Position(overrideSymbol, Quantity, (float)Average)); }
protected override FilledOrder InstantiateWithSymbolOverride(string overrideSymbol, OptionQuote quote) { return(new FilledOrder(overrideSymbol, (float)FilledPrice, Instruction, OrderType, (float)Limit, Quantity, Time, quote)); }
private Order?DecideBuy(PositionDelta delta, Position?currentPos, OptionQuote quote) { if (delta.DeltaType == DeltaType.ADD && currentPos == null) { Log.Information("No current position corresponding to {DeltaType} delta {@Delta}. Symbol {Symbol}", delta.DeltaType, delta, delta.Symbol); } else if (delta.DeltaType == DeltaType.NEW && currentPos != null) { Log.Warning("Current position exists {@CurrentPosition} for {DeltaType} delta {@Delta}. Taking no action for Symbol {Symbol}", currentPos, delta.DeltaType, delta, delta.Symbol); return(null); } if (delta.Age.TotalMinutes > _config.MinutesUntilBuyOrderExpires) { Log.Warning("New/Add delta expired after {Minutes} minutes for delta {@Delta}. Symbol {Symbol}", delta.Age.TotalMinutes.ToString("0"), delta, delta.Symbol); return(null); } if (delta.Price > _config.MaxBuyPrice) { Log.Information("Buy price higher than buy max limit. Skipping order. Symbol {Symbol}, Price={Price}", delta.Symbol, delta.Price); return(null); } float diff = quote.Mark - delta.Price; float absPercent = Math.Abs(diff / delta.Price); bool withinHighThreshold = Math.Sign(diff) >= 0 && absPercent <= _config.HighBuyThreshold; bool withinLowThreshold = Math.Sign(diff) <= 0 && absPercent <= _config.LowBuyThreshold; int quantity; string orderType; float limit = -1; if (withinHighThreshold && _config.HighBuyStrategy == BuyStrategyType.MARKET || withinLowThreshold && _config.LowBuyStrategy == BuyStrategyType.MARKET) { orderType = OrderType.MARKET; quantity = DecideBuyQuantity(quote.AskPrice, delta, currentPos, quote.AskPrice); // Assume we will pay the ask price } else if (withinHighThreshold && _config.HighBuyStrategy == BuyStrategyType.DELTA_LIMIT || withinLowThreshold && _config.LowBuyStrategy == BuyStrategyType.DELTA_LIMIT) { orderType = OrderType.LIMIT; limit = delta.Price; quantity = DecideBuyQuantity(limit, delta, currentPos, quote.AskPrice); } else if (withinHighThreshold && _config.HighBuyStrategy == BuyStrategyType.THRESHOLD_LIMIT) { orderType = OrderType.LIMIT; limit = delta.Price * (1 + _config.HighBuyLimit); quantity = DecideBuyQuantity(limit, delta, currentPos, quote.AskPrice); } else if (withinLowThreshold && _config.LowBuyStrategy == BuyStrategyType.THRESHOLD_LIMIT) { orderType = OrderType.LIMIT; limit = delta.Price * (1 - _config.LowBuyLimit); quantity = DecideBuyQuantity(limit, delta, currentPos, quote.AskPrice); } else { Log.Information("Current mark price not within buy threshold. Skipping order. Symbol {Symbol}, Mark={Mark}", delta.Symbol, quote.Mark.ToString("0.00")); return(null); } if (quantity == 0) { Log.Information("Decided buy quantity of 0. Skipping Order. Symbol {Symbol}, CurrentPosition = {@CurrentPosition}, Delta = {@Delta}", delta.Symbol, currentPos, delta); return(null); } else { DateTime cancelTime = delta.Time.Date.Equals(DateTime.Today) ? delta.Time.AddMinutes(_config.MinutesUntilBuyOrderExpires) : DateTime.Now.AddMinutes(_config.MinutesUntilBuyOrderExpires); Order order = new Order(delta.Symbol, quantity, InstructionType.BUY_TO_OPEN, orderType, limit, cancelTime); Log.Information("Decided new Order: {@Order} for Symbol {Symbol}", order, order.Symbol); return(order); } }