コード例 #1
0
ファイル: OptionData.cs プロジェクト: johnmensen/TradeSharp
 public OptionData(OptionData op)
 {
     Type = op.Type;
     Style = op.Style;
     BaseActive = op.BaseActive;
     DatePublished = op.DatePublished;
     DateExpiration = op.DateExpiration;
     StrikePrice = op.StrikePrice;
     ContractHigh = op.ContractHigh;
     ContractLow = op.ContractLow;
     ContractClose = op.ContractClose;
     OpenInterest = op.OpenInterest;
     Volume = op.Volume;
 }
コード例 #2
0
ファイル: OptionData.cs プロジェクト: johnmensen/TradeSharp
 public bool Equals(OptionData op)
 {
     if (op == null) return false;
     return Type == op.Type && Style == op.Style
         && BaseActive == op.BaseActive
         && DatePublished == op.DatePublished
         && DateExpiration == op.DateExpiration
         && StrikePrice == op.StrikePrice
         && ContractHigh == op.ContractHigh
         && ContractLow == op.ContractLow
         && ContractClose == op.ContractClose
         && OpenInterest == op.OpenInterest
         && Volume == op.Volume;
 }
コード例 #3
0
ファイル: OptionData.cs プロジェクト: johnmensen/TradeSharp
        /// <summary>
        /// Формат строки "[#fmt]#;newstype=option#;type=val#;style=val#;baseactive=val#;countdate=val#;
        /// dateexpiration=val#;strikeprice=val#;delta=val#;openinterest=val"
        /// </summary>
        /// <param name="op"></param>
        public static OptionData Parse(String op)
        {
            var od = new OptionData();
            try
            {
                var separator = new[] { PartsSeparator };
                var str = op.Split(separator, StringSplitOptions.RemoveEmptyEntries);
                if (str.Length != 13) return null;
                if (str[0] != "[#fmt]") return null;

                // строка отформатирована, проверим, что это опцион
                var members = new Dictionary<string, string>();
                var sep = new [] { '=' };
                foreach (var a in str)
                {
                    var mem = a.Split(sep);
                    if (mem.Count() == 1)
                        continue;
                    members.Add(mem[0], mem[1]);
                }
                if (members["newstype"] == null || members["newstype"] != "option")
                    throw new Exception("OptionData.Parse: тип новости отличается от опциона");

                var typeStr = members["type"];
                if (!string.IsNullOrEmpty(typeStr))
                    od.Type = (OptionType)Enum.Parse(typeof(OptionType), typeStr);
                var styleStr = members["style"];
                if (!string.IsNullOrEmpty(styleStr))
                    od.Style = (OptionStyle)Enum.Parse(typeof(OptionStyle), styleStr);

                od.BaseActive = members["baseactive"];
                od.DatePublished = members["publishdate"].ToDateTimeUniform();
                od.DateExpiration = DateTime.ParseExact(members["dateexpiration"],
                    "dd.MM.yyyy", CultureProvider.Common);
                od.StrikePrice = members["strikeprice"].ToFloatUniform();
                od.ContractHigh = members["high"].ToFloatUniform();
                od.ContractLow = members["low"].ToFloatUniform();
                od.ContractClose = members["close"].ToFloatUniform();
                od.OpenInterest = members["oi"].ToInt();
                od.Volume = members["volume"].ToInt();
            }
            catch (InvalidCastException ex)
            {
                Logger.Error("OptionData.Parse ошибка ", ex);
                return null;
            }
            catch (Exception ex)
            {
                Logger.Error("OptionData.Parse ошибка ", ex);
                return null;
            }
            return od;
        }
コード例 #4
0
        private void BuildSummaryOL()
        {
            if (options.Count == 0) return;

            // count date - level * [OI | Volume], sum OI, sum Volume
            var dicSumCall = new Dictionary<DateTime, Cortege3<float, float, float>>();
            var dicSumPut = new Dictionary<DateTime, Cortege3<float, float, float>>();

            foreach (var opt in options)
            {
                if ((AllowedOptionStyles == AllowedOptionStyle.American && opt.Style == OptionStyle.European)
                    || (AllowedOptionStyles == AllowedOptionStyle.European && opt.Style == OptionStyle.American))
                    continue;

                var multiplier = WeightType == OptionLevelWeightType.ОткрытыйИнтерес
                                     ? opt.OpenInterest
                                     : opt.Volume;

                if (opt.Type == OptionType.CALL)
                {
                    var sumCall = opt.OptionLevelClose*multiplier;
                    if (!dicSumCall.ContainsKey(opt.DatePublished))
                        dicSumCall.Add(opt.DatePublished,
                                       new Cortege3<float, float, float>(sumCall, opt.OpenInterest, opt.Volume));
                    else
                    {
                        sumCall += dicSumCall[opt.DatePublished].a;
                        var totalOI = dicSumCall[opt.DatePublished].b + opt.OpenInterest;
                        var totalVolume = dicSumCall[opt.DatePublished].c + opt.Volume;
                        dicSumCall[opt.DatePublished] =
                            new Cortege3<float, float, float>(sumCall, totalOI, totalVolume);
                    }
                }
                else
                {
                    var sumPut = opt.OptionLevelClose*multiplier;
                    if (!dicSumPut.ContainsKey(opt.DatePublished))
                        dicSumPut.Add(opt.DatePublished,
                                      new Cortege3<float, float, float>(sumPut, opt.OpenInterest, opt.Volume));
                    else
                    {
                        sumPut += dicSumPut[opt.DatePublished].a;
                        var totalOI = dicSumPut[opt.DatePublished].b + opt.OpenInterest;
                        var totalVolume = dicSumPut[opt.DatePublished].c + opt.Volume;
                        dicSumPut[opt.DatePublished] =
                            new Cortege3<float, float, float>(sumPut, totalOI, totalVolume);
                    }
                }
            }

            var sumOpts = new List<OptionData>();
            foreach (var date in dicSumCall)
            {
                if (date.Value.a == 0) continue;
                var strike = date.Value.a/(WeightType == OptionLevelWeightType.ОткрытыйИнтерес
                    ? date.Value.b : date.Value.c);
                var opt = new OptionData(OptionType.CALL, OptionStyle.American,
                                         options[0].BaseActive, date.Key,
                                         new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1),
                                         strike, 0, 0, 0, (int) date.Value.b, (int) date.Value.c);
                sumOpts.Add(opt);
            }
            foreach (var date in dicSumPut)
            {
                if (date.Value.a == 0) continue;
                var strike = date.Value.a/(WeightType == OptionLevelWeightType.ОткрытыйИнтерес
                                               ? date.Value.b
                                               : date.Value.c);
                var opt = new OptionData(OptionType.PUT, OptionStyle.American,
                                         options[0].BaseActive, date.Key,
                                         new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1),
                                         strike, 0, 0, 0, (int) date.Value.b, (int) date.Value.c);
                sumOpts.Add(opt);
            }
            // медианный уровень
            List<Cortege2<DateTime, float>> channelCall = null, channelPut = null, channelMid = null;
            if (SummaryLevelStyle == SummaryLevelLineStyle.Каналы)
            {
                channelCall = new List<Cortege2<DateTime, float>>();
                channelPut = new List<Cortege2<DateTime, float>>();
                channelMid = new List<Cortege2<DateTime, float>>();
            }

            foreach (var callData in dicSumCall)
            {
                if (!dicSumPut.ContainsKey(callData.Key)) continue;
                var putData = dicSumPut[callData.Key];

                var oi = callData.Value.b + putData.b;
                var volume = callData.Value.c + putData.c;
                var denominator = WeightType == OptionLevelWeightType.ОткрытыйИнтерес ? oi : volume;
                var strike = (callData.Value.a + putData.a)/denominator;

                var opt = new OptionData(WeightType == OptionLevelWeightType.ОткрытыйИнтерес
                                             ? callData.Value.b > putData.b ? OptionType.CALL : OptionType.PUT
                                             : callData.Value.c > putData.c ? OptionType.CALL : OptionType.PUT,
                                         OptionStyle.American,
                                         options[0].BaseActive, callData.Key,
                                         new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1),
                                         strike, 0, 0, 0, (int) oi, (int) volume);

                // добавить мед. уровень
                if (SummaryLevelStyle == SummaryLevelLineStyle.Каналы)
                    channelMid.Add(new Cortege2<DateTime, float>(
                                       opt.DatePublished,
                                       opt.OptionLevelClose));
                else
                    AddOptionLevel(opt, true);
            }

            foreach (var opt in sumOpts)
            {
                if (SummaryLevelStyle == SummaryLevelLineStyle.Каналы)
                {
                    var pivot = new Cortege2<DateTime, float>(opt.DatePublished, opt.OptionLevelClose);
                    if (opt.Type == OptionType.CALL) channelCall.Add(pivot);
                    else channelPut.Add(pivot);
                }
                else
                    AddOptionLevel(opt, false);
            }
            // построить каналы a-la Bollinger?
            if (SummaryLevelStyle == SummaryLevelLineStyle.Каналы)
            {
                BuildLineSeriesFromPivots(channelCall, seriesChannelCall);
                BuildLineSeriesFromPivots(channelPut, seriesChannelPut);
                BuildLineSeriesFromPivots(channelMid, seriesChannelMid);
            }
        }
コード例 #5
0
        private void AddOptionLevel(OptionData opt, bool isMedian)
        {
            var color = isMedian ? Color.Green : opt.Type == OptionType.PUT ? colorPut : colorGet;

            var linePart = new SpanWithText
                               {
                                   Price = opt.OptionLevelClose,
                                   LineColor = color,
                                   Name = string.Format("{0} {1:f4} OI:{2}", opt.Type, opt.OptionLevelClose, opt.OpenInterest)
                               };
            var indexStart = owner.StockSeries.GetIndexByCandleOpen(opt.DatePublished);
            var indexEnd = owner.StockSeries.GetIndexByCandleOpen(opt.DatePublished.AddHours(LengthHours));

            // проверить расстояние до рынка в пп
            // как мин. расстояние до уровня
            if (MaxPointsDistanceToShow > 0)
            {
                var candles = owner.StockSeries.Data.Candles;
                var distanceAbs = float.MaxValue;
                for (var i = indexStart < 0 ? 0 : indexStart; i < indexEnd; i++)
                {
                    if (i >= candles.Count) break;
                    var dist = Math.Min(
                        Math.Abs(candles[i].high - opt.OptionLevelClose),
                        Math.Abs(candles[i].low - opt.OptionLevelClose));
                    if (dist < distanceAbs) distanceAbs = dist;
                }
                var distPoints = DalSpot.Instance.GetPointsValue(owner.Symbol, distanceAbs);
                if (distPoints > MaxPointsDistanceToShow) return;
            }

            linePart.StartIndex = indexStart;
            linePart.EndIndex = indexEnd;
            var daysLeft = (opt.DateExpiration - opt.DatePublished).TotalDays;
            if (daysLeft <= daysToHighlight) linePart.LineWidth = 2;
            // показать метки
            if (LabelLeft != LevelLabel.Нет) AddOptionLabel(linePart, LabelLeft, true, opt);
            if (LabelRight != LevelLabel.Нет) AddOptionLabel(linePart, LabelRight, false, opt);
            seriesSpan.data.Add(linePart);
            // подсказка по уровню
            lineHints.Add(linePart, string.Format("{0:f4}{1} {2} (strike:{3:f4} close:{4:f4} OI:{5} volm:{6})",
                                                  opt.OptionLevelClose,
                                                  opt.Type,
                                                  opt.Style == OptionStyle.American ? "AM" : "EU",
                                                  opt.StrikePrice,
                                                  opt.ContractClose,
                                                  opt.OpenInterest,
                                                  opt.Volume));
        }
コード例 #6
0
        private static void AddOptionLabel(SpanWithText span, LevelLabel label, bool isLeft, OptionData opt)
        {
            string text = label == LevelLabel.Объем
                              ? opt.Volume.ToString()
                              : label == LevelLabel.ОткрИнтерес
                                    ? opt.OpenInterest.ToString()
                                    : string.Format("{0:MMMyy}", opt.DateExpiration);

            if (isLeft) span.TextLeft = text;
            else span.TextRight = text;
        }