Example #1
0
        private static TWPosition FindTWPosition(string account, Position pos)
        {
            // this loop could be eliminated if the long symbol name gets persisted in database
            foreach (KeyValuePair <string, TWPosition> p in twpositions[account])
            {
                TWPosition twpos = p.Value;
                if ((pos.Symbol == twpos.Symbol) && (pos.Type == twpos.Type) && (pos.Strike == twpos.Strike) && (pos.ExpDate == twpos.ExpDate))
                {
                    return(twpos);
                }
            }

            return(null);
        }
Example #2
0
        private static decimal DefaultCapital(string account, string strat, Positions positions)
        {
            decimal multiplier = 100;

            TWPosition twpos = FindTWPosition(account, positions.ElementAt(0).Value);

            if (twpos != null)
            {
                multiplier = twpos.Multiplier;
            }


            if (strat.Length >= 8)
            {
                strat = strat.Substring(0, 8);
                if ((strat == "Iron Con") || (strat == "Vertical"))
                {
                    Dictionary <string, decimal> strikeRange = new Dictionary <string, decimal> {
                        { "Call", 0 }, { "Put", 0 }
                    };

                    foreach (KeyValuePair <string, Position> item in positions)
                    {
                        Position p = item.Value;
                        strikeRange[p.Type] += (p.Strike * p.Quantity);
                    }
                    if (Math.Abs(strikeRange["Put"]) > Math.Abs(strikeRange["Call"]))
                    {
                        return(Math.Abs(strikeRange["Put"]) * multiplier);
                    }
                    else
                    {
                        return(Math.Abs(strikeRange["Call"]) * multiplier);
                    }
                }
            }
            return(0);
        }
Example #3
0
        public static TWPositions Positions(string accountNumber)
        {
            Dictionary <string, decimal> marketValues = new Dictionary <string, decimal>();
            Dictionary <string, Int32>   orderIds     = new Dictionary <string, Int32>();

            SetHeaders(Token);

            // retrieve current values
            string  reply   = Web.DownloadString("https://api.tastyworks.com/margin/accounts/" + accountNumber);
            JObject package = JObject.Parse(reply);

            List <JToken> list = package["data"]["underlyings"].Children().ToList();

            foreach (JToken item in list)
            {
                // capture the value of all of the options plus the underlaying
                JToken prices = item["marks"];
                foreach (JProperty price in prices)
                {
                    if (!marketValues.ContainsKey(price.Name))
                    {
                        marketValues.Add(price.Name, Convert.ToDecimal(price.Value));
                    }
                }

                // capture any orders associated with the underlying
                string symbol = item["underlying-symbol"].ToString();
                JToken orders = item["order-ids"];
                for (int i = 0; i < orders.Count(); i++)
                {
                    if (!orderIds.ContainsKey(symbol))
                    {
                        Int32 order = Convert.ToInt32(orders[i]);
                        orderIds.Add(symbol, order);
                    }
                }
            }

            SetHeaders(Token); // reset, lost after previous call

            // retrieve specific positions
            reply   = Web.DownloadString("https://api.tastyworks.com/accounts/" + accountNumber + "/positions");
            package = JObject.Parse(reply);

            TWPositions returnList = new TWPositions();

            list = package["data"]["items"].Children().ToList();

            foreach (JToken item in list)
            {
                TWPosition inst = new TWPosition();
                inst.Symbol       = item["underlying-symbol"].ToString();
                inst.OptionSymbol = item["symbol"].ToString();
                inst.Quantity     = Convert.ToDecimal(item["quantity"]);
                if (item["quantity-direction"].ToString() == "Short")
                {
                    inst.Quantity *= -1;
                }
                DateTime exp = Convert.ToDateTime(item["expires-at"]).Trim(TimeSpan.TicksPerDay);
                inst.PreviousClose = Convert.ToDecimal(item["close-price"]);
                if (inst.PreviousClose == 0)
                {
                    inst.PreviousClose = Convert.ToDecimal(item["average-open-price"]);
                }

                inst.Multiplier = Convert.ToDecimal(item["multiplier"]);;
                if (marketValues.ContainsKey(inst.OptionSymbol))
                {
                    inst.Market = marketValues[inst.OptionSymbol] * inst.Multiplier;
                }
                if (marketValues.ContainsKey(inst.Symbol))
                {
                    inst.UnderlyingPrice = marketValues[inst.Symbol];
                }

                inst.OrderActive = orderIds.ContainsKey(inst.Symbol);

                SymbolDecoder symbol = new SymbolDecoder(inst.OptionSymbol, item["instrument-type"].ToString());
                inst.Type    = symbol.Type;
                inst.ExpDate = symbol.Expiration;
                inst.Strike  = symbol.Strike;

                returnList.Add(inst.OptionSymbol.Length > 0 ? inst.OptionSymbol : inst.Symbol, inst);
            }


            return((returnList.Count > 0) ? returnList : null);
        }
Example #4
0
        public string ValidateCurrentHoldings()
        {
            string returnValue = "";
            Dictionary <string, TWPositions> overallPositions = null;

            // always start with clean data
            if (TastyWorks.ActiveSession())
            {
                overallPositions = new Dictionary <string, TWPositions>();
                foreach (Account a in accounts)
                {
                    if (a.Active)
                    {
                        // retrieve Tastyworks positions for given account
                        TWPositions pos = TastyWorks.Positions(a.ID);
                        overallPositions.Add(a.ID, pos);
                    }
                }
            }
            else
            {
                MessageBox.Show("Login to TastyWorks failed", "Error");
                return("LoginFailed");
            }


            foreach (KeyValuePair <string, TWPositions> item  in overallPositions)
            {
                // cycle thru each account
                TWPositions accountPositions = item.Value;

                // skip if the account is empty of positions
                // and confirm each aligns with what is in current database by
                // iterating thru all the positions in the current account
                //
                int i = 0;
                while ((accountPositions != null) && (i < accountPositions.Count))
                {
                    TWPosition position = accountPositions.ElementAt(i).Value;

                    // iterate thru each group
                    foreach (KeyValuePair <int, TransactionGroup> grpItem in this)
                    {
                        TransactionGroup grp = grpItem.Value;

                        // examine closer if right account and underlying
                        if ((item.Key == grp.Account) && (position.Symbol == grp.Symbol))
                        {
                            // iterate thru everthing in the group
                            int j = 0;
                            while ((j < grp.Holdings.Count) && (position.Quantity != 0))
                            {
                                Position dbpos = grp.Holdings[grp.Holdings.Keys.ElementAt(j)];

                                // look for matching security
                                if ((position.Type == dbpos.Type) && (position.Strike == dbpos.Strike) && (position.ExpDate == dbpos.ExpDate))
                                {
                                    position.Quantity -= dbpos.Quantity;
                                    grp.Holdings.Remove(grp.Holdings.Keys.ElementAt(j));
                                }
                                else
                                {
                                    j++;
                                }
                            }
                        }
                    }

                    if (position.Quantity == 0)
                    {
                        accountPositions.Remove(accountPositions.ElementAt(i).Key);
                    }
                    else
                    {
                        i++;
                    }
                }
            }


            // catch anything left over in database
            foreach (KeyValuePair <int, TransactionGroup> grpItem in this)
            {
                TransactionGroup grp = grpItem.Value;

                if (grp.Holdings.Count > 0)
                {
                    // something left
                    if (returnValue.Length == 0)
                    {
                        returnValue = "Unmatched positons in the database:\n";
                    }
                    returnValue += grp.Holdings.ToString();
                }
            }
            // add anything left from the TW query
            foreach (KeyValuePair <string, TWPositions> positionsPair in overallPositions)
            {
                bool firstPass = true;

                // nothing to do if account is empty
                if (positionsPair.Value != null)
                {
                    foreach (KeyValuePair <string, TWPosition> p in positionsPair.Value)
                    {
                        TWPosition pos = p.Value;

                        if (firstPass)
                        {
                            firstPass = false;
                            if (returnValue.Length > 0)
                            {
                                returnValue += "\n";
                            }
                            returnValue += "Unmatched from TastyWorks account:\n";
                        }
                        returnValue += (pos.Type == "Stock") ? pos.Symbol : pos.Symbol + pos.ExpDate.ToString("yyMMdd") + pos.Strike.ToString("0000.0") + pos.Type + " : " + pos.Quantity.ToString() + "\n";
                    }
                }
            }


            return(returnValue);
        }
Example #5
0
        private void RetrieveCurrentData(TransactionGroup grp)
        {
            decimal currentValue       = 0;
            decimal previousCloseValue = 0;

            try
            {
                // retrieve and cache current data from tastyworks for this a subsequent passes
                if (twpositions == null)
                {
                    if (TastyWorks.ActiveSession())
                    {
                        List <string> symbols = new List <string>();

                        twpositions = new Dictionary <string, TWPositions>();
                        foreach (Account a in accounts)
                        {
                            if (a.Active)
                            {
                                // retrieve Tastyworks positions for given account
                                TWPositions pos = TastyWorks.Positions(a.ID);
                                twpositions.Add(a.ID, pos);

                                if (pos != null)
                                {
                                    foreach (KeyValuePair <string, TWPosition> p in pos)
                                    {
                                        if (!symbols.Contains(p.Value.Symbol))
                                        {
                                            symbols.Add(p.Value.Symbol);
                                        }
                                    }
                                }
                            }
                        }

                        twmarketinfo = TastyWorks.MarketInfo(symbols);  // get IV's
                    }
                }

                // ensure that positions got instanciated AND that the particular account isn't empty
                if ((twpositions != null) && (twpositions.Count > 0) && (twpositions[grp.Account] != null))
                {
                    foreach (KeyValuePair <string, Position> item in grp.Holdings)
                    {
                        Position pos = item.Value;

                        // this loop could be eliminated if the long symbol name gets persisted in database
                        foreach (KeyValuePair <string, TWPosition> p in twpositions[grp.Account])
                        {
                            TWPosition twpos = p.Value;
                            if ((pos.Symbol == twpos.Symbol) && (pos.Type == twpos.Type) && (pos.Strike == twpos.Strike) && (pos.ExpDate == twpos.ExpDate))
                            {
                                //Debug.WriteLine(twpos.Market);
                                currentValue       += pos.Quantity * twpos.Market;
                                previousCloseValue += pos.Quantity * twpos.PreviousClose * twpos.Multiplier;

                                // capture current details while we have it
                                pos.Market          = twpos.Market;
                                pos.Multiplier      = twpos.Multiplier;
                                pos.UnderlyingPrice = twpos.UnderlyingPrice;

                                // capture the underlying price from the first position for the overall group
                                if (grp.UnderlyingPrice == 0)
                                {
                                    grp.UnderlyingPrice = twpos.UnderlyingPrice;
                                }

                                // update groups order status based on any of items constituent holdings
                                grp.OrderActive = twpos.OrderActive;
                            }
                        }
                    }
                }

                grp.CurrentValue            = currentValue;
                grp.PreviousCloseValue      = previousCloseValue;
                grp.ChangeFromPreviousClose = currentValue - previousCloseValue;
                if (twmarketinfo.ContainsKey(grp.ShortSymbol))
                {
                    grp.ImpliedVolatility     = twmarketinfo[grp.ShortSymbol].ImpliedVolatility;
                    grp.ImpliedVolatilityRank = twmarketinfo[grp.ShortSymbol].ImpliedVolatilityRank;
                    grp.DividendYield         = twmarketinfo[grp.ShortSymbol].DividendYield;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("RetrieveCurrentData: " + ex.Message);
            }
        }