├── ADX.cs ├── AMA.cs ├── AccumHandlers.cs ├── AlignedSecurity.DataSourceSecurity.cs ├── AlignedSecurity.cs ├── AlignedSecurityHandler.cs ├── AllTimeTradeStatisticsHandler.cs ├── Alligator.cs ├── Aroon.cs ├── BarNumber.cs ├── BarsConstructorHandler.cs ├── BarsCountForValuesSumHandler.cs ├── BaseIndicator.cs ├── BaseTradeStatisticsHandler.cs ├── BuysHandler.cs ├── BuysMinusSellsHandler.cs ├── BuysSellsHandler.cs ├── Compress.cs ├── ConstGen.cs ├── ConstList.cs ├── ControlledBoolConst.cs ├── DoubleStreamAndValuesHandler.cs ├── ExtremePos.cs ├── FinInfoHandlers.cs ├── FinMath.cs ├── HoldSignalForNBars.cs ├── InteractiveConstGen.cs ├── InteractiveLineGen.BaseList.cs ├── InteractiveLineGen.ConstList.cs ├── InteractiveLineGen.LineList.cs ├── InteractiveLineGen.cs ├── InteractiveSeriesHandler.cs ├── LastContractsTradeStatisticsHandler.cs ├── LastTradeStatisticsHandler.cs ├── MACD.cs ├── MAMA.cs ├── MarketPosition.cs ├── MessageHandler.cs ├── Momentum.cs ├── Options ├── ApproximationAlgo.cs ├── AutoHedger.cs ├── BaseCanvasDrawing.cs ├── BaseContextBimodal.cs ├── BaseContextHandler.cs ├── BaseContextTemplate.cs ├── BaseContextWithBlock.cs ├── BaseContextWithNumber.cs ├── BasePx.cs ├── BasePx2.cs ├── BasePxMode.cs ├── BaseSmileDrawing.cs ├── BestChartTrading.cs ├── BlackScholesConstSmile2.cs ├── BlackScholesDelta.cs ├── BlackScholesGreeks.cs ├── BlackScholesSmile2.cs ├── BrokenDefaultParameter.cs ├── BuyOptionGroup.cs ├── BuyOptionGroupDelta.cs ├── BuyOptions.cs ├── CentralStrike.cs ├── ChartTrading.cs ├── CloseVirtualFutPosition.cs ├── CloseVirtualPosition.cs ├── CombinePositionProfiles.cs ├── ConstSmileLevel2.cs ├── Constants.cs ├── CurrentDateMode.cs ├── CurrentFutPx.cs ├── DropVirtualPositions.cs ├── EditTemplateSmile.cs ├── ExchangeTheorPx.cs ├── ExchangeTheorSigma2.cs ├── ExchangeTheorSigma3.cs ├── ExchangeTheorSigma5.cs ├── ExpiryMode.cs ├── FixedCommission.cs ├── FixedValue.cs ├── FixedValueMode.cs ├── ForwardTheorPx.cs ├── GaussSmile.cs ├── GetValueAtm.cs ├── GlobalHv.cs ├── GlobalIvOnF.cs ├── GlobalSkewOnF.cs ├── Greeks.cs ├── HV.cs ├── Heartbeat.cs ├── HelperDescriptionAttribute.cs ├── HelperLinkAttribute.cs ├── HelperNameAttribute.cs ├── IvChartTrading.cs ├── IvOnF.cs ├── IvOnF2.cs ├── IvOnFAllSeries.cs ├── IvSmile.cs ├── IvSmile2.cs ├── IvSmileRescaled2.cs ├── LastValueToParameter.cs ├── LinearTransform.cs ├── LoadFromGlobalCache.cs ├── MarketMaker.cs ├── MarketMakerDelta.cs ├── NumericalDeltaOnF.cs ├── NumericalDeltaOnF2.cs ├── NumericalDeltaOnF3.cs ├── NumericalGammaOnF.cs ├── NumericalGammaOnF3.cs ├── NumericalGreekAlgo.cs ├── NumericalThetaOnF.cs ├── NumericalVegaOnF.cs ├── NumericalVommaOnF.cs ├── OpenVirtualFutPosition.cs ├── OpenVirtualFutPosition2.cs ├── OpenVirtualOptPosition.cs ├── OpenVirtualOptPosition2.cs ├── OptionBase2.cs ├── OptionPxMode.cs ├── OptionSelector.cs ├── OptionSeriesBase.cs ├── OptionSeriesBaseN.cs ├── OptionSeriesByNumber.cs ├── OptionSeriesByNumber2.cs ├── OptionSeriesSelector.cs ├── OptionUtils.cs ├── Options.cs ├── OptionsBoardNumericalDelta.cs ├── OptionsBoardNumericalGamma.cs ├── OptionsBoardNumericalTheta.cs ├── OptionsBoardNumericalVega.cs ├── OptionsBoardPrice.cs ├── OptionsBoardVolatility.cs ├── OwnOrders.cs ├── OwnPositionIv.cs ├── OwnPositionIvLine.cs ├── PositionGridDisplayMode.cs ├── PositionsManager.IvTargetInfo.cs ├── PositionsManager.PosInfo.cs ├── PositionsManager.SecInfo.cs ├── PositionsManager.cs ├── PositionsManagerSingle.cs ├── PrepareLineForCanvasPane.cs ├── QuoteIv.cs ├── QuoteIvDeribit.cs ├── QuoteIvMode.cs ├── RaiseException.cs ├── Random.cs ├── RandomPersistent.cs ├── SaveToGlobalCache.cs ├── SelectStrike.cs ├── SellOptionGroup.cs ├── SellOptionGroupDelta.cs ├── SellOptions.cs ├── SeriesSelector.cs ├── SetViewport.cs ├── ShowIvTargets.cs ├── ShowIvTargetsDeribit.cs ├── ShowTrades.cs ├── SingleOption.cs ├── SingleOption2.cs ├── SingleSeriesNumericalDelta.cs ├── SingleSeriesNumericalDelta3.cs ├── SingleSeriesNumericalDeltaDeribit3.cs ├── SingleSeriesNumericalGamma.cs ├── SingleSeriesNumericalGamma3.cs ├── SingleSeriesNumericalSpeed.cs ├── SingleSeriesNumericalTheta.cs ├── SingleSeriesNumericalVega.cs ├── SingleSeriesPositionCommissions.cs ├── SingleSeriesPositionGrid.cs ├── SingleSeriesPositionList.cs ├── SingleSeriesPositionPrices.cs ├── SingleSeriesProfile.cs ├── SingleSeriesProfileDeribit.cs ├── SmileImitation3.cs ├── SmileImitation5.cs ├── SmileImitationDeribit5.cs ├── SmileInfo.cs ├── SmileNodeInfo.cs ├── SmileSelector.cs ├── SmileSkewMode.cs ├── SmileTransformation.cs ├── SmileType.cs ├── Smiles.cs ├── StrikeSelectionMode.cs ├── SubtractVolatilities.cs ├── TestSecurityDescription.cs ├── TimeRemainMode.cs ├── TimeToExpiry.cs ├── TimeToExpiry2.cs ├── TotalCommission.cs ├── TotalProfit.cs ├── TotalProfitAlgo.cs ├── TotalQty.cs ├── TotalRiskN2.cs ├── TransformSmile.cs ├── VerticalLine.cs ├── VerticalLine2.cs └── eHV.cs ├── OptionsPublic ├── BasePxPublic.cs ├── BuyOptionsPublic.cs ├── GlobalHvPublic.cs ├── HVPublic.cs ├── SmileFunction3Public.cs ├── SmileImitation3Public.cs └── TimeToExpiryPublic.cs ├── ParabolicSAR.cs ├── Portfolio.cs ├── PositionHandlers.cs ├── PositionHandlers2.cs ├── ProfitExtensions.cs ├── README.md ├── ResettableControlledBoolConst.cs ├── ResultForOptimization.cs ├── SecurityHandlers.cs ├── SellsHandler.cs ├── SessionBase.cs ├── ShrinkedList.cs ├── SomeIndicators.cs ├── SpecifiedQuantityPriceAtTradeHandler.cs ├── StatMath.cs ├── SumForTimeFrameHandler.cs ├── Support.cs ├── TEMA.cs ├── TextHandler.cs ├── TickTest Handler.cs ├── TradeMath ├── OrderBookPrice.cs ├── OrderBookQty.cs └── OrderBookTotal.cs ├── TradeStatisticsBarsCountHandler.cs ├── TradeStatisticsBarsHandler.cs ├── TradeStatisticsBarsSumHandler.cs ├── TradeStatisticsBaseExtendedBarsHandler.cs ├── TradeStatisticsBaseExtendedExtremumPriceHandler.cs ├── TradeStatisticsBaseExtremumPriceHandler.cs ├── TradeStatisticsEdgeHandler.cs ├── TradeStatisticsExtendedBarsCountHandler.cs ├── TradeStatisticsExtendedBarsCountHandler2.cs ├── TradeStatisticsExtendedBarsHandler.cs ├── TradeStatisticsExtendedBarsHandler2.cs ├── TradeStatisticsExtendedBarsSumHandler.cs ├── TradeStatisticsExtendedBarsSumHandler2.cs ├── TradeStatisticsExtendedExtremumPriceHandler.cs ├── TradeStatisticsExtendedExtremumPriceHandler2.cs ├── TradeStatisticsExtremumPriceHandler.cs ├── TradeStatisticsExtremumValueHandler.cs ├── TradeStatisticsHandler.cs ├── TradeStatisticsLowerEdgeHandler.cs ├── TradeStatisticsPriceValueHandler.cs ├── TradeStatisticsUpperEdgeHandler.cs ├── Trix.cs ├── ValueForPeriodHandler.cs ├── ValueSupportedIndicator.cs └── VolumeForPeriodHandler.cs /AMA.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | 5 | using TSLab.Script.Handlers.Options; 6 | 7 | // ReSharper disable InconsistentNaming 8 | namespace TSLab.Script.Handlers 9 | { 10 | [HandlerCategory(HandlerCategories.Indicators)] 11 | [HelperName("AMA", Language = Constants.En)] 12 | [HelperName("AMA", Language = Constants.Ru)] 13 | [InputsCount(1)] 14 | [Input(0, TemplateTypes.DOUBLE)] 15 | [OutputsCount(1)] 16 | [OutputType(TemplateTypes.DOUBLE)] 17 | [Description("Адаптивное сглаженное скользящее среднее.")] 18 | [HelperDescription("The Adaptive Moving Average.", Constants.En)] 19 | public sealed class AMA : DoubleStreamAndValuesHandlerWithPeriod 20 | { 21 | private ShrinkedList m_source; 22 | private double m_lastResult; 23 | 24 | public override bool IsGapTolerant 25 | { 26 | get { return false; } 27 | } 28 | 29 | public override IList Execute(IList source) 30 | { 31 | return Calc(source, Period, Context); 32 | } 33 | 34 | protected override void InitExecuteContext() 35 | { 36 | m_source = new ShrinkedList(Period + 2); 37 | m_lastResult = 0; 38 | } 39 | 40 | protected override void ClearExecuteContext() 41 | { 42 | m_source = null; 43 | m_lastResult = 0; 44 | } 45 | 46 | protected override void InitForGap() 47 | { 48 | var firstIndex = Math.Max(m_executeContext.LastIndex + 1, m_executeContext.Index - 7 * Period); 49 | for (var i = firstIndex; i < m_executeContext.Index; i++) 50 | { 51 | m_source.Add(m_executeContext.GetSourceForGap(i)); 52 | m_lastResult = Calc(m_source, m_lastResult, m_source.Count - 1, Period); 53 | } 54 | } 55 | 56 | protected override double Execute() 57 | { 58 | m_source.Add(m_executeContext.Source); 59 | m_lastResult = Calc(m_source, m_lastResult, m_source.Count - 1, Period); 60 | return m_lastResult; 61 | } 62 | 63 | public static IList Calc(IList source, int period, IMemoryContext context = null) 64 | { 65 | if (source == null) 66 | throw new ArgumentNullException(nameof(source)); 67 | 68 | if (period <= 0) 69 | throw new ArgumentOutOfRangeException(nameof(period)); 70 | 71 | var result = context?.GetArray(source.Count) ?? new double[source.Count]; 72 | if (result.Length > 0) 73 | { 74 | result[0] = Calc(source, 0, 0, period); 75 | for (var i = 1; i < result.Length; i++) 76 | result[i] = Calc(source, result[i - 1], i, period); 77 | } 78 | return result; 79 | } 80 | 81 | private static double Calc(IList source, double lastResult, int index, int period) 82 | { 83 | if (index <= period) 84 | return source[index]; 85 | 86 | var signal = Math.Abs(source[index] - source[index - period]); 87 | var noise = 0.000000001; 88 | 89 | for (var i = 0; i < period; i++) 90 | noise = noise + Math.Abs(source[index - i] - source[index - i - 1]); 91 | 92 | var er = signal / noise; 93 | var ssc = (er * 0.60215) + 0.06452; 94 | var cst = Math.Pow(ssc, 2); 95 | var result = lastResult + cst * (source[index] - lastResult); 96 | return result; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /AlignedSecurity.DataSourceSecurity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TSLab.DataSource; 3 | 4 | namespace TSLab.Script.Handlers 5 | { 6 | public sealed partial class AlignedSecurity 7 | { 8 | private sealed class DataSourceSecurity : IDataSourceSecurity 9 | { 10 | private readonly IDataSourceSecurity m_source; 11 | 12 | public DataSourceSecurity(IDataSourceSecurity source) 13 | { 14 | m_source = source ?? throw new ArgumentNullException(nameof(source)); 15 | } 16 | 17 | public string ToString(string format, IFormatProvider formatProvider) 18 | { 19 | throw new NotSupportedException(); 20 | } 21 | 22 | public string Id => throw new NotSupportedException(); 23 | 24 | public string Name => throw new NotSupportedException(); 25 | 26 | public string FullName => throw new NotSupportedException(); 27 | 28 | public string Comment => throw new NotSupportedException(); 29 | 30 | public string Currency => throw new NotSupportedException(); 31 | 32 | public IDataSourceTradePlace TradePlace => throw new NotSupportedException(); 33 | 34 | public string DSName => m_source.DSName + ".Aligned"; 35 | 36 | public int LotSize => throw new NotSupportedException(); 37 | 38 | public double LotTick => throw new NotSupportedException(); 39 | 40 | public double Margin => throw new NotSupportedException(); 41 | 42 | public int Decimals => throw new NotSupportedException(); 43 | 44 | public int BalanceDecimals => throw new NotSupportedException(); 45 | 46 | public double Tick => throw new NotSupportedException(); 47 | 48 | public double GetTick(double price) 49 | { 50 | throw new NotSupportedException(); 51 | } 52 | 53 | public bool Expired => throw new NotSupportedException(); 54 | 55 | public bool IsMoney => throw new NotSupportedException(); 56 | 57 | public ActiveType ActiveType => throw new NotSupportedException(); 58 | 59 | public bool IsOption => throw new NotSupportedException(); 60 | 61 | public IDataSourceSecurity BaseSecurity => throw new NotSupportedException(); 62 | 63 | public double Strike => throw new NotSupportedException(); 64 | 65 | public DateTime ExpirationDate => throw new NotSupportedException(); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /AlignedSecurityHandler.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using TSLab.DataSource; 3 | 4 | using TSLab.Script.Handlers.Options; 5 | 6 | namespace TSLab.Script.Handlers 7 | { 8 | // TODO: английское описание 9 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 10 | [HelperName("Aligned instrument", Language = Constants.En)] 11 | [HelperName("Выровненный инструмент", Language = Constants.Ru)] 12 | [InputsCount(1)] 13 | [Input(0, TemplateTypes.SECURITY, Name = Constants.SecuritySource)] 14 | [OutputsCount(1)] 15 | [OutputType(TemplateTypes.SECURITY)] 16 | [Description("Блок 'Выровненный инструмент' обеспечивает отображение гистограмм одинаковой ширины вне зависимости от фактического количества свечей в графике.")] 17 | [HelperDescription("", Constants.En)] 18 | public sealed class AlignedSecurityHandler : IAlignedSecurityHandler 19 | { 20 | /// 21 | /// \~english Timeframe (integer value in units of parameter 'Timeframe units') 22 | /// \~russian Интервал (целое число в единицах параметра 'База интервала') 23 | /// 24 | [HelperName("Timeframe", Constants.En)] 25 | [HelperName("Интервал", Constants.Ru)] 26 | [Description("Интервал (целое число в единицах параметра 'База интервала')")] 27 | [HelperDescription("Timeframe (integer value in units of parameter 'Timeframe units')", Constants.En)] 28 | [HandlerParameter(true, "1", Min = "1", Max = "365", Step = "1")] 29 | public int TimeFrame { get; set; } 30 | 31 | /// 32 | /// \~english Timeframe units (second, minute, hour, day) 33 | /// \~russian База интервала (секунды, минуты, часы, дни) 34 | /// 35 | [HelperName("Timeframe units", Constants.En)] 36 | [HelperName("База интервала", Constants.Ru)] 37 | [Description("База интервала (секунды, минуты, часы, дни)")] 38 | [HelperDescription("Timeframe units (second, minute, hour, day)", Constants.En)] 39 | [HandlerParameter(true, nameof(TimeFrameUnit.Hour))] 40 | public TimeFrameUnit TimeFrameUnit { get; set; } 41 | 42 | public ISecurity Execute(ISecurity security) 43 | { 44 | var timeFrame = TimeFrameFactory.Create(TimeFrame, TimeFrameUnit); 45 | return new AlignedSecurity(security, timeFrame); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /AllTimeTradeStatisticsHandler.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using TSLab.Script.Handlers.Options; 3 | 4 | namespace TSLab.Script.Handlers 5 | { 6 | // TODO: английское описание 7 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 8 | [HelperName("All Time Trade Statistics", Language = Constants.En)] 9 | [HelperName("Торговая статистика за всё время", Language = Constants.Ru)] 10 | [InputsCount(1)] 11 | [Input(0, TemplateTypes.SECURITY, Name = Constants.SecuritySource)] 12 | [OutputsCount(1)] 13 | [OutputType(TemplateTypes.TRADE_STATISTICS)] 14 | [Description("Блок 'Торговая статистика за всё время' создает гистограмму на основе всего доступного временного интервала. " + 15 | "[br]Гистограмма может быть построена на количестве сделок, объеме торгов, количестве покупок, количестве продаж, разнице количества покупок и продаж и относительной разнице количества покупок и продаж, % (см. параметр 'Вид').")] 16 | [HelperDescription("", Constants.En)] 17 | public sealed class AllTimeTradeStatisticsHandler : BaseTradeStatisticsHandler, IAllTimeTradeStatisticsHandler 18 | { 19 | /// 20 | /// \~english A width of a hystogram relative to a width of a chart pane. 21 | /// \~russian Ширина гистограммы в процентах относительно ширины панели графика. 22 | /// 23 | [HelperName("Width, %", Constants.En)] 24 | [HelperName("Ширина, %", Constants.Ru)] 25 | [Description("Ширина гистограммы в процентах относительно ширины панели графика.")] 26 | [HelperDescription("A width of a hystogram relative to a width of a chart pane.", Constants.En)] 27 | [HandlerParameter(true, "10", Min = "1", Max = "100", Step = "1", EditorMin = "1", EditorMax = "100")] 28 | public override double WidthPercent { get; set; } 29 | 30 | public override ITradeStatisticsWithKind Execute(ISecurity security) 31 | { 32 | var runTime = Context.Runtime; 33 | var id = runTime != null ? string.Join(".", runTime.TradeName, runTime.IsAgentMode, VariableId) : VariableId; 34 | var stateId = string.Join(".", security.Symbol, security.Interval, security.IsAligned, CombinePricesCount); 35 | var tradeStatistics = Context.GetTradeStatistics(stateId, () => TradeStatisticsCache.Instance.GetAllTimeTradeStatistics(id, stateId, GetTradeHistogramsCache(security))); 36 | return new AllTimeTradeStatisticsWithKind(tradeStatistics, Kind, WidthPercent); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /BarNumber.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | 6 | using TSLab.Script.Handlers.Options; 7 | 8 | namespace TSLab.Script.Handlers 9 | { 10 | // TODO: правильней назвать кубик Bar INDEX или Index of the bar 11 | [HandlerCategory(HandlerCategories.TradeMath)] 12 | [HelperName("Bar number", Language = Constants.En)] 13 | [HelperName("Номер бара", Language = Constants.Ru)] 14 | [InputsCount(1)] 15 | [Input(0, TemplateTypes.SECURITY | TemplateTypes.DOUBLE | TemplateTypes.INT | TemplateTypes.BOOL)] 16 | [OutputsCount(1)] 17 | [OutputType(TemplateTypes.DOUBLE)] 18 | [Description("Индекс элемента в списке баров или числовых значений.")] 19 | [HelperDescription("An index of an element in a list of bars or numeric values.", Constants.En)] 20 | public sealed class BarNumber : IOneSourceHandler, IDoubleReturns, IStreamHandler, ISecurityInputs, IDoubleInputs, IIntInputs, IBooleanInputs 21 | { 22 | /// 23 | /// Рудиментарная реализация интерфейса IList[double], которая для экономии памяти и повышения скорости 24 | /// обеспечивает только минимальный функционал. В качестве 'элементов' выступают индексы исходного списка баров. 25 | /// 26 | private sealed class IndexList : IList 27 | { 28 | public IndexList(int count) 29 | { 30 | Count = count; 31 | } 32 | 33 | public IEnumerator GetEnumerator() 34 | { 35 | for (var i = 0; i < Count; i++) 36 | yield return i; 37 | } 38 | 39 | IEnumerator IEnumerable.GetEnumerator() 40 | { 41 | return GetEnumerator(); 42 | } 43 | 44 | public void Add(double item) 45 | { 46 | throw new NotSupportedException(); 47 | } 48 | 49 | public void Clear() 50 | { 51 | throw new NotSupportedException(); 52 | } 53 | 54 | public bool Contains(double item) 55 | { 56 | return IndexOf(item) >= 0; 57 | } 58 | 59 | public void CopyTo(double[] array, int arrayIndex) 60 | { 61 | throw new NotSupportedException(); 62 | } 63 | 64 | public bool Remove(double item) 65 | { 66 | throw new NotSupportedException(); 67 | } 68 | 69 | public int Count { get; } 70 | 71 | public bool IsReadOnly 72 | { 73 | get { return true; } 74 | } 75 | 76 | public int IndexOf(double item) 77 | { 78 | var indexOf = (int)item; 79 | if (item != indexOf) 80 | throw new ArgumentException(nameof(item)); 81 | 82 | return indexOf >= 0 && indexOf < Count ? indexOf : -1; 83 | } 84 | 85 | public void Insert(int index, double item) 86 | { 87 | throw new NotSupportedException(); 88 | } 89 | 90 | public void RemoveAt(int index) 91 | { 92 | throw new NotSupportedException(); 93 | } 94 | 95 | public double this[int index] 96 | { 97 | get 98 | { 99 | if (index >= 0 && index < Count) 100 | return index; 101 | 102 | throw new ArgumentOutOfRangeException(nameof(index)); 103 | } 104 | set { throw new NotSupportedException(); } 105 | } 106 | } 107 | 108 | public IList Execute(ISecurity security) 109 | { 110 | return new IndexList(security.Bars.Count); 111 | } 112 | 113 | public IList Execute(IList security) 114 | { 115 | return new IndexList(security.Count); 116 | } 117 | 118 | public IList Execute(IList security) 119 | { 120 | return new IndexList(security.Count); 121 | } 122 | 123 | public IList Execute(IList security) 124 | { 125 | return new IndexList(security.Count); 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /BarsCountForValuesSumHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using TSLab.Script.Handlers.Options; 5 | using TSLab.Utils; 6 | 7 | namespace TSLab.Script.Handlers 8 | { 9 | [HandlerCategory(HandlerCategories.Indicators)] 10 | [HelperName("Bars count for values sum", Language = Constants.En)] 11 | [HelperName("Количество баров для суммы значений", Language = Constants.Ru)] 12 | [Description("Количество баров для суммы значений")] 13 | [HelperDescription("Bars count for values sum", Constants.En)] 14 | public sealed class BarsCountForValuesSumHandler : DoubleStreamAndValuesHandler 15 | { 16 | private double[] m_source; 17 | 18 | public override bool IsGapTolerant => false; 19 | 20 | /// 21 | /// \~english Indicator values sum 22 | /// \~russian Сумма значений индикатора 23 | /// 24 | [HelperName("Values sum", Constants.En)] 25 | [HelperName("Сумма значений", Constants.Ru)] 26 | [Description("Сумма значений индикатора")] 27 | [HelperDescription("Indicator values sum", Constants.En)] 28 | [HandlerParameter(true, "1", Min = "0", Max = "2147483647", Step = "1", EditorMin = "1")] 29 | public double ValuesSum { get; set; } 30 | 31 | public override IList Execute(IList source) 32 | { 33 | if (source == null) 34 | throw new ArgumentNullException(nameof(source)); 35 | 36 | if (source.Count == 0) 37 | return EmptyArrays.Double; 38 | 39 | var results = Context.GetArray(source.Count); 40 | for (var i = 0; i < source.Count; i++) 41 | results[i] = Calculate(source, i); 42 | 43 | return results; 44 | } 45 | 46 | protected override void InitExecuteContext() 47 | { 48 | m_source = Context.GetArray(Context.BarsCount); 49 | } 50 | 51 | protected override void ClearExecuteContext() 52 | { 53 | Context.ReleaseArray(m_source); 54 | m_source = null; 55 | } 56 | 57 | protected override void InitForGap() 58 | { 59 | for (var i = m_executeContext.LastIndex; i < m_executeContext.Index; i++) 60 | m_source[i] = m_executeContext.GetSourceForGap(i); 61 | } 62 | 63 | protected override double Execute() 64 | { 65 | var index = m_executeContext.Index; 66 | m_source[index] = m_executeContext.Source; 67 | return Calculate(m_source, index); 68 | } 69 | 70 | private double Calculate(IList source, int index) 71 | { 72 | var valuesSum = 0D; 73 | for (var j = index; j >= 0; j--) 74 | { 75 | valuesSum += source[j]; 76 | if (valuesSum >= ValuesSum) 77 | return index - j + 1; 78 | } 79 | return 0; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /BaseTradeStatisticsHandler.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using TSLab.Script.Handlers.Options; 3 | 4 | namespace TSLab.Script.Handlers 5 | { 6 | //[HandlerCategory(HandlerCategories.ClusterAnalysis)] 7 | // Не стоит навешивать на абстрактные классы атрибуты категорий и описания входов/выходов. Это снижает гибкость управления в перспективе. 8 | public abstract class BaseTradeStatisticsHandler : IBaseTradeStatisticsHandler 9 | where TTradeStatisticsWithKind : IBaseTradeStatisticsWithKind 10 | { 11 | public string VariableId { get; set; } = string.Empty; 12 | 13 | public IContext Context { get; set; } 14 | 15 | /// 16 | /// \~english How many price steps should be grouped together. 17 | /// \~russian Осуществление выбора шага цены, используемого для группировки цен. 18 | /// 19 | [HelperName("Combine price steps", Constants.En)] 20 | [HelperName("Объединять шаги цены", Constants.Ru)] 21 | [Description("Осуществление выбора шага цены, используемого для группировки цен.")] 22 | [HelperDescription("How many price steps should be grouped together.", Constants.En)] 23 | [HandlerParameter(true, "1", Min = "1", Max = "10", Step = "1", EditorMin = "1")] 24 | public int CombinePricesCount { get; set; } 25 | 26 | /// 27 | /// \~english Kind of a trade statistics (trades count, trade volume, buy count, sell count, buy and sell difference, relative buy and sell difference). 28 | /// \~russian Вид торговой статистики (количество сделок, объем торгов, количество покупок, количество продаж, разница количества покупок и продаж, относительная разница количества покупок и продаж). 29 | /// 30 | [HelperName("Kind", Constants.En)] 31 | [HelperName("Вид", Constants.Ru)] 32 | [Description("Вид торговой статистики (количество сделок, объем торгов, количество покупок, количество продаж, разница количества покупок и продаж, относительная разница количества покупок и продаж).")] 33 | [HelperDescription("Kind of a trade statistics (trades count, trade volume, buy count, sell count, buy and sell difference, relative buy and sell difference).", Constants.En)] 34 | [HandlerParameter(true, nameof(TradeStatisticsKind.TradesCount))] 35 | public TradeStatisticsKind Kind { get; set; } 36 | 37 | /// 38 | /// \~english A width of a hystogram relative to a width of a chart pane. 39 | /// \~russian Ширина гистограммы в процентах относительно ширины панели графика. 40 | /// 41 | [HelperName("Width, %", Constants.En)] 42 | [HelperName("Ширина, %", Constants.Ru)] 43 | [Description("Ширина гистограммы в процентах относительно ширины панели графика.")] 44 | [HelperDescription("A width of a hystogram relative to a width of a chart pane.", Constants.En)] 45 | [HandlerParameter(true, "100", Min = "1", Max = "100", Step = "1", EditorMin = "1", EditorMax = "100")] 46 | public virtual double WidthPercent { get; set; } 47 | 48 | public abstract TTradeStatisticsWithKind Execute(ISecurity security); 49 | 50 | protected ITradeHistogramsCache GetTradeHistogramsCache(ISecurity security) 51 | { 52 | var result = TradeHistogramsCaches.Instance.GetTradeHistogramsCache(Context, security, CombinePricesCount); 53 | return result; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /BuysHandler.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using TSLab.Script.Handlers.Options; 3 | 4 | namespace TSLab.Script.Handlers 5 | { 6 | [HandlerCategory(HandlerCategories.VolumeAnalysis)] 7 | [HelperName("Buys", Language = Constants.En)] 8 | [HelperName("Покупки", Language = Constants.Ru)] 9 | [InputsCount(1)] 10 | [Input(0, TemplateTypes.SECURITY, Name = Constants.SecuritySource)] 11 | [OutputsCount(1)] 12 | [OutputType(TemplateTypes.DOUBLE)] 13 | [Description("Показывает характеристики (количество или суммарный объем) сделок на покупку")] 14 | [HelperDescription("A handler calculates statistics (amount or total volume) of a long trades", Constants.En)] 15 | public sealed class BuysHandler : BuysSellsHandler 16 | { 17 | protected override double GetValue(ICachedTradeHistogram histogram) 18 | { 19 | return histogram.AskQuantity; 20 | } 21 | 22 | protected override int GetCount(ICachedTradeHistogram histogram) 23 | { 24 | return histogram.AskTradesCount; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /BuysMinusSellsHandler.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using TSLab.Script.Handlers.Options; 3 | 4 | namespace TSLab.Script.Handlers 5 | { 6 | [HandlerCategory(HandlerCategories.VolumeAnalysis)] 7 | [HelperName("Buys Minus Sells", Language = Constants.En)] 8 | [HelperName("Покупки минус продажи", Language = Constants.Ru)] 9 | [InputsCount(1)] 10 | [Input(0, TemplateTypes.SECURITY, Name = Constants.SecuritySource)] 11 | [OutputsCount(1)] 12 | [OutputType(TemplateTypes.DOUBLE)] 13 | [Description("Показывает разницу характеристик (количество или суммарный объем) сделок на покупку и на продажу")] 14 | [HelperDescription("A handler calculates statistics difference (amount or total volume) of a long and short trades", Constants.En)] 15 | public sealed class BuysMinusSellsHandler : BuysSellsHandler 16 | { 17 | protected override double GetValue(ICachedTradeHistogram histogram) 18 | { 19 | return histogram.DeltaAskBidQuantity; 20 | } 21 | 22 | protected override int GetCount(ICachedTradeHistogram histogram) 23 | { 24 | return histogram.AskTradesCount - histogram.BidTradesCount; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /BuysSellsHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using TSLab.Script.Handlers.Options; 5 | using TSLab.Utils; 6 | 7 | namespace TSLab.Script.Handlers 8 | { 9 | //[HandlerCategory(HandlerCategories.VolumeAnalysis)] 10 | // Не стоит навешивать на абстрактные классы атрибуты категорий и описания входов/выходов. Это снижает гибкость управления в перспективе. 11 | public abstract class BuysSellsHandler : IBuysSellsHandler 12 | { 13 | public IContext Context { get; set; } 14 | 15 | /// 16 | /// \~english Market volume quantity units (shares, lots, trades count) 17 | /// \~russian Режим отображения рыночной статистики (объем, лоты, количество сделок) 18 | /// 19 | [HelperName("Quantity units", Constants.En)] 20 | [HelperName("Единицы объема", Constants.Ru)] 21 | [Description("Режим отображения рыночной статистики (объем, лоты, количество сделок)")] 22 | [HelperDescription("Market volume quantity units (shares, lots, trades count)", Constants.En)] 23 | [HandlerParameter(true, nameof(QuantityMode.Quantity))] 24 | public QuantityMode QuantityMode { get; set; } 25 | 26 | public IList Execute(ISecurity security) 27 | { 28 | if (security == null) 29 | throw new ArgumentNullException(nameof(security)); 30 | 31 | var quantityMode = QuantityMode; 32 | if (quantityMode != QuantityMode.Quantity && quantityMode != QuantityMode.QuantityInLots && quantityMode != QuantityMode.TradesCount) 33 | throw new InvalidEnumArgumentException(nameof(QuantityMode), (int)quantityMode, quantityMode.GetType()); 34 | 35 | var barsCount = security.Bars.Count; 36 | if (barsCount == 0) 37 | return EmptyArrays.Double; 38 | 39 | var results = Context?.GetArray(barsCount) ?? new double[barsCount]; 40 | var tradeHistogramsCache = TradeHistogramsCaches.Instance.GetTradeHistogramsCache(Context, security, 0); 41 | 42 | if (quantityMode == QuantityMode.Quantity) 43 | for (var i = 0; i < barsCount; i++) 44 | results[i] = GetValue(tradeHistogramsCache.GetHistogram(i)); 45 | else if (quantityMode == QuantityMode.QuantityInLots) 46 | for (var i = 0; i < barsCount; i++) 47 | results[i] = GetValue(tradeHistogramsCache.GetHistogram(i)) / security.LotSize; 48 | else 49 | for (var i = 0; i < barsCount; i++) 50 | results[i] = GetCount(tradeHistogramsCache.GetHistogram(i)); 51 | 52 | return results; 53 | } 54 | 55 | protected abstract double GetValue(ICachedTradeHistogram histogram); 56 | 57 | protected abstract int GetCount(ICachedTradeHistogram histogram); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ConstGen.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tslab-hub/handlers/16c33a92bb1c15861c95f05463ee2b348379770b/ConstGen.cs -------------------------------------------------------------------------------- /ConstList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace TSLab.Script.Handlers 6 | { 7 | internal sealed class ConstList : IList, IReadOnlyList 8 | { 9 | private static readonly IEqualityComparer s_equalityComparer = EqualityComparer.Default; 10 | private readonly T m_value; 11 | 12 | public ConstList(int count, T value) 13 | { 14 | if (count < 0) 15 | throw new ArgumentOutOfRangeException(nameof(count)); 16 | 17 | Count = count; 18 | m_value = value; 19 | } 20 | 21 | public IEnumerator GetEnumerator() 22 | { 23 | for (var i = 0; i < Count; i++) 24 | yield return m_value; 25 | } 26 | 27 | IEnumerator IEnumerable.GetEnumerator() 28 | { 29 | return GetEnumerator(); 30 | } 31 | 32 | public void Add(T item) 33 | { 34 | throw new NotSupportedException(); 35 | } 36 | 37 | public void Clear() 38 | { 39 | throw new NotSupportedException(); 40 | } 41 | 42 | public bool Contains(T item) 43 | { 44 | return Count > 0 && s_equalityComparer.Equals(m_value, item); 45 | } 46 | 47 | public void CopyTo(T[] array, int arrayIndex) 48 | { 49 | throw new NotSupportedException(); 50 | } 51 | 52 | public bool Remove(T item) 53 | { 54 | throw new NotSupportedException(); 55 | } 56 | 57 | public int Count { get; } 58 | 59 | public bool IsReadOnly => true; 60 | 61 | public int IndexOf(T item) 62 | { 63 | return Contains(item) ? 0 : -1; 64 | } 65 | 66 | public void Insert(int index, T item) 67 | { 68 | throw new NotSupportedException(); 69 | } 70 | 71 | public void RemoveAt(int index) 72 | { 73 | throw new NotSupportedException(); 74 | } 75 | 76 | public T this[int index] 77 | { 78 | get 79 | { 80 | if (index < 0 || index >= Count) 81 | throw new ArgumentOutOfRangeException(nameof(index)); 82 | 83 | return m_value; 84 | } 85 | set { throw new NotSupportedException(); } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /ControlledBoolConst.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | 6 | using TSLab.Script.Handlers.Options; 7 | using TSLab.Utils; 8 | 9 | namespace TSLab.Script.Handlers 10 | { 11 | [HandlerCategory(HandlerCategories.TradeMath)] 12 | [HelperName("Controlled Boolean Constant", Language = Constants.En)] 13 | [HelperName("Управляемая логическая константа", Language = Constants.Ru)] 14 | [InputsCount(1)] 15 | [Input(0, TemplateTypes.BOOL)] 16 | [OutputsCount(1)] 17 | [OutputType(TemplateTypes.BOOL)] 18 | [Description("Управляемая логическая константа (переключатель). При поступлении на вход значения 'Истина' данный блок выдает значение из поля 'Значение', при поступлении на вход значения 'Ложь' используется 'Значение по умолчанию'.")] 19 | [HelperDescription("Controlled boolean constant (switch). If input is TRUE the result is taken from a field 'Value', otherwise the result is taken from a field 'Default value'.", Constants.En)] 20 | public sealed class ControlledBoolConst : IOneSourceHandler, IBooleanReturns, IStreamHandler, IValuesHandler, IBooleanInputs, IContextUses 21 | { 22 | public IContext Context { get; set; } 23 | 24 | /// 25 | /// \~english A value to return as output of a handler when input is true 26 | /// \~russian Значение на выходе блока, если на вход подать 'Истина' 27 | /// 28 | [HelperName("Value", Constants.En)] 29 | [HelperName("Значение", Constants.Ru)] 30 | [Description("Значение на выходе блока, если на вход подать 'Истина'")] 31 | [HelperDescription("A value to return as output of a handler when input is true", Constants.En)] 32 | [HandlerParameter] 33 | public bool Value { get; set; } 34 | 35 | /// 36 | /// \~english A value to return as output of a handler when input is false 37 | /// \~russian Значение на выходе блока, если на вход подать 'Ложь' 38 | /// 39 | [HelperName("Default value", Constants.En)] 40 | [HelperName("Значение по умолчанию", Constants.Ru)] 41 | [Description("Значение на выходе блока, если на вход подать 'Ложь'")] 42 | [HelperDescription("A value to return as output of a handler when input is false", Constants.En)] 43 | [HandlerParameter(NotOptimized = true)] 44 | public bool DefaultValue { get; set; } 45 | 46 | public IList Execute(IList source) 47 | { 48 | if (source == null) 49 | throw new ArgumentNullException(nameof(source)); 50 | 51 | if (source.Count == 0) 52 | return EmptyArrays.Bool; 53 | 54 | var firstValue = source[0]; 55 | if (source.All(item => item == firstValue)) 56 | return new ConstList(source.Count, firstValue ? Value : DefaultValue); 57 | 58 | var result = Context?.GetArray(source.Count) ?? new bool[source.Count]; 59 | for (var i = 0; i < result.Length; i++) 60 | result[i] = source[i] ? Value : DefaultValue; 61 | 62 | return result; 63 | } 64 | 65 | public bool Execute(bool value, int index) 66 | { 67 | return value ? Value : DefaultValue; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /DoubleStreamAndValuesHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | 5 | using TSLab.Script.Handlers.Options; 6 | 7 | namespace TSLab.Script.Handlers 8 | { 9 | public abstract class DoubleStreamAndValuesHandler : IDoubleStreamAndValuesHandler 10 | { 11 | protected sealed class ExecuteContext 12 | { 13 | private double m_a; 14 | private double m_b; 15 | 16 | public double Source { get; set; } 17 | public int Index { get; set; } 18 | public double LastResult { get; set; } 19 | public double LastSource { get; set; } 20 | public int LastIndex { get; set; } 21 | 22 | public void InitForGap() 23 | { 24 | if (LastIndex < 0) 25 | { 26 | m_a = 0; 27 | m_b = Source; 28 | } 29 | else 30 | { 31 | m_a = (LastSource - Source) / (LastIndex - Index); 32 | m_b = LastSource - m_a * LastIndex; 33 | } 34 | } 35 | 36 | public double GetSourceForGap(int i) 37 | { 38 | var source = m_a * i + m_b; 39 | return source; 40 | } 41 | } 42 | 43 | protected ExecuteContext m_executeContext; 44 | 45 | public IContext Context { get; set; } 46 | 47 | public abstract bool IsGapTolerant { get; } 48 | 49 | public abstract IList Execute(IList source); 50 | 51 | public double Execute(double source, int index) 52 | { 53 | if (index < 0 || index >= Context.BarsCount) 54 | throw new ArgumentOutOfRangeException(nameof(index)); 55 | 56 | if (m_executeContext != null) 57 | { 58 | if (index < m_executeContext.LastIndex) 59 | throw new ArgumentException(nameof(index)); 60 | 61 | if (index == m_executeContext.LastIndex) 62 | return m_executeContext.LastResult; 63 | 64 | m_executeContext.Source = source; 65 | m_executeContext.Index = index; 66 | } 67 | else 68 | { 69 | m_executeContext = new ExecuteContext { Source = source, Index = index, LastIndex = -1 }; 70 | InitExecuteContext(); 71 | } 72 | if (index - m_executeContext.LastIndex > 1) 73 | { 74 | m_executeContext.InitForGap(); 75 | InitForGap(); 76 | } 77 | m_executeContext.LastResult = Execute(); 78 | m_executeContext.LastSource = source; 79 | m_executeContext.LastIndex = index; 80 | 81 | if (index == Context.BarsCount - 1) 82 | ClearExecuteContext(); 83 | 84 | return m_executeContext.LastResult; 85 | } 86 | 87 | protected abstract void InitExecuteContext(); 88 | 89 | protected abstract void ClearExecuteContext(); 90 | 91 | protected abstract void InitForGap(); 92 | 93 | protected abstract double Execute(); 94 | } 95 | 96 | public abstract class DoubleStreamAndValuesHandlerWithPeriod : DoubleStreamAndValuesHandler, IDoubleStreamAndValuesHandlerWithPeriod 97 | { 98 | protected const int GapTolerancePeriodMultiplier = 2; 99 | private int m_period = 1; 100 | 101 | /// 102 | /// \~english Indicator period (processing window) 103 | /// \~russian Период индикатора (окно расчетов) 104 | /// 105 | [HelperName("Period", Constants.En)] 106 | [HelperName("Период", Constants.Ru)] 107 | [Description("Период индикатора (окно расчетов)")] 108 | [HelperDescription("Indicator period (processing window)", Constants.En)] 109 | [HandlerParameter(true, "20", Min = "10", Max = "100", Step = "5", EditorMin = "1")] 110 | public int Period 111 | { 112 | get { return m_period; } 113 | set { m_period = Math.Max(value, 1); } 114 | } 115 | 116 | protected virtual bool IsSimple 117 | { 118 | get { return Period == 1 || Context.BarsCount == 1; } 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /ExtremePos.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using TSLab.Script.Handlers.Options; 4 | using TSLab.Script.Helpers; 5 | 6 | namespace TSLab.Script.Handlers 7 | { 8 | /// 9 | /// Базовый класс для группы кубиков, которые вычисляют сколько прошло баров с предыдущего экстремума 10 | /// 11 | [HandlerCategory(HandlerCategories.TradeMath)] 12 | [InputsCount(1)] 13 | [Input(0, TemplateTypes.DOUBLE)] 14 | [OutputsCount(1)] 15 | [OutputType(TemplateTypes.DOUBLE)] 16 | public abstract class ExtremePos : IDouble2DoubleHandler, IContextUses 17 | { 18 | public IContext Context { get; set; } 19 | 20 | /// 21 | /// \~english Indicator period (processing window) 22 | /// \~russian Период индикатора (окно расчетов) 23 | /// 24 | [HelperName("Period", Constants.En)] 25 | [HelperName("Период", Constants.Ru)] 26 | [Description("Период индикатора (окно расчетов)")] 27 | [HelperDescription("Indicator period (processing window)", Constants.En)] 28 | [HandlerParameter(true, "20", Min = "10", Max = "100", Step = "5", EditorMin = "1")] 29 | public int Period { get; set; } 30 | 31 | public IList Execute(IList source) 32 | { 33 | var extremeValues = GetExtremeValues(source); 34 | var result = Context?.GetArray(source.Count) ?? new double[source.Count]; 35 | 36 | for (var i = 1; i < result.Length; i++) 37 | { 38 | var k = 0; 39 | while (i - k >= 0 && extremeValues[i] != source[i - k]) 40 | k++; 41 | 42 | result[i] = k; 43 | } 44 | return result; 45 | } 46 | 47 | protected abstract IList GetExtremeValues(IList source); 48 | } 49 | 50 | //[HandlerCategory(HandlerCategories.TradeMath)] 51 | // Категория и описание входов/выходов идет через базовый класс. 52 | [HelperName("Bars since last high", Language = Constants.En)] 53 | [HelperName("Баров с последнего максимума", Language = Constants.Ru)] 54 | [Description("Количество баров, прошедшее с момента последнего обновления максимума.")] 55 | [HelperDescription("The number of bars since the latest high.", Constants.En)] 56 | public sealed class HighestPos : ExtremePos 57 | { 58 | protected override IList GetExtremeValues(IList source) 59 | { 60 | return Series.Highest(source, Period, Context); 61 | } 62 | } 63 | 64 | //[HandlerCategory(HandlerCategories.TradeMath)] 65 | // Категория и описание входов/выходов идет через базовый класс. 66 | [HelperName("Bars since last low", Language = Constants.En)] 67 | [HelperName("Баров с последнего минимума", Language = Constants.Ru)] 68 | [Description("Количество баров, прошедшее с момента последнего обновления минимума.")] 69 | [HelperDescription("The number of bars since the latest low.", Constants.En)] 70 | public sealed class LowestPos : ExtremePos 71 | { 72 | protected override IList GetExtremeValues(IList source) 73 | { 74 | return Series.Lowest(source, Period, Context); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /FinInfoHandlers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | 5 | using TSLab.DataSource; 6 | using TSLab.Script.Handlers.Options; 7 | using TSLab.Utils; 8 | 9 | namespace TSLab.Script.Handlers 10 | { 11 | /// 12 | /// Базовый класс для группы кубиков, которые используют FinInfo 13 | /// 14 | [HandlerCategory(HandlerCategories.TradeMath)] 15 | [InputsCount(1)] 16 | [Input(0, TemplateTypes.SECURITY, Name = Constants.SecuritySource)] 17 | [OutputsCount(1)] 18 | [OutputType(TemplateTypes.DOUBLE)] 19 | public abstract class FinInfoHandler : IBar2DoubleHandler//, IContextUses 20 | { 21 | //public IContext Context { get; set; } 22 | 23 | public IList Execute(ISecurity source) 24 | { 25 | return new ConstList(source.Bars.Count, GetValue(source.FinInfo) ?? 0); 26 | } 27 | 28 | protected abstract double? GetValue(FinInfo finInfo); 29 | } 30 | 31 | // Категория и описание входов/выходов идет через базовый класс. 32 | [HelperName("Number of purchases", Language = Constants.En)] 33 | [HelperName("СумСпрос", Language = Constants.Ru)] 34 | [Description("Суммарное текущее количество заявок на покупку. Эта же величина показывается в таблице 'Котировки'.")] 35 | [HelperDescription("Shows the number of purchases (bids). This value is shown also in 'Quotes' table.", Constants.En)] 36 | public sealed class BuyCount : FinInfoHandler 37 | { 38 | protected override double? GetValue(FinInfo finInfo) 39 | { 40 | return finInfo.BuyCount; 41 | } 42 | } 43 | 44 | // Категория и описание входов/выходов идет через базовый класс. 45 | [HelperName("Number of sales", Language = Constants.En)] 46 | [HelperName("СумПредл", Language = Constants.Ru)] 47 | [Description("Суммарное текущее количество заявок на продажу. Эта же величина показывается в таблице 'Котировки'.")] 48 | [HelperDescription("Shows the number of sales (asks). This value is shown also in 'Quotes' table.", Constants.En)] 49 | public sealed class SellCount : FinInfoHandler 50 | { 51 | protected override double? GetValue(FinInfo finInfo) 52 | { 53 | return finInfo.SellCount; 54 | } 55 | } 56 | 57 | // Гарантийные обязательства покупателя 58 | public sealed class BuyDeposit : FinInfoHandler 59 | { 60 | protected override double? GetValue(FinInfo finInfo) 61 | { 62 | return finInfo.BuyDeposit; 63 | } 64 | } 65 | 66 | // Гарантийные обязательства продавца 67 | public sealed class SellDeposit : FinInfoHandler 68 | { 69 | protected override double? GetValue(FinInfo finInfo) 70 | { 71 | return finInfo.SellDeposit; 72 | } 73 | } 74 | 75 | // Категория и описание входов/выходов идет через базовый класс. 76 | [HelperName("Price step", Language = Constants.En)] 77 | [HelperName("Шаг цены", Language = Constants.Ru)] 78 | [Description("Шаг цены инструмента. Эта же величина показывается в таблице 'Котировки'.")] 79 | [HelperDescription("Price step of a security. This value is shown also in 'Quotes' table.", Constants.En)] 80 | public sealed class Tick : FinInfoHandler 81 | { 82 | protected override double? GetValue(FinInfo finInfo) 83 | { 84 | if (finInfo == null || finInfo.Security == null) 85 | return 1; 86 | 87 | var lastPrice = finInfo.LastPrice ?? 0.0; 88 | var tick = finInfo.Security.GetTick(lastPrice); 89 | if (!DoubleUtil.IsPositive(tick)) 90 | tick = Math.Pow(10, -finInfo.Security.Decimals); 91 | 92 | return tick; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /HoldSignalForNBars.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | 6 | using TSLab.Script.Handlers.Options; 7 | 8 | namespace TSLab.Script.Handlers 9 | { 10 | [HandlerCategory(HandlerCategories.Position)] 11 | [HelperName("Hold signal for N bars", Language = Constants.En)] 12 | [HelperName("Удерживать сигнал N баров", Language = Constants.Ru)] 13 | [InputsCount(1)] 14 | [Input(0, TemplateTypes.BOOL)] 15 | [OutputsCount(1)] 16 | [OutputType(TemplateTypes.BOOL)] 17 | [Description("Удерживает сигнал 'Истина' в течение заданного количества баров после его появления.")] 18 | [HelperDescription("Holds a signal TRUE for some number of bars.", Constants.En)] 19 | public sealed class HoldSignalForNBars : IOneSourceHandler, IBooleanReturns, IStreamHandler, IBooleanInputs 20 | { 21 | /// 22 | /// \~english Hold signal for N bars 23 | /// \~russian Удерживать сигнал в течение N баров 24 | /// 25 | [HelperName("Bars count", Constants.En)] 26 | [HelperName("Количество баров", Constants.Ru)] 27 | [Description("Количество баров для продления сигнала")] 28 | [HelperDescription("Bars count to hold a signal", Constants.En)] 29 | [HandlerParameter(true, "0", Min = "0", Max = "10", Step = "1", EditorMin = "0")] 30 | public int NBars { get; set; } 31 | 32 | public IList Execute(IList source) 33 | { 34 | if (NBars <= 0 || source.Count <= 1 || source.All(item => item) || source.All(item => !item)) 35 | return source; 36 | 37 | var result = new List(source); 38 | for (var i = 0; i < source.Count; i++) 39 | { 40 | if (source[i]) 41 | { 42 | var jMax = Math.Min(i + NBars, source.Count - 1); 43 | for (var j = i + 1; j <= jMax; j++) 44 | result[j] = true; 45 | } 46 | } 47 | return result; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /InteractiveLineGen.BaseList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace TSLab.Script.Handlers 6 | { 7 | public sealed partial class InteractiveLineGen 8 | { 9 | private abstract class BaseList : IList 10 | { 11 | protected BaseList(int count) 12 | : this(count, 0, count - 1) 13 | { 14 | } 15 | 16 | protected BaseList(int count, int minIndex, int maxIndex) 17 | { 18 | if (count == 0) 19 | { 20 | if (minIndex != -1) 21 | throw new ArgumentOutOfRangeException(nameof(minIndex)); 22 | 23 | if (maxIndex != -1) 24 | throw new ArgumentOutOfRangeException(nameof(maxIndex)); 25 | } 26 | else if (count > 0) 27 | { 28 | if (minIndex < 0) 29 | throw new ArgumentOutOfRangeException(nameof(minIndex)); 30 | 31 | if (maxIndex >= count) 32 | throw new ArgumentOutOfRangeException(nameof(maxIndex)); 33 | 34 | if (minIndex > maxIndex) 35 | throw new ArgumentOutOfRangeException(nameof(maxIndex)); 36 | } 37 | else 38 | throw new ArgumentOutOfRangeException(nameof(count)); 39 | 40 | Count = count; 41 | MinIndex = minIndex; 42 | MaxIndex = maxIndex; 43 | } 44 | 45 | public IEnumerator GetEnumerator() 46 | { 47 | if (Count > 0) 48 | { 49 | for (var i = 0; i < MinIndex; i++) 50 | yield return double.NaN; 51 | 52 | for (var i = MinIndex; i <= MaxIndex; i++) 53 | yield return GetValue(i); 54 | 55 | for (var i = MaxIndex + 1; i < Count; i++) 56 | yield return double.NaN; 57 | } 58 | else 59 | yield return double.NaN; 60 | } 61 | 62 | IEnumerator IEnumerable.GetEnumerator() 63 | { 64 | return GetEnumerator(); 65 | } 66 | 67 | public void Add(double item) 68 | { 69 | throw new NotSupportedException(); 70 | } 71 | 72 | public void Clear() 73 | { 74 | throw new NotSupportedException(); 75 | } 76 | 77 | public bool Contains(double item) 78 | { 79 | return IndexOf(item) >= 0; 80 | } 81 | 82 | public void CopyTo(double[] array, int arrayIndex) 83 | { 84 | throw new NotSupportedException(); 85 | } 86 | 87 | public bool Remove(double item) 88 | { 89 | throw new NotSupportedException(); 90 | } 91 | 92 | public int Count { get; } 93 | 94 | public bool IsReadOnly 95 | { 96 | get { return true; } 97 | } 98 | 99 | public abstract int IndexOf(double item); 100 | 101 | public void Insert(int index, double item) 102 | { 103 | throw new NotSupportedException(); 104 | } 105 | 106 | public void RemoveAt(int index) 107 | { 108 | throw new NotSupportedException(); 109 | } 110 | 111 | public double this[int index] 112 | { 113 | get { return index >= MinIndex && index <= MaxIndex ? GetValue(index) : double.NaN; } 114 | set { throw new NotSupportedException(); } 115 | } 116 | 117 | protected int MinIndex { get; } 118 | 119 | protected int MaxIndex { get; } 120 | 121 | protected abstract double GetValue(int index); 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /InteractiveLineGen.ConstList.cs: -------------------------------------------------------------------------------- 1 | namespace TSLab.Script.Handlers 2 | { 3 | public sealed partial class InteractiveLineGen 4 | { 5 | private sealed class ConstList : BaseList 6 | { 7 | private readonly double m_value; 8 | 9 | public ConstList(double value, int count) 10 | : base(count) 11 | { 12 | m_value = value; 13 | } 14 | 15 | public ConstList(double value, int count, int minIndex, int maxIndex) 16 | : base(count, minIndex, maxIndex) 17 | { 18 | m_value = value; 19 | } 20 | 21 | public override int IndexOf(double item) 22 | { 23 | return m_value == item ? MinIndex : -1; 24 | } 25 | 26 | protected override double GetValue(int index) 27 | { 28 | return m_value; 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /InteractiveLineGen.LineList.cs: -------------------------------------------------------------------------------- 1 | namespace TSLab.Script.Handlers 2 | { 3 | public sealed partial class InteractiveLineGen 4 | { 5 | private sealed class LineList : BaseList 6 | { 7 | private readonly double m_a; 8 | private readonly double m_b; 9 | 10 | public LineList(double a, double b, int count, int minIndex, int maxIndex) 11 | : base(count, minIndex, maxIndex) 12 | { 13 | m_a = a; 14 | m_b = b; 15 | } 16 | 17 | public override int IndexOf(double item) 18 | { 19 | var minValue = GetValue(MinIndex); 20 | var maxValue = GetValue(MaxIndex); 21 | 22 | if (minValue > maxValue) 23 | { 24 | var value = minValue; 25 | minValue = maxValue; 26 | maxValue = value; 27 | } 28 | if (item >= minValue && item <= maxValue) 29 | for (var i = MinIndex; i <= MaxIndex; i++) 30 | if (GetValue(i) == item) 31 | return i; 32 | 33 | return -1; 34 | } 35 | 36 | protected override double GetValue(int index) 37 | { 38 | return m_a * index + m_b; 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /InteractiveSeriesHandler.cs: -------------------------------------------------------------------------------- 1 | #if DEBUG 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | 6 | using TSLab.Script.CanvasPane; 7 | using TSLab.Script.Handlers.Options; 8 | 9 | namespace TSLab.Script.Handlers 10 | { 11 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 12 | [HelperName("InteractiveSeriesHandler", Language = Constants.En)] 13 | [HelperName("InteractiveSeriesHandler", Language = Constants.Ru)] 14 | [InputsCount(1)] 15 | [Input(0, TemplateTypes.SECURITY, Name = Constants.SecuritySource)] 16 | [OutputsCount(1)] 17 | [OutputType(TemplateTypes.INTERACTIVESPLINE)] 18 | [Description("БЕЗ ОПИСАНИЯ (кубик виден только в девелоперской версии)")] 19 | [HelperDescription("БЕЗ ОПИСАНИЯ (кубик виден только в девелоперской версии)", Constants.En)] 20 | #if !DEBUG 21 | [HandlerInvisible] 22 | #endif 23 | public sealed class InteractiveSeriesHandler : IOneSourceHandler, IStreamHandler, ISecurityInputs 24 | { 25 | public InteractiveSeries Execute(ISecurity security) 26 | { 27 | var interactiveObjects = new List(); 28 | for (byte i = 0; i < 31; i++) 29 | { 30 | var j = (byte)(i << 3); 31 | var interactivePointActive = new InteractivePointActive(i, i) 32 | { 33 | BackColor = new Color(j, 0, 0), 34 | ForeColor = new Color(0, j, 0), 35 | 36 | IsActive = true, 37 | Label = i.ToString(), 38 | Color = new AlphaColor(255, j, 0, 0), 39 | DateTime = DateTime.UtcNow.AddDays(1), 40 | 41 | ValueXBackColor = new AlphaColor(255, j, 0, 0), 42 | ValueXForeColor = new AlphaColor(255, 0, j, 0), 43 | 44 | ValueYBackColor = new AlphaColor(255, 0, j, 0), 45 | ValueYForeColor = new AlphaColor(255, 0, 0, j), 46 | 47 | DateTimeBackColor = new AlphaColor(255, 0, 0, j), 48 | DateTimeForeColor = new AlphaColor(255, j, 0, 0), 49 | }; 50 | interactiveObjects.Add(new InteractiveObject { Anchor = interactivePointActive }); 51 | } 52 | return new InteractiveSeries(interactiveObjects); 53 | } 54 | } 55 | } 56 | #endif 57 | -------------------------------------------------------------------------------- /LastContractsTradeStatisticsHandler.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using TSLab.Script.Handlers.Options; 3 | 4 | namespace TSLab.Script.Handlers 5 | { 6 | // TODO: английское описание 7 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 8 | [HelperName("Last Contracts Trade Statistics", Language = Constants.En)] 9 | [HelperName("Торговая статистика последних контрактов", Language = Constants.Ru)] 10 | [InputsCount(1)] 11 | [Input(0, TemplateTypes.SECURITY, Name = Constants.SecuritySource)] 12 | [OutputsCount(1)] 13 | [OutputType(TemplateTypes.LAST_CONTRACTS_TRADE_STATISTICS)] 14 | [Description("Блок 'Торговая статистика последних контрактов' создает гистограмму за указанное количество последних контрактов.")] 15 | [HelperDescription("", Constants.En)] 16 | public sealed class LastContractsTradeStatisticsHandler : BaseTradeStatisticsHandler, ILastContractsTradeStatisticsHandler 17 | { 18 | /// 19 | /// \~english A parameter to set contracts count to be used for trade statistics. 20 | /// \~russian Осуществляет выбор количества контрактов, за которые должна отображаться торговая статистика. 21 | /// 22 | [HelperName("Contracts count", Constants.En)] 23 | [HelperName("Количество контрактов", Constants.Ru)] 24 | [Description("Осуществляет выбор количества контрактов, за которые должна отображаться торговая статистика.")] 25 | [HelperDescription("A parameter to set contracts count to be used for trade statistics.", Constants.En)] 26 | [HandlerParameter(true, "10000", Min = "10000", Max = "1000000", Step = "10000", EditorMin = "1")] 27 | public int ContractsCount { get; set; } 28 | 29 | public override ILastContractsTradeStatisticsWithKind Execute(ISecurity security) 30 | { 31 | var runTime = Context.Runtime; 32 | var id = runTime != null ? string.Join(".", runTime.TradeName, runTime.IsAgentMode, VariableId) : VariableId; 33 | var stateId = string.Join(".", security.Symbol, security.Interval, security.IsAligned, CombinePricesCount, ContractsCount); 34 | var tradeStatistics = Context.GetLastContractsTradeStatistics(stateId, () => new LastContractsTradeStatistics(id, stateId, GetTradeHistogramsCache(security), ContractsCount)); 35 | return new LastContractsTradeStatisticsWithKind(tradeStatistics, Kind, WidthPercent); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LastTradeStatisticsHandler.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using TSLab.DataSource; 3 | using TSLab.Script.Handlers.Options; 4 | 5 | namespace TSLab.Script.Handlers 6 | { 7 | // TODO: английское описание 8 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 9 | [HelperName("Last Trade Statistics", Language = Constants.En)] 10 | [HelperName("Последняя торговая статистика", Language = Constants.Ru)] 11 | [InputsCount(1)] 12 | [Input(0, TemplateTypes.SECURITY, Name = Constants.SecuritySource)] 13 | [OutputsCount(1)] 14 | [OutputType(TemplateTypes.TRADE_STATISTICS)] 15 | [Description("Блок 'Последняя торговая статистика' создает гистограмму за указанный временной интервал.")] 16 | [HelperDescription("", Constants.En)] 17 | public sealed class LastTradeStatisticsHandler : BaseTradeStatisticsHandler, ITradeStatisticsHandler 18 | { 19 | [HandlerParameter(true, nameof(TimeFrameKind.FromMidnightToNow))] 20 | public TimeFrameKind TimeFrameKind { get; set; } 21 | 22 | /// 23 | /// \~english Timeframe (integer value in units of parameter 'Timeframe units') 24 | /// \~russian Интервал (целое число в единицах параметра 'База интервала') 25 | /// 26 | [HelperName("Timeframe", Constants.En)] 27 | [HelperName("Интервал", Constants.Ru)] 28 | [Description("Интервал (целое число в единицах параметра 'База интервала')")] 29 | [HelperDescription("Timeframe (integer value in units of parameter 'Timeframe units')", Constants.En)] 30 | [HandlerParameter(true, "1", Min = "1", Max = "365", Step = "1", EditorMin = "1")] 31 | public int TimeFrame { get; set; } 32 | 33 | /// 34 | /// \~english Timeframe units (second, minute, hour, day) 35 | /// \~russian База интервала (секунды, минуты, часы, дни) 36 | /// 37 | [HelperName("Timeframe units", Constants.En)] 38 | [HelperName("База интервала", Constants.Ru)] 39 | [Description("База интервала (секунды, минуты, часы, дни)")] 40 | [HelperDescription("Timeframe units (second, minute, hour, day)", Constants.En)] 41 | [HandlerParameter(true, nameof(TimeFrameUnit.Hour))] 42 | public TimeFrameUnit TimeFrameUnit { get; set; } 43 | 44 | [HandlerParameter(true, "0", Min = "0", Max = "365", Step = "1", EditorMin = "0")] 45 | public int TimeFrameShift { get; set; } 46 | 47 | [HandlerParameter(true, nameof(TimeFrameUnit.Hour))] 48 | public TimeFrameUnit TimeFrameShiftUnit { get; set; } 49 | 50 | public override ITradeStatisticsWithKind Execute(ISecurity security) 51 | { 52 | var timeFrame = TimeFrameFactory.Create(TimeFrame, TimeFrameUnit); 53 | var timeFrameShift = TimeFrameFactory.Create(TimeFrameShift, TimeFrameShiftUnit); 54 | var runTime = Context.Runtime; 55 | var id = runTime != null ? string.Join(".", runTime.TradeName, runTime.IsAgentMode, VariableId) : VariableId; 56 | var stateId = string.Join(".", security.Symbol, security.Interval, security.IsAligned, CombinePricesCount, TimeFrameKind, TimeFrame, TimeFrameUnit, TimeFrameShift, TimeFrameShiftUnit); 57 | var tradeStatistics = Context.GetTradeStatistics(stateId, () => new LastTradeStatistics(id, stateId, GetTradeHistogramsCache(security), TimeFrameKind, timeFrame, TimeFrameUnit, timeFrameShift, TimeFrameShiftUnit)); 58 | return new TradeStatisticsWithKind(tradeStatistics, Kind, WidthPercent); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /MessageHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using TSLab.Script.Handlers.Options; 6 | 7 | namespace TSLab.Script.Handlers 8 | { 9 | [HandlerCategory(HandlerCategories.ServiceElements)] 10 | [HelperName("Message", Language = Constants.En)] 11 | [HelperName("Сообщение", Language = Constants.Ru)] 12 | [InputsCount(1)] 13 | [Input(0, TemplateTypes.BOOL)] 14 | [OutputsCount(0)] 15 | [Description("При появлении на входе блока значения 'Истина' выводит в лог программы пользовательское сообщение.")] 16 | [HelperDescription("When input becomes TRUE a handler sends user message to a TSLab log.", Constants.En)] 17 | public sealed class MessageHandler : IOneSourceHandler, IBooleanReturns, IStreamHandler, IValuesHandlerWithNumber, IBooleanInputs, IContextUses 18 | { 19 | private const string UserMessageTag = "$UserMessageTag"; 20 | 21 | public IContext Context { get; set; } 22 | 23 | /// 24 | /// \~english Message 25 | /// \~russian Текст 26 | /// 27 | [HelperName("Message", Constants.En)] 28 | [HelperName("Текст", Constants.Ru)] 29 | [Description("Текст")] 30 | [HelperDescription("Message", Constants.En)] 31 | [HandlerParameter(true, "", NotOptimized = true)] 32 | public string Message { get; set; } 33 | 34 | /// 35 | /// \~english Additional user tag 36 | /// \~russian Дополнительная пользовательская метка 37 | /// 38 | [HelperName("Tag", Constants.En)] 39 | [HelperName("Метка", Constants.Ru)] 40 | [Description("Дополнительная пользовательская метка")] 41 | [HelperDescription("Additional user tag", Constants.En)] 42 | [HandlerParameter(true, "Tag", NotOptimized = true)] 43 | public string Tag { get; set; } 44 | 45 | /// 46 | /// \~english Message importance (Info, Warning, Error) 47 | /// \~russian Важность сообщения (Info, Warning, Error) 48 | /// 49 | [HelperName("Importance", Constants.En)] 50 | [HelperName("Важность", Constants.Ru)] 51 | [Description("Важность сообщения (Info, Warning, Error)")] 52 | [HelperDescription("Message importance (Info, Warning, Error)", Constants.En)] 53 | [HandlerParameter(true, "Info", NotOptimized = true)] 54 | public MessageType Type { get; set; } 55 | 56 | public void Execute(IList values) 57 | { 58 | if (values == null) 59 | throw new ArgumentNullException(nameof(values)); 60 | 61 | if (values.LastOrDefault()) 62 | Log(); 63 | } 64 | 65 | public void Execute(bool value, int number) 66 | { 67 | if (value && number == Context.BarsCount - (Context.IsLastBarUsed ? 1 : 2)) 68 | Log(); 69 | } 70 | 71 | private void Log() 72 | { 73 | var args = new Dictionary { { UserMessageTag, Tag ?? string.Empty } }; 74 | Context.Log(Message, Type, true, args); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Options/ApproximationAlgo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TSLab.Script.Handlers.Options 4 | { 5 | /// 6 | /// \~english Points interpolation algorythm 7 | /// \~russian Алгоритм интерполяции точек 8 | /// 9 | public enum ApproximationAlgo 10 | { 11 | /// \~english No interpolation (plain table) \~russian Без интерполирования (плоская таблица) 12 | None, 13 | /// \~english Linear interpolation \~russian Линейная интерполяция 14 | Linear, 15 | /// \~english Natural Cubic Spline \~russian Натуральный кубический сплайн 16 | NaturalCubicSpline, 17 | /// \~english Not-a-knot Cubic Spline \~russian Кубический сплайн 'без двух узлов' 18 | NotAKnotCubicSpline, 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Options/BaseCanvasDrawing.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// \~englisg Base class to draw curve on CanvasPane. Main feature -- automatic adaptation to current price, volatility and time to expiry. 8 | /// \~russian Базовый класс для рисования чего угодно на CanvasPane. Главная особенность -- автоматическая привязка к текущей цене БА, волатильности и времени до экспирации. 9 | /// 10 | public abstract class BaseCanvasDrawing : BaseContextHandler 11 | { 12 | protected bool m_showNodes = false; 13 | /// Множитель ширины 14 | protected double m_sigmaMult = 7; 15 | 16 | #region Parameters 17 | /// 18 | /// \~english Width Multiplier 19 | /// \~russian Множитель ширины 20 | /// 21 | [HelperName("Width multiplier", Constants.En)] 22 | [HelperName("Множитель ширины", Constants.Ru)] 23 | [Description("Множитель ширины")] 24 | [HelperDescription("Width multiplier", Constants.En)] 25 | [HandlerParameter(true, NotOptimized = false, IsVisibleInBlock = true, Name = "Sigma Mult", 26 | Default = "7", Min = "0", Max = "1000000", Step = "1", NumberDecimalDigits = 3)] 27 | public double SigmaMult 28 | { 29 | get { return m_sigmaMult; } 30 | set 31 | { 32 | if (value > 0) 33 | m_sigmaMult = value; 34 | } 35 | } 36 | 37 | /// 38 | /// \~english Nodes are shown when true 39 | /// \~russian При true будет показывать узлы на отображаемой линии 40 | /// 41 | [HelperName("Show nodes", Constants.En)] 42 | [HelperName("Показывать узлы", Constants.Ru)] 43 | [Description("При true будет показывать узлы на отображаемой линии")] 44 | [HelperDescription("Nodes are shown when true", Constants.En)] 45 | [HandlerParameter(true, NotOptimized = false, IsVisibleInBlock = true, Default = "false")] 46 | public bool ShowNodes 47 | { 48 | get { return m_showNodes; } 49 | set { m_showNodes = value; } 50 | } 51 | #endregion Parameters 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Options/BaseContextBimodal.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | 5 | namespace TSLab.Script.Handlers.Options 6 | { 7 | /// 8 | /// \~englisg Base class for handlers with stream AND bar processing (implements of BaseContextTemplate, IStreamHandler, IValuesHandlerWithNumber) 9 | /// \~russian Базовый класс для блоков с потоковой И побарной обработкой (реализует BaseContextTemplate, IStreamHandler, IValuesHandlerWithNumber) 10 | /// 11 | public abstract class BaseContextBimodal : BaseContextTemplate, IStreamHandler, IValuesHandlerWithNumber 12 | where T : struct 13 | { 14 | // ReSharper disable once VirtualMemberNeverOverriden.Global 15 | protected virtual IList CommonStreamExecute(string resultsCashKey, string historyCashKey, ISecurity sec, 16 | bool repeatLastValue, bool printInMainLog, bool useGlobalCacheForHistory, params object[] args) 17 | { 18 | if (sec == null) 19 | return new T[0]; 20 | 21 | int len = m_context.BarsCount; 22 | if (len <= 0) 23 | return new T[0]; 24 | 25 | // 1. Извлекаю лист с результатами из ЛОКАЛЬНОГО кеша (настройка useGlobalCacheForHistory только для передачи в функцию CommonExecute) 26 | List results = m_context.LoadObject(resultsCashKey) as List; 27 | if (results == null) 28 | { 29 | results = new List(); 30 | m_context.StoreObject(resultsCashKey, results); 31 | } 32 | 33 | // 3. Выравниваю список, если он слишком длинный 34 | if (results.Count > len) 35 | { 36 | results.RemoveRange(len, results.Count - len); 37 | 38 | Debug.Assert(results.Count == len, "(results.Count != len). It is a mistake #1."); 39 | } 40 | else if (results.Count < len) 41 | { 42 | results.AddRange(new T[len - results.Count]); 43 | 44 | Debug.Assert(results.Count == len, "(results.Count != len). It is a mistake #2."); 45 | } 46 | 47 | // 5. Пошел главный цикл 48 | for (int barNum = 0; barNum < len; barNum++) 49 | { 50 | DateTime now = sec.Bars[barNum].Date; 51 | T t = CommonExecute(historyCashKey, now, repeatLastValue, printInMainLog, useGlobalCacheForHistory, barNum, args); 52 | results[barNum] = t; 53 | } 54 | 55 | return results; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Options/BaseContextWithBlock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | 5 | namespace TSLab.Script.Handlers.Options 6 | { 7 | /// 8 | /// \~englisg Base class for handlers with stream processing (implements of BaseContextTemplate, IStreamHandler) 9 | /// \~russian Базовый класс для блоков с потоковой обработкой (реализует BaseContextTemplate, IStreamHandler) 10 | /// 11 | public abstract class BaseContextWithBlock : BaseContextTemplate, IStreamHandler 12 | where T : struct 13 | { 14 | // ReSharper disable once VirtualMemberNeverOverriden.Global 15 | protected virtual IList CommonStreamExecute(string resultsCashKey, string historyCashKey, ISecurity sec, 16 | bool repeatLastValue, bool printInMainLog, bool useGlobalCacheForHistory, params object[] args) 17 | { 18 | if (sec == null) 19 | return new T[0]; 20 | 21 | int len = m_context.BarsCount; 22 | if (len <= 0) 23 | return new T[0]; 24 | 25 | // 1. Извлекаю лист с результатами из ЛОКАЛЬНОГО кеша (настройка useGlobalCacheForHistory только для передачи в функцию CommonExecute) 26 | List results = m_context.LoadObject(resultsCashKey) as List; 27 | if (results == null) 28 | { 29 | results = new List(); 30 | m_context.StoreObject(resultsCashKey, results); 31 | } 32 | 33 | // 3. Выравниваю список, если он слишком длинный 34 | if (results.Count > len) 35 | { 36 | results.RemoveRange(len, results.Count - len); 37 | 38 | Debug.Assert(results.Count == len, "(results.Count != len). It is a mistake #1."); 39 | } 40 | else if (results.Count < len) 41 | { 42 | results.AddRange(new T[len - results.Count]); 43 | 44 | Debug.Assert(results.Count == len, "(results.Count != len). It is a mistake #2."); 45 | } 46 | 47 | // 5. Пошел главный цикл 48 | for (int barNum = 0; barNum < len; barNum++) 49 | { 50 | DateTime now = sec.Bars[barNum].Date; 51 | T t = CommonExecute(historyCashKey, now, repeatLastValue, printInMainLog, false, barNum, args); 52 | results[barNum] = t; 53 | } 54 | 55 | return results; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Options/BaseContextWithNumber.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TSLab.Script.Handlers.Options 4 | { 5 | /// 6 | /// \~englisg Base class for handlers with barNumber (implements of BaseContextTemplate, IValuesHandlerWithNumber) 7 | /// \~russian Базовый класс для блоков с номером бара (реализует BaseContextTemplate, IValuesHandlerWithNumber) 8 | /// 9 | public abstract class BaseContextWithNumber : BaseContextTemplate, IValuesHandlerWithNumber 10 | where T : struct 11 | { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Options/BasePxMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TSLab.Utils; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// \~english Algorythm to get base asset price 8 | /// \~russian Алгоритм определения цены БА 9 | /// 10 | public enum BasePxMode 11 | { 12 | /// \~english Fixed price \~russian Фиксированная цена 13 | //[LocalizeDisplayName("BasePxMode.FixedPx")] 14 | [LocalizeDescription("BasePxMode.FixedPx")] 15 | FixedPx, 16 | 17 | /// \~english Last trade \~russian Последний трейд в БА 18 | //[LocalizeDisplayName("BasePxMode.LastTrade")] 19 | [LocalizeDescription("BasePxMode.LastTrade")] 20 | LastTrade, 21 | 22 | /// \~english L1 midpoint \~russian Между заявками 23 | //[LocalizeDisplayName("BasePxMode.BidAskMidPoint")] 24 | [LocalizeDescription("BasePxMode.BidAskMidPoint")] 25 | BidAskMidPoint, 26 | 27 | /// \~english Using theoretical option prices \~russian На основании теоретических цен опционов 28 | //[LocalizeDisplayName("BasePxMode.TheorPxBased")] 29 | [LocalizeDescription("BasePxMode.TheorPxBased")] 30 | TheorPxBased, 31 | 32 | // [2015-09-22] Пока неясен алгоритм и значение ни разу не использовалось, отключаю. 33 | ///// \~english Using option quotes L1 \~russian На основании опционных котировок 34 | //OptionBased, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Options/BrokenDefaultParameter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using TSLab.Script.Options; 4 | 5 | namespace TSLab.Script.Handlers.Options 6 | { 7 | /// 8 | /// BrokenDefaultParameter 9 | /// 10 | //[HandlerCategory(Constants.Bugs)] 11 | //[HandlerName("BrokenDefaultParameter")] 12 | //[InputsCount(1)] 13 | //[Input(0, TemplateTypes.OPTION)] 14 | //[OutputsCount(1)] 15 | //[OutputType(TemplateTypes.DOUBLE)] 16 | //[Description("BrokenDefaultParameter")] 17 | public class BrokenDefaultParameter : BaseContextHandler, IValuesHandlerWithNumber 18 | { 19 | protected double m_prevRnd = 3.1415; 20 | protected System.Random m_rnd = new System.Random((int)DateTime.Now.Ticks); 21 | 22 | #region Parameters 23 | //[Description("Rnd")] 24 | //[HandlerParameter(true, NotOptimized = false, IsVisibleInBlock = true, Default = "Просто текст")] 25 | //public double Rnd 26 | //{ 27 | // get { return m_prevRnd; } 28 | // set { } 29 | //} 30 | #endregion Parameters 31 | 32 | public double Execute(IOption opt, int barNumber) 33 | { 34 | m_prevRnd = 100.0 * m_rnd.NextDouble(); 35 | 36 | if (barNumber >= m_context.BarsCount - 1) 37 | { 38 | m_context.Log(String.Format("RND[{0}]: {1}", barNumber, m_prevRnd), MessageType.Warning, true); 39 | } 40 | 41 | return m_prevRnd; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Options/CloseVirtualFutPosition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | using TSLab.Utils; 5 | 6 | namespace TSLab.Script.Handlers.Options 7 | { 8 | /// 9 | /// \~english Close virtual fut position in base asset 10 | /// \~russian Закрыть виртуальную позицию в БА 11 | /// 12 | [HandlerCategory(HandlerCategories.Position)] // Перекидываю в общую категорию работы с позициями 13 | [HelperName("Close Virtual Pos", Language = Constants.En)] 14 | [HelperName("Закрыть вирт. позицию", Language = Constants.Ru)] 15 | [HandlerAlwaysKeep] 16 | [InputsCount(1)] 17 | [Input(0, TemplateTypes.POSITION)] 18 | [OutputsCount(0)] 19 | [Description("Закрыть виртуальную позицию в БА")] 20 | [HelperDescription("Close virtual fut position in base asset", Constants.En)] 21 | public class CloseVirtualFutPosition : IContextUses, IStreamHandler 22 | { 23 | private const string DefaultPx = "125000"; 24 | private const string DefaultTtl = "15"; 25 | 26 | private IContext m_context; 27 | 28 | private double m_timeToLive = Double.Parse(DefaultTtl); 29 | private double m_fixedPx = Double.Parse(DefaultPx); 30 | 31 | public IContext Context 32 | { 33 | get { return m_context; } 34 | set { m_context = value; } 35 | } 36 | 37 | #region Parameters 38 | /// 39 | /// \~english Exit price for virtual futures position 40 | /// \~russian Фиксированная цена закрытия фьючерсной позиции 41 | /// 42 | [HelperName("Fixed Price", Constants.En)] 43 | [HelperName("Фиксированная цена", Constants.Ru)] 44 | [Description("Фиксированная цена закрытия фьючерсной позиции")] 45 | [HelperDescription("Exit price for virtual futures position", Language = Constants.En)] 46 | [HandlerParameter(true, NotOptimized = false, IsVisibleInBlock = true, Default = DefaultPx)] 47 | public double FixedPx 48 | { 49 | get { return m_fixedPx; } 50 | set { m_fixedPx = value; } 51 | } 52 | 53 | /// 54 | /// \~english Position lifetime (in minutes) 55 | /// \~russian Время жизни позиции (в минутах) 56 | /// 57 | [HelperName("Time to Live", Constants.En)] 58 | [HelperName("Время жизни", Constants.Ru)] 59 | [Description("Время жизни позиции (в минутах)")] 60 | [HelperDescription("Position lifetime (in minutes)", Language = Constants.En)] 61 | [HandlerParameter(true, NotOptimized = false, IsVisibleInBlock = true, Default = DefaultTtl)] 62 | public double TimeToLive 63 | { 64 | get { return m_timeToLive; } 65 | set { m_timeToLive = value; } 66 | } 67 | #endregion Parameters 68 | 69 | /// 70 | /// Метод под флаг TemplateTypes.POSITION, чтобы подключаться к источнику-позиции 71 | /// 72 | public void Execute(IPosition pos) 73 | { 74 | if (pos == null) 75 | return; 76 | 77 | int len = pos.Security.Bars.Count; 78 | if (len <= 0) 79 | return; 80 | 81 | if (DoubleUtil.IsZero(pos.Shares)) 82 | return; 83 | 84 | DateTime openTime = pos.EntryBar.Date; 85 | DateTime now = pos.Security.Bars[len - 1].Date; 86 | if ((now - openTime).TotalMinutes >= m_timeToLive) 87 | { 88 | for (int j = pos.EntryBarNum; j < len; j++) 89 | { 90 | if ((pos.Security.Bars[j].Date - openTime).TotalMinutes >= m_timeToLive) 91 | { 92 | string msg = String.Format("Closing virtual FUT position. j:{0}; Ticker:{1}; Qty:{2}; Px:{3}", 93 | j, pos.Security.Symbol, 0, m_fixedPx); 94 | m_context.Log(msg, MessageType.Info, true); 95 | 96 | pos.VirtualChange(j, m_fixedPx, 0, "Close FUT"); 97 | break; 98 | } 99 | } 100 | } 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Options/CloseVirtualPosition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// \~english Close virtual position 8 | /// \~russian Закрыть виртуальную позицию 9 | /// 10 | [HandlerCategory(HandlerCategories.OptionsPositions)] 11 | [HelperName("Close Virtual Pos (bar)", Language = Constants.En)] 12 | [HelperName("Закрыть вирт. позицию (бары)", Language = Constants.Ru)] 13 | [HandlerAlwaysKeep] 14 | [InputsCount(1)] 15 | [Input(0, TemplateTypes.POSITION)] 16 | [OutputsCount(0)] 17 | [Description("Закрыть виртуальную позицию (побарный обработчик)")] 18 | [HelperDescription("Close virtual position (bar handler)", Constants.En)] 19 | public class CloseVirtualPosition : IContextUses, IValuesHandlerWithNumber 20 | { 21 | private const string DefaultPx = "125000"; 22 | private const string DefaultTtl = "15"; 23 | 24 | private IContext m_context; 25 | 26 | private double m_timeToLive = Double.Parse(DefaultTtl); 27 | private double m_fixedPx = Double.Parse(DefaultPx); 28 | 29 | public IContext Context 30 | { 31 | get { return m_context; } 32 | set { m_context = value; } 33 | } 34 | 35 | #region Parameters 36 | /// 37 | /// \~english Exit price for virtual position 38 | /// \~russian Фиксированная цена закрытия позиции 39 | /// 40 | [HelperName("Fixed Price", Constants.En)] 41 | [HelperName("Фиксированная цена", Constants.Ru)] 42 | [Description("Фиксированная цена закрытия позиции")] 43 | [HelperDescription("Exit price for virtual position", Language = Constants.En)] 44 | [HandlerParameter(true, NotOptimized = false, IsVisibleInBlock = true, Default = DefaultPx)] 45 | public double FixedPx 46 | { 47 | get { return m_fixedPx; } 48 | set { m_fixedPx = value; } 49 | } 50 | 51 | /// 52 | /// \~english Position lifetime (in minutes) 53 | /// \~russian Время жизни позиции (в минутах) 54 | /// 55 | [HelperName("Time to Live", Constants.En)] 56 | [HelperName("Время жизни", Constants.Ru)] 57 | [Description("Время жизни позиции (в минутах)")] 58 | [HelperDescription("Position lifetime (in minutes)", Language = Constants.En)] 59 | [HandlerParameter(true, NotOptimized = false, IsVisibleInBlock = true, Default = DefaultTtl)] 60 | public double TimeToLive 61 | { 62 | get { return m_timeToLive; } 63 | set { m_timeToLive = value; } 64 | } 65 | #endregion Parameters 66 | 67 | /// 68 | /// Метод под флаг TemplateTypes.POSITION, чтобы подключаться к источнику-позиции 69 | /// 70 | public void Execute(IPosition pos, int barNum) 71 | { 72 | if (pos == null) 73 | return; 74 | 75 | int len = pos.Security.Bars.Count; 76 | if (len <= 0) 77 | return; 78 | 79 | if (barNum < m_context.BarsCount - 1) 80 | return; 81 | 82 | if (pos.Shares == 0) 83 | return; 84 | 85 | DateTime openTime = pos.EntryBar.Date; 86 | DateTime now = pos.Security.Bars[len - 1].Date; 87 | if ((now - openTime).TotalMinutes >= m_timeToLive) 88 | { 89 | for (int j = pos.EntryBarNum; j < len; j++) 90 | { 91 | if ((pos.Security.Bars[j].Date - openTime).TotalMinutes >= m_timeToLive) 92 | { 93 | string msg = String.Format("Closing virtual position. j:{0}; Ticker:{1}; Qty:{2}; Px:{3}", 94 | j, pos.Security.Symbol, 0, m_fixedPx); 95 | m_context.Log(msg, MessageType.Info, true); 96 | 97 | pos.VirtualChange(j, m_fixedPx, 0, "Close"); 98 | break; 99 | } 100 | } 101 | } 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Options/CombinePositionProfiles.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using TSLab.Script.CanvasPane; 7 | using TSLab.Utils; 8 | 9 | namespace TSLab.Script.Handlers.Options 10 | { 11 | /// 12 | /// \~english Add 2 position profiles 13 | /// \~russian Сложить два профиля позиций 14 | /// 15 | [HandlerCategory(HandlerCategories.OptionsPositions)] 16 | [HelperName("Combine Series Profiles", Language = Constants.En)] 17 | [HelperName("Сложить профили позиций", Language = Constants.Ru)] 18 | [InputsCount(2)] 19 | [Input(0, TemplateTypes.INTERACTIVESPLINE, Name = "Profile1")] 20 | [Input(1, TemplateTypes.INTERACTIVESPLINE, Name = "Profile2")] 21 | [OutputsCount(1)] 22 | [OutputType(TemplateTypes.INTERACTIVESPLINE)] 23 | [Description("Сложить два профиля позиций")] 24 | [HelperDescription("Add 2 position profiles", Constants.En)] 25 | public class CombinePositionProfiles : BaseContextHandler, IValuesHandlerWithNumber 26 | { 27 | #region Parameters 28 | #endregion Parameters 29 | 30 | public InteractiveSeries Execute(InteractiveSeries ser1, InteractiveSeries ser2, int barNum) 31 | { 32 | int barsCount = m_context.BarsCount; 33 | if (!m_context.IsLastBarUsed) 34 | barsCount--; 35 | if (barNum < barsCount - 1) 36 | return Constants.EmptySeries; 37 | 38 | if ((ser1 == null) && (ser2 == null)) 39 | return Constants.EmptySeries; 40 | else if ((ser1 == null) && (ser2 != null)) 41 | return ser2; 42 | else if ((ser1 != null) && (ser2 == null)) 43 | return ser1; 44 | 45 | var query = (from s1 in ser1.ControlPoints 46 | from s2 in ser2.ControlPoints 47 | where DoubleUtil.AreClose(s1.Anchor.Value.X, s2.Anchor.Value.X) 48 | select new { cp1 = s1, cp2 = s2 }); 49 | 50 | List controlPoints = new List(); 51 | foreach (var pair in query) 52 | { 53 | double x = pair.cp1.Anchor.Value.X; 54 | double y = pair.cp1.Anchor.Value.Y + pair.cp2.Anchor.Value.Y; 55 | InteractivePointActive ip = new InteractivePointActive(x, y); 56 | //ip.Geometry = Geometries.Rect; 57 | ip.Tooltip = String.Format("F:{0}; PnL:{1}", x, y); 58 | 59 | controlPoints.Add(new InteractiveObject(ip)); 60 | } 61 | 62 | InteractiveSeries res = new InteractiveSeries(); // Здесь так надо -- мы делаем новую улыбку 63 | res.ControlPoints = new ReadOnlyCollection(controlPoints); 64 | 65 | return res; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Options/CurrentDateMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TSLab.Utils; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// \~english Algorythm to get current date 8 | /// \~russian Способ вычисления текущей псевдо-даты 9 | /// 10 | public enum CurrentDateMode 11 | { 12 | /// \~english Fixed date \~russian Фиксированная дата 13 | //[LocalizeDisplayName("CurrentDateMode.FixedDate")] 14 | [LocalizeDescription("CurrentDateMode.FixedDate")] 15 | FixedDate, 16 | 17 | /// \~english Current date \~russian Текущая дата 18 | //[LocalizeDisplayName("CurrentDateMode.CurrentDate")] 19 | [LocalizeDescription("CurrentDateMode.CurrentDate")] 20 | CurrentDate, 21 | 22 | /// \~english Tomorrow \~russian Завтра 23 | //[LocalizeDisplayName("CurrentDateMode.Tomorrow")] 24 | [LocalizeDescription("CurrentDateMode.Tomorrow")] 25 | Tomorrow, 26 | 27 | /// \~english Next working day \~russian На следующий рабочий день 28 | //[LocalizeDisplayName("CurrentDateMode.NextWorkingDay")] 29 | [LocalizeDescription("CurrentDateMode.NextWorkingDay")] 30 | NextWorkingDay, 31 | 32 | /// \~english Next week \~russian Через неделю 33 | //[LocalizeDisplayName("CurrentDateMode.NextWeek")] 34 | [LocalizeDescription("CurrentDateMode.NextWeek")] 35 | NextWeek, 36 | 37 | ///// \~english Next day of week \~russian На ближайший день недели 38 | //NextDayOfWeek, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Options/DropVirtualPositions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// \~english Clear collection of virtual positions 8 | /// \~russian Удалить виртуальные позиции 9 | /// 10 | [HandlerCategory(HandlerCategories.OptionsPositions)] 11 | [HelperName("Clear Virtual Positions", Language = Constants.En)] 12 | [HelperName("Удалить виртуальные позиции", Language = Constants.Ru)] 13 | [InputsCount(0)] 14 | [OutputsCount(0)] 15 | [Description("Блок служит для удаления виртуальных позиций. Для этого нужно привязать его свойство 'Удалить позиции' к 'Контрольной панели' и оформить его в виде кнопки.")] 16 | [HelperDescription("This block allows you to delete virtual positions. Connect Delete positions property to Control Pane and create a button.", Constants.En)] 17 | public class DropVirtualPositions : IContextUses, IValuesHandlerWithNumber 18 | { 19 | private IContext m_context; 20 | 21 | private bool m_dropVirtualPositions = false; 22 | 23 | public IContext Context 24 | { 25 | get { return m_context; } 26 | set { m_context = value; } 27 | } 28 | 29 | #region Parameters 30 | /// 31 | /// \~english Drop virtual positions 32 | /// \~russian Очистить коллекцию виртуальных позиций 33 | /// 34 | [HelperName("Drop Positions", Constants.En)] 35 | [HelperName("Удалить позиции", Constants.Ru)] 36 | [Description("Очистить коллекцию виртуальных позиций")] 37 | [HelperDescription("Drop virtual positions", Constants.En)] 38 | [HandlerParameter(true, NotOptimized = false, IsVisibleInBlock = true, Default = "False")] 39 | public bool DropPositions 40 | { 41 | get { return m_dropVirtualPositions; } 42 | set { m_dropVirtualPositions = value; } 43 | } 44 | #endregion Parameters 45 | 46 | public void Execute(int barNum) 47 | { 48 | int barsCount = m_context.BarsCount; 49 | if (!m_context.IsLastBarUsed) 50 | barsCount--; 51 | if (barNum < barsCount - 1) 52 | return; 53 | 54 | if (m_dropVirtualPositions) 55 | { 56 | try 57 | { 58 | PositionsManager posMan = PositionsManager.GetManager(m_context); 59 | m_context.Log("All virtual positions will be dropped right now.", MessageType.Warning, true); 60 | posMan.DropVirtualPositions(m_context); 61 | 62 | // Безтолку делать повторный пересчет 63 | //context.Recalc(true); 64 | } 65 | finally 66 | { 67 | m_dropVirtualPositions = false; 68 | } 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Options/ExchangeTheorPx.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using TSLab.DataSource; 6 | using TSLab.Script.Options; 7 | using TSLab.Utils; 8 | 9 | namespace TSLab.Script.Handlers.Options 10 | { 11 | /// 12 | /// \~english Theoretical option price provided by exchange. Additional linear transformation is allowed. 13 | /// \~russian Теоретические биржевые цены опционов. Возможно, с каким-то линейным преобразованием. 14 | /// 15 | [HandlerCategory(HandlerCategories.Options)] 16 | [HelperName("Exchange Theor Px", Language = Constants.En)] 17 | [HelperName("Биржевая теор. цена", Language = Constants.Ru)] 18 | [InputsCount(1)] 19 | [Input(0, TemplateTypes.OPTION_SERIES)] 20 | [OutputType(TemplateTypes.DOUBLE2)] 21 | [Description("Теоретические биржевые цены опционов. Возможно, с каким-то линейным преобразованием.")] 22 | [HelperDescription("Theoretical option price provided by exchange. Additional linear transformation is allowed.", Constants.En)] 23 | public class ExchangeTheorPx : IContextUses, IStreamHandler 24 | { 25 | private IContext m_context; 26 | private double m_multPx = 1, m_addPx = 0; 27 | 28 | public IContext Context 29 | { 30 | get { return m_context; } 31 | set { m_context = value; } 32 | } 33 | 34 | #region Parameters 35 | /// 36 | /// \~english Price multiplier 37 | /// \~russian Мультипликатор цен 38 | /// 39 | [HelperName("Multiplier", Constants.En)] 40 | [HelperName("Мультипликатор", Constants.Ru)] 41 | [Description("Мультипликатор цен")] 42 | [HelperDescription("Price multiplier", Language = Constants.En)] 43 | [HandlerParameter(true, NotOptimized = true, IsVisibleInBlock = true, 44 | Default = "1", Min = "-1000000", Max = "1000000", Step = "1")] 45 | public double Multiplier 46 | { 47 | get { return m_multPx; } 48 | set { m_multPx = value; } 49 | } 50 | 51 | /// 52 | /// \~english Price shift (price steps) 53 | /// \~russian Сдвиг цен (в шагах цены) 54 | /// 55 | [HelperName("Shift", Constants.En)] 56 | [HelperName("Сдвиг цен", Constants.Ru)] 57 | [Description("Сдвиг цен (в шагах цены)")] 58 | [HelperDescription("Price shift (price steps)", Language = Constants.En)] 59 | [HandlerParameter(true, NotOptimized = true, IsVisibleInBlock = true, 60 | Default = "0", Min = "-1000000", Max = "1000000", Step = "1")] 61 | public double ShiftPx 62 | { 63 | get { return m_addPx; } 64 | set { m_addPx = value; } 65 | } 66 | #endregion Parameters 67 | 68 | /// 69 | /// Обработчик под тип входных данных OPTION_SERIES 70 | /// 71 | public IList Execute(IOptionSeries optSer) 72 | { 73 | List res = new List(); 74 | 75 | IOptionStrike[] strikes = (from strike in optSer.GetStrikes() 76 | orderby strike.Strike ascending 77 | select strike).ToArray(); 78 | for (int j = 0; j < strikes.Length; j++) 79 | { 80 | IOptionStrike sInfo = strikes[j]; 81 | if ((sInfo.FinInfo == null) || (!sInfo.FinInfo.TheoreticalPrice.HasValue)) 82 | continue; 83 | 84 | double optPx = sInfo.FinInfo.TheoreticalPrice.Value; 85 | optPx *= m_multPx; 86 | optPx += m_addPx * sInfo.Security.SecurityDescription.GetTick(sInfo.FinInfo.TheoreticalPrice.Value); 87 | 88 | res.Add(new Double2(sInfo.Strike, optPx)); 89 | } 90 | 91 | return res; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Options/ExpiryMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TSLab.Utils; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// \~english Algorythms to get expiration date 8 | /// \~russian Алгоритмы расчета даты экспирации 9 | /// 10 | public enum ExpiryMode 11 | { 12 | /// \~english Fixed date \~russian Фиксированная дата 13 | //[LocalizeDisplayName("ExpiryMode.FixedExpiry")] 14 | [LocalizeDescription("ExpiryMode.FixedExpiry")] 15 | FixedExpiry, 16 | 17 | /// \~english First expiry \~russian Ближайшая экспирация 18 | //[LocalizeDisplayName("ExpiryMode.FirstExpiry")] 19 | [LocalizeDescription("ExpiryMode.FirstExpiry")] 20 | FirstExpiry, 21 | 22 | /// \~english Last expiry \~russian Последняя экспирация 23 | //[LocalizeDisplayName("ExpiryMode.LastExpiry")] 24 | [LocalizeDescription("ExpiryMode.LastExpiry")] 25 | LastExpiry, 26 | 27 | /// \~english Expiry by number \~russian Экспирация по порядковому номеру 28 | //[LocalizeDisplayName("ExpiryMode.ExpiryByNumber")] 29 | [LocalizeDescription("ExpiryMode.ExpiryByNumber")] 30 | ExpiryByNumber, 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Options/FixedValueMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TSLab.Utils; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// \~english Units to be used for presentation 8 | /// \~russian В какой размерности показывать хранимое значение 9 | /// 10 | public enum FixedValueMode 11 | { 12 | /// \~english As is \~russian Как есть 13 | //[LocalizeDisplayName("FixedValueMode.AsIs")] 14 | [LocalizeDescription("FixedValueMode.AsIs")] 15 | AsIs, 16 | 17 | /// \~english As percent (multiply by 100) \~russian В процентах (умножить на 100) 18 | //[LocalizeDisplayName("FixedValueMode.Percent")] 19 | [LocalizeDescription("FixedValueMode.Percent")] 20 | Percent, 21 | 22 | /// \~english As per mille (multiply by 1000) \~russian В промилле (умножить на 1000) 23 | //[LocalizeDisplayName("FixedValueMode.Promille")] 24 | [LocalizeDescription("FixedValueMode.Promille")] 25 | Promille, 26 | 27 | /// \~english As thousand (divide by 1000) \~russian В тысячах (разделить на 1000) 28 | //[LocalizeDisplayName("FixedValueMode.Thousand")] 29 | [LocalizeDescription("FixedValueMode.Thousand")] 30 | Thousand, 31 | 32 | /// \~english Convert to days (multiply by 365) \~russian Перевести в дни (умножить на 365) 33 | //[LocalizeDisplayName("FixedValueMode.YearsAsDays")] 34 | [LocalizeDescription("FixedValueMode.YearsAsDays")] 35 | YearsAsDays, 36 | 37 | /// \~english Convert to years (divide by 365) \~russian Перевести в годы (разделить на 365) 38 | //[LocalizeDisplayName("FixedValueMode.DaysAsYears")] 39 | [LocalizeDescription("FixedValueMode.DaysAsYears")] 40 | DaysAsYears, 41 | 42 | /// \~english As Parts-per-Million (multiply by 1000000) \~russian В миллионных долях (умножить на 1000000) 43 | //[LocalizeDisplayName("FixedValueMode.PartsPerMillion")] 44 | [LocalizeDescription("FixedValueMode.PartsPerMillion")] 45 | PartsPerMillion, 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Options/ForwardTheorPx.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using TSLab.DataSource; 6 | using TSLab.Script.Options; 7 | using TSLab.Utils; 8 | 9 | namespace TSLab.Script.Handlers.Options 10 | { 11 | /// 12 | /// \~english Base asset price calculated using theretical option prices 13 | /// \~russian Цена базового актива, вычисленная через теоретические (биржевые) цены опционов 14 | /// 15 | [HandlerCategory(HandlerCategories.OptionsIndicators)] 16 | [HelperName("Forward Price", Language = Constants.En)] 17 | [HelperName("Форвардная цена", Language = Constants.Ru)] 18 | [InputsCount(1)] 19 | [Input(0, TemplateTypes.OPTION_SERIES, Name = Constants.OptionSeries)] 20 | [OutputsCount(1)] 21 | [OutputType(TemplateTypes.DOUBLE)] 22 | [Description("Цена базового актива, вычисленная через теоретические (биржевые) цены опционов")] 23 | [HelperDescription("Base asset price calculated using theretical option prices", Constants.En)] 24 | public class ForwardTheorPx : BaseContextHandler, IStreamHandler 25 | { 26 | protected double m_strike = 120000; 27 | 28 | #region Parameters 29 | /// 30 | /// \~english Strike to calculate forward price 31 | /// \~russian Страйк, который будет использован для расчета форвардной цены 32 | /// 33 | [HelperName("Strike", Constants.En)] 34 | [HelperName("Страйк", Constants.Ru)] 35 | [Description("Страйк, который будет использован для расчета форвардной цены")] 36 | [HelperDescription("Strike to calculate forward price", Language = Constants.En)] 37 | [HandlerParameter(true, NotOptimized = true, IsVisibleInBlock = true, Default = "120000")] 38 | public double Strike 39 | { 40 | get { return m_strike; } 41 | set { m_strike = value; } 42 | } 43 | #endregion Parameters 44 | 45 | /// 46 | /// Метод под флаг TemplateTypes.OPTION_SERIES, чтобы подключаться к источнику-серии 47 | /// 48 | public IList Execute(IOptionSeries optSer) 49 | { 50 | List res = m_context.LoadObject(VariableId + "Prices") as List; 51 | if (res == null) 52 | { 53 | res = new List(); 54 | m_context.StoreObject(VariableId + "Prices", res); 55 | } 56 | 57 | int oldCount = res.Count; 58 | int len = m_context.BarsCount; 59 | for (int j = oldCount; j < len; j++) 60 | res.Add(Constants.NaN); 61 | 62 | IOptionStrikePair pair = (from p in optSer.GetStrikePairs() 63 | where DoubleUtil.AreClose(p.Strike, m_strike) 64 | select p).FirstOrDefault(); 65 | if (pair == null) 66 | return res; 67 | var putBars = pair.Put.Security.Bars; 68 | var callBars = pair.Call.Security.Bars; 69 | 70 | //if ((putBars.Count <= 0) || (callBars.Count <= 0)) 71 | // return res; 72 | 73 | ISecurity sec = optSer.UnderlyingAsset; 74 | // кеширование 75 | for (int j = oldCount; j < len; j++) 76 | { 77 | int putIndex = Math.Min(putBars.Count - 1, j); 78 | int callIndex = Math.Min(callBars.Count - 1, j); 79 | if ((putIndex >= 0) && (callIndex >= 0) && 80 | (putBars[putIndex] is IBar) && (callBars[callIndex] is IBar)) 81 | { 82 | double putPx = ((IBar)putBars[j]).TheoreticalPrice; 83 | double callPx = ((IBar)callBars[j]).TheoreticalPrice; 84 | double px = callPx - putPx + pair.Strike; 85 | res.Add(px); 86 | } 87 | else 88 | res.Add(Constants.NaN); 89 | } 90 | 91 | // актуализирую текущее значение 92 | if ((len > 0) && 93 | pair.PutFinInfo.TheoreticalPrice.HasValue && pair.CallFinInfo.TheoreticalPrice.HasValue) 94 | { 95 | double putPx = pair.PutFinInfo.TheoreticalPrice.Value; 96 | double callPx = pair.CallFinInfo.TheoreticalPrice.Value; 97 | double px = callPx - putPx + pair.Strike; 98 | 99 | res[res.Count - 1] = px; 100 | } 101 | 102 | return res; 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Options/Greeks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TSLab.Script.Handlers.Options 4 | { 5 | /// 6 | /// \~english Greeks 7 | /// \~russian Греки 8 | /// 9 | public enum Greeks 10 | { 11 | Delta, 12 | Theta, 13 | Vega, 14 | 15 | Gamma, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Options/HelperDescriptionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// Описание кубика как его будет видеть Пользователь. 8 | /// Это вспомогательный атрибут для упрощения локализации зоопарка кубиков (как опционных, так и обычных). 9 | /// 10 | [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)] 11 | public class HelperDescriptionAttribute : Attribute 12 | { 13 | public HelperDescriptionAttribute() 14 | : this(String.Empty, Constants.Ru) 15 | { 16 | } 17 | 18 | public HelperDescriptionAttribute(string description) 19 | : this(description, Constants.Ru) 20 | { 21 | } 22 | 23 | public HelperDescriptionAttribute(string description, string language) 24 | { 25 | Description = description ?? String.Empty; 26 | Language = String.IsNullOrWhiteSpace(language) ? Constants.Ru : language; 27 | } 28 | 29 | public string Description { get; set; } 30 | 31 | public string Language { get; set; } 32 | 33 | public override string ToString() 34 | { 35 | return Description; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Options/HelperLinkAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// Ссылка на скрипт или статью с использованием данного кубика. 8 | /// Это вспомогательный атрибут для упрощения локализации зоопарка кубиков (как опционных, так и обычных), 9 | /// а также для автоматизированного формирования документации. 10 | /// 11 | [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)] 12 | public class HelperLinkAttribute : Attribute 13 | { 14 | public HelperLinkAttribute(string link) 15 | : this(link, link, Constants.Ru) 16 | { 17 | } 18 | 19 | public HelperLinkAttribute(string link, string name, string language) 20 | { 21 | Link = link ?? String.Empty; 22 | Name = name ?? String.Empty; 23 | Language = String.IsNullOrWhiteSpace(language) ? Constants.Ru : language; 24 | } 25 | 26 | public string Link { get; set; } 27 | 28 | public string Name { get; set; } 29 | 30 | public string Language { get; set; } 31 | 32 | public override string ToString() 33 | { 34 | return Name + ": " + Link; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Options/HelperNameAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// Название кубика как его будет видеть Пользователь. 8 | /// Вспомогательный атрибут для упрощения локализации зоопарка кубиков (как опционных, так и обычных), 9 | /// а также для автоматизированного формирования документации. 10 | /// 11 | [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)] 12 | public class HelperNameAttribute : Attribute 13 | { 14 | public HelperNameAttribute(string name) 15 | : this(name, Constants.Ru) 16 | { 17 | } 18 | 19 | public HelperNameAttribute(string name, string language) 20 | { 21 | Name = name ?? String.Empty; 22 | Language = String.IsNullOrWhiteSpace(language) ? Constants.Ru : language; 23 | } 24 | 25 | public string Name { get; set; } 26 | 27 | public string Language { get; set; } 28 | 29 | public override string ToString() 30 | { 31 | return Name; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Options/LastValueToParameter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | using TSLab.Script.Optimization; 5 | 6 | namespace TSLab.Script.Handlers.Options 7 | { 8 | /// 9 | /// \~english Convert last value in series to parameter 10 | /// \~russian Преобразовать последнее значение индикатора в параметр 11 | /// 12 | [HandlerCategory(HandlerCategories.OptionsIndicators)] 13 | [HelperName("Last Value", Language = Constants.En)] 14 | [HelperName("Последнее значение", Language = Constants.Ru)] 15 | [HandlerAlwaysKeep] 16 | [InputsCount(1)] 17 | [Input(0, TemplateTypes.DOUBLE)] 18 | [OutputsCount(1)] 19 | [OutputType(TemplateTypes.DOUBLE)] 20 | [Description("Преобразовать последнее значение индикатора в параметр")] 21 | [HelperDescription("Convert last value in series to parameter", Constants.En)] 22 | public class LastValueToParameter : BaseContextHandler, IValuesHandlerWithNumber 23 | { 24 | private OptimProperty m_result = new OptimProperty(0, true, double.MinValue, double.MaxValue, 1.0, 4); 25 | 26 | #region Parameters 27 | /// 28 | /// Свойство используется только для отображения на UI 29 | /// 30 | [HelperName("Display value", Constants.En)] 31 | [HelperName("Показываемое значение", Constants.Ru)] 32 | [Description("Показываемое значение (для отображения в интерфейсе агента)")] 33 | [HelperDescription("Display value (just to show it on ControlPane)", Language = Constants.En)] 34 | [HandlerParameter(true, NotOptimized = false, IsVisibleInBlock = true, Default = "0", IsCalculable = true)] 35 | public OptimProperty Result 36 | { 37 | get { return m_result; } 38 | set { m_result = value; } 39 | } 40 | 41 | /// 42 | /// Свойство используется только для связывания с другими блоком LinkedParameters 43 | /// 44 | //[ReadOnly(true)] 45 | [HelperName("Last value", Constants.En)] 46 | [HelperName("Последнее значение", Constants.Ru)] 47 | [Description("Последнее значение")] 48 | [HelperDescription("Last value", Language = Constants.En)] 49 | [HandlerParameter(true, NotOptimized = true, IsVisibleInBlock = true, Default = "0", IsCalculable = false)] 50 | public double LastValue 51 | { 52 | get 53 | { 54 | if (m_result != null) 55 | return m_result.Value; 56 | else 57 | return Constants.NaN; 58 | } 59 | set 60 | { 61 | } 62 | } 63 | 64 | ///// 65 | ///// \~english Display units (hundreds, thousands, as is) 66 | ///// \~russian Единицы отображения (сотни, тысячи, как есть) 67 | ///// 68 | //[HelperName("Display Units", Constants.En)] 69 | //[HelperName("Единицы отображения", Constants.Ru)] 70 | //[Description("Единицы отображения (сотни, тысячи, как есть)")] 71 | //[HelperDescription("Display units (hundreds, thousands, as is)", Constants.En)] 72 | //[HandlerParameter(true, NotOptimized = true, IsVisibleInBlock = true, Default = "AsIs")] 73 | //public FixedValueMode DisplayUnits 74 | //{ 75 | // get { return m_valueMode; } 76 | // set { m_valueMode = value; } 77 | //} 78 | #endregion Parameters 79 | 80 | /// 81 | /// Метод под флаг TemplateTypes.DOUBLE, чтобы подключаться к источнику 82 | /// 83 | public void Execute(double source, int barNum) 84 | { 85 | int len = ContextBarsCount; 86 | if (len - 1 <= barNum) 87 | { 88 | m_result.Value = source; 89 | } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Options/LinearTransform.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// \~english Linear transform (a*x+b) 8 | /// \~russian Линейное преобразование (a*x+b) 9 | /// 10 | [HandlerCategory(HandlerCategories.OptionsTickByTick)] 11 | [HelperName("Linear transform (a*x+b)", Language = Constants.En)] 12 | [HelperName("Линейное преобразование (a*x+b)", Language = Constants.Ru)] 13 | [InputsCount(1)] 14 | [Input(0, TemplateTypes.DOUBLE)] 15 | [OutputsCount(1)] 16 | [OutputType(TemplateTypes.DOUBLE)] 17 | [Description("Линейное преобразование (a*x+b)")] 18 | [HelperDescription("Linear transform (a*x+b)", Constants.En)] 19 | public class LinearTransform : IValuesHandlerWithNumber 20 | { 21 | private double m_add = 0; 22 | private double m_multiplier = 1; 23 | 24 | #region Parameters 25 | /// 26 | /// \~english Summand 27 | /// \~russian Слагаемое 28 | /// 29 | [HelperName("Summand", Constants.En)] 30 | [HelperName("Слагаемое", Constants.Ru)] 31 | [Description("Слагаемое")] 32 | [HelperDescription("Summand", Constants.En)] 33 | [HandlerParameter(true, NotOptimized = false, IsVisibleInBlock = true, 34 | Default = "0.0", Min = "-5000000.0", Max = "5000000.0", Step = "1")] 35 | public double Add 36 | { 37 | get { return m_add; } 38 | set { m_add = value; } 39 | } 40 | 41 | /// 42 | /// \~english Multiplier 43 | /// \~russian Множитель 44 | /// 45 | [HelperName("Multiplier", Constants.En)] 46 | [HelperName("Множитель", Constants.Ru)] 47 | [Description("Множитель")] 48 | [HelperDescription("Multiplier", Constants.En)] 49 | [HandlerParameter(true, NotOptimized = false, IsVisibleInBlock = true, 50 | Default = "1.0", Min = "-5000000.0", Max = "5000000.0", Step = "1")] 51 | public double Mult 52 | { 53 | get { return m_multiplier; } 54 | set { m_multiplier = value; } 55 | } 56 | #endregion Parameters 57 | 58 | public double Execute(double val, int barNum) 59 | { 60 | double res = m_multiplier * val + m_add; 61 | return res; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Options/NumericalGammaOnF3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | 5 | using TSLab.Script.CanvasPane; 6 | using TSLab.Script.Optimization; 7 | 8 | namespace TSLab.Script.Handlers.Options 9 | { 10 | /// 11 | /// \~english Numerical estimate of gamma at-the-money (only one point is processed using gamma profile) 12 | /// \~russian Численный расчет гаммы позиции в текущей точке БА (вычисляется одна точка по профилю гаммы) 13 | /// 14 | [HandlerCategory(HandlerCategories.OptionsPositions)] 15 | [HelperName("Numerical Gamma ATM (IntSer)", Language = Constants.En)] 16 | [HelperName("Численная гамма на деньгах (IntSer)", Language = Constants.Ru)] 17 | [InputsCount(1)] 18 | [Input(0, TemplateTypes.INTERACTIVESPLINE, Name = "GammaProfile")] 19 | [OutputType(TemplateTypes.DOUBLE)] 20 | [Description("Численный расчет гаммы позиции в текущей точке БА (вычисляется одна точка по профилю гаммы)")] 21 | [HelperDescription("Numerical estimate of gamma at-the-money (only one point is processed using gamma profile)", Constants.En)] 22 | public class NumericalGammaOnF3 : BaseContextHandler, IValuesHandlerWithNumber 23 | { 24 | private OptimProperty m_gamma = new OptimProperty(0, false, Double.MinValue, Double.MaxValue, 1, 6); 25 | 26 | #region Parameters 27 | /// 28 | /// \~english Current gamma (just to show it on ControlPane) 29 | /// \~russian Текущая гамма всей позиции (для отображения в интерфейсе агента) 30 | /// 31 | [HelperName("Gamma", Constants.En)] 32 | [HelperName("Гамма", Constants.Ru)] 33 | [ReadOnly(true)] 34 | [Description("Текущая гамма всей позиции (для отображения в интерфейсе агента)")] 35 | [HelperDescription("Current gamma (just to show it on ControlPane)", Constants.En)] 36 | [HandlerParameter(true, NotOptimized = false, IsVisibleInBlock = true, Default = "0", IsCalculable = true)] 37 | public OptimProperty Gamma 38 | { 39 | get { return m_gamma; } 40 | set { m_gamma = value; } 41 | } 42 | #endregion Parameters 43 | 44 | public double Execute(InteractiveSeries gammaProfile, int barNum) 45 | { 46 | List positionGammas = m_context.LoadObject(VariableId + "positionGammas") as List; 47 | if (positionGammas == null) 48 | { 49 | positionGammas = new List(); 50 | m_context.StoreObject(VariableId + "positionGammas", positionGammas); 51 | } 52 | 53 | int len = m_context.BarsCount; 54 | if (len <= barNum) 55 | { 56 | string msg = String.Format("[{0}] (BarsCount <= barNum)! BarsCount:{1}; barNum:{2}", 57 | GetType().Name, m_context.BarsCount, barNum); 58 | m_context.Log(msg, MessageType.Info, true); 59 | } 60 | for (int j = positionGammas.Count; j < Math.Max(len, barNum + 1); j++) 61 | positionGammas.Add(Constants.NaN); 62 | 63 | { 64 | int barsCount = m_context.BarsCount; 65 | if (!m_context.IsLastBarUsed) 66 | barsCount--; 67 | if (barNum < barsCount - 1) 68 | return positionGammas[barNum]; 69 | } 70 | 71 | if (gammaProfile == null) 72 | return Constants.NaN; 73 | 74 | SmileInfo gammaInfo = gammaProfile.GetTag(); 75 | if ((gammaInfo == null) || (gammaInfo.ContinuousFunction == null)) 76 | { 77 | positionGammas[barNum] = Constants.NaN; // заполняю индекс barNumber 78 | return Constants.NaN; 79 | } 80 | 81 | double f = gammaInfo.F; 82 | double dT = gammaInfo.dT; 83 | 84 | if ((dT < Double.Epsilon) || Double.IsNaN(dT) || Double.IsNaN(f)) 85 | { 86 | positionGammas[barNum] = Constants.NaN; // заполняю индекс barNumber 87 | return Constants.NaN; 88 | } 89 | 90 | double rawGamma; 91 | if (!gammaInfo.ContinuousFunction.TryGetValue(f, out rawGamma)) 92 | { 93 | rawGamma = Constants.NaN; 94 | } 95 | 96 | positionGammas[barNum] = rawGamma; // заполняю индекс barNumber 97 | 98 | m_gamma.Value = rawGamma; 99 | //context.Log("Gamma[3]: " + gamma.Value, logColor, true); 100 | 101 | return rawGamma; 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Options/NumericalGreekAlgo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TSLab.Utils; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// \~english Numerical algorythms to estimate greeks 8 | /// \~russian Алгоритмы численного расчета греков 9 | /// 10 | public enum NumericalGreekAlgo 11 | { 12 | /// 13 | /// \~english Smile is frozen and does not change with market 14 | /// \~russian Улыбка заморожена и никак не меняется при изменении рыночных параметров 15 | /// 16 | //[LocalizeDisplayName("NumericalGreekAlgo.FrozenSmile")] 17 | [LocalizeDescription("NumericalGreekAlgo.FrozenSmile")] 18 | FrozenSmile, 19 | 20 | /// 21 | /// \~english Smile follows base asset as solid body; no vertical shift 22 | /// \~russian Улыбка без искажений сдвигается по горизонтали вслед за БА 23 | /// 24 | //[LocalizeDisplayName("NumericalGreekAlgo.ShiftingSmile")] 25 | [LocalizeDescription("NumericalGreekAlgo.ShiftingSmile")] 26 | ShiftingSmile, 27 | 28 | ///// 29 | ///// \~english Smile follows base asset and slides on itself as solid body 30 | ///// \~russian Улыбка без искажений скользит сама по себе вслед за БА 31 | ///// 32 | //SlidingSmile, 33 | 34 | ///// 35 | ///// \~english Smile follows base asset and changes its shape when market moves 36 | ///// \~russian При движении БА улыбка скользит и деформируется 37 | ///// 38 | //AdaptingSmile, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Options/OptionBase2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | using TSLab.Script.Options; 5 | 6 | namespace TSLab.Script.Handlers.Options 7 | { 8 | /// 9 | /// \~english Base asset (bar handler) 10 | /// \~russian Базовый актив (побарный обработчик) 11 | /// 12 | [HandlerCategory(HandlerCategories.OptionsTickByTick)] 13 | [HelperName("Base asset", Language = Constants.En)] 14 | [HelperName("Базовый актив", Language = Constants.Ru)] 15 | [InputsCount(1)] 16 | [Input(0, TemplateTypes.OPTION | TemplateTypes.OPTION_SERIES)] 17 | [OutputType(TemplateTypes.SECURITY)] 18 | [Description("Базовый актив (побарный обработчик)")] 19 | [HelperDescription("Base asset (bar handler)", Constants.En)] 20 | public class OptionBase2 : IValuesHandlerWithNumber, ISecurityReturns 21 | { 22 | public ISecurity Execute(IOption opt, int barNum) 23 | { 24 | return opt.UnderlyingAsset; 25 | } 26 | 27 | public ISecurity Execute(IOptionSeries opt, int barNum) 28 | { 29 | return opt.UnderlyingAsset; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Options/OptionPxMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TSLab.Script.Handlers.Options 4 | { 5 | /// 6 | /// \~english Source of price or its kind 7 | /// \~russian Вид цены или её источник 8 | /// 9 | public enum OptionPxMode 10 | { 11 | /// \~english Bid \~russian Покупка 12 | Bid, 13 | /// \~english Ask \~russian Продажа 14 | Ask, 15 | /// \~english Midpoint \~russian Середина спреда 16 | Mid, 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Options/OptionSeriesBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | 6 | using TSLab.Script.CanvasPane; 7 | using TSLab.Script.Options; 8 | 9 | namespace TSLab.Script.Handlers.Options 10 | { 11 | [HandlerCategory(HandlerCategories.Options)] 12 | [InputsCount(1)] 13 | [Input(0, TemplateTypes.OPTION | TemplateTypes.OPTION_SERIES | TemplateTypes.OPTION_STRIKE)] 14 | [OutputType(TemplateTypes.DOUBLE2)] 15 | public abstract class OptionSeriesBase : IStreamHandler 16 | { 17 | /// 18 | /// \~english Type of option to be used in handler (put, call, any) 19 | /// \~russian Тип опционов, которые будут использованы в обработчике (пут, колл, любой) 20 | /// 21 | [HelperName("Option Type", Constants.En)] 22 | [HelperName("Вид опционов", Constants.Ru)] 23 | [Description("Тип опционов, которые будут использованы в обработчике (пут, колл, любой)")] 24 | [HelperDescription("Type of option to be used in handler (put, call, any)", Constants.En)] 25 | //[HandlerParameter(NotOptimized = true)] 26 | [HandlerParameter(true, "Any")] 27 | public StrikeType StrikeType { get; set; } 28 | 29 | public IList Execute(IOption source) 30 | { 31 | var strikes = source.CurrentSeries.GetStrikes(); 32 | return CalculateInternal(strikes); 33 | } 34 | 35 | public IList Execute(IOptionSeries source) 36 | { 37 | var strikes = source != null ? source.GetStrikes() : new IOptionStrike[0]; 38 | return CalculateInternal(strikes); 39 | } 40 | 41 | public IList Execute(IOptionStrike source) 42 | { 43 | var strikes = source != null ? new[] { source } : new IOptionStrike[0]; 44 | return CalculateInternal(strikes); 45 | } 46 | 47 | private IList CalculateInternal(IEnumerable strikes) 48 | { 49 | if (StrikeType == StrikeType.Call) 50 | strikes = strikes.Where(s => s.StrikeType == StrikeType.Call); 51 | else if (StrikeType == StrikeType.Put) 52 | strikes = strikes.Where(s => s.StrikeType == StrikeType.Put); 53 | var res = Calculate(strikes.OrderBy(st => st.Strike).ToArray()).ToArray(); 54 | return res; 55 | } 56 | 57 | protected abstract IEnumerable Calculate(IOptionStrike[] strikes); 58 | } 59 | 60 | [HandlerCategory(HandlerCategories.Options)] 61 | [InputsCount(2)] 62 | [Input(0, TemplateTypes.OPTION | TemplateTypes.OPTION_SERIES)] 63 | [Input(1, TemplateTypes.DOUBLE2 | TemplateTypes.DOUBLE2N | TemplateTypes.INTERACTIVESPLINE)] 64 | [OutputType(TemplateTypes.DOUBLE2)] 65 | public abstract class OptionSeriesBase2 : IStreamHandler 66 | { 67 | public IList Execute(IOption source, InteractiveSeries data) 68 | { 69 | var strikes = source.GetStrikes().ToArray(); 70 | return Calculate(strikes, data.ControlPoints); 71 | } 72 | 73 | public IList Execute(IOption source, IReadOnlyList data) 74 | { 75 | var strikes = source.GetStrikes().ToArray(); 76 | return Calculate(strikes, data); 77 | } 78 | 79 | public IList Execute(IOptionSeries source, InteractiveSeries data) 80 | { 81 | var strikes = source.GetStrikes().ToArray(); 82 | return Calculate(strikes, data.ControlPoints); 83 | } 84 | 85 | public IList Execute(IOptionSeries source, IReadOnlyList data) 86 | { 87 | var strikes = source.GetStrikes().ToArray(); 88 | return Calculate(strikes, data); 89 | } 90 | 91 | protected abstract IList Calculate(IOptionStrike[] strikes, IReadOnlyList data); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Options/OptionSeriesBaseN.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Globalization; 5 | using System.Linq; 6 | 7 | using TSLab.Script.Options; 8 | 9 | namespace TSLab.Script.Handlers.Options 10 | { 11 | [HandlerCategory(HandlerCategories.Options)] 12 | [InputsCount(1)] 13 | [Input(0, TemplateTypes.OPTION | TemplateTypes.OPTION_SERIES | TemplateTypes.OPTION_STRIKE)] 14 | [OutputType(TemplateTypes.DOUBLE2N)] 15 | public abstract class OptionSeriesBaseN : BaseContextHandler, IStreamHandler 16 | { 17 | /// 18 | /// \~english Type of option to be used in handler (put, call, any) 19 | /// \~russian Тип опционов, которые будут использованы в обработчике (пут, колл, любой) 20 | /// 21 | [HelperName("Option Type", Constants.En)] 22 | [HelperName("Вид опционов", Constants.Ru)] 23 | [Description("Тип опционов, которые будут использованы в обработчике (пут, колл, любой)")] 24 | [HelperDescription("Type of option to be used in handler (put, call, any)", Constants.En)] 25 | [HandlerParameter(NotOptimized = true)] 26 | public StrikeType StrikeType { get; set; } 27 | 28 | /// 29 | /// \~english Shift calculations back in time 30 | /// \~russian Перевод времени в прошлое на заданное число баров 31 | /// 32 | [HelperName("Shift Time", Constants.En)] 33 | [HelperName("Сдвиг времени", Constants.Ru)] 34 | [Description("Перевод времени в прошлое на заданное число баров")] 35 | [HelperDescription("Shift calculations back in time", Constants.En)] 36 | [HandlerParameter(true, "0", Min = "0", Max = "1000", Step = "1")] 37 | public int Shift { get; set; } 38 | 39 | public Double2N Execute(IOption source) 40 | { 41 | var strikes = source.CurrentSeries.GetStrikes(); 42 | return CalculateInternal(strikes); 43 | } 44 | 45 | public Double2N Execute(IOptionSeries source) 46 | { 47 | var strikes = source != null ? source.GetStrikes() : new IOptionStrike[0]; 48 | return CalculateInternal(strikes); 49 | } 50 | 51 | public Double2N Execute(IOptionStrike source) 52 | { 53 | var strikes = source != null ? new[] { source } : new IOptionStrike[0]; 54 | return CalculateInternal(strikes); 55 | } 56 | 57 | private Double2N CalculateInternal(IEnumerable strikes) 58 | { 59 | if (StrikeType == StrikeType.Call) 60 | strikes = strikes.Where(s => s.StrikeType == StrikeType.Call); 61 | else if (StrikeType == StrikeType.Put) 62 | strikes = strikes.Where(s => s.StrikeType == StrikeType.Put); 63 | var array = strikes.OrderBy(st => st.Strike).ToArray(); 64 | var maxBar = Context.BarsCount - 1; 65 | var initialbarNumber = maxBar - Shift; // по умолчанию выдаём данные для последней свечи 66 | initialbarNumber = Math.Min(maxBar, Math.Max(0, initialbarNumber)); 67 | return new Double2N(Context, initialbarNumber, 68 | barNum => Context.GetData( 69 | VariableId, 70 | new[] 71 | { 72 | barNum.ToString(CultureInfo.InvariantCulture) 73 | }, 74 | () => Calculate(array, barNum).ToArray())); 75 | } 76 | 77 | protected abstract IEnumerable Calculate(IOptionStrike[] strikes, int barNum); 78 | } 79 | } -------------------------------------------------------------------------------- /Options/PositionGridDisplayMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TSLab.Script.Handlers.Options 4 | { 5 | /// 6 | /// \~english Type of data to be displayed in a grid column 7 | /// \~russian Вид данных, которые надо показать в столбце грида 8 | /// 9 | public enum PositionGridDisplayMode 10 | { 11 | /// \~english IV \~russian Волатильность 12 | Iv, 13 | /// \~english Price \~russian Цена 14 | Px, 15 | /// \~english Direction \~russian Направление 16 | Dir, 17 | /// \~english Qty \~russian Количество 18 | Qty, 19 | /// \~english Symbol \~russian Символ 20 | Symbol, 21 | /// \~english Is virtual \~russian Виртуальная или реальная 22 | IsVirtual, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Options/PrepareLineForCanvasPane.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.ComponentModel; 5 | using System.Windows; 6 | 7 | using TSLab.Script.CanvasPane; 8 | 9 | namespace TSLab.Script.Handlers.Options 10 | { 11 | /// 12 | /// \~english Merge two series of numbers to InteractiveSeries 13 | /// \~russian Объединить две серии чисел в интерактивную линию 14 | /// 15 | [HandlerCategory(HandlerCategories.OptionsIndicators)] 16 | [HelperName("Prepare line", Language = Constants.En)] 17 | [HelperName("Подготовить линию", Language = Constants.Ru)] 18 | [InputsCount(2)] 19 | [Input(0, TemplateTypes.DOUBLE, Name = "X")] 20 | [Input(1, TemplateTypes.DOUBLE, Name = "Y")] 21 | [OutputsCount(1)] 22 | [OutputType(TemplateTypes.INTERACTIVESPLINE)] 23 | [Description("Объединить две серии чисел в интерактивную линию")] 24 | [HelperDescription("Merge two series of numbers to InteractiveSeries", Constants.En)] 25 | public class PrepareLineForCanvasPane : BaseContextHandler, IStreamHandler, IValuesHandlerWithNumber, IDisposable 26 | { 27 | /// 28 | /// Локальный накопитель точек для побарного обработчика 29 | /// 30 | private List m_controlPoints; 31 | 32 | public InteractiveSeries Execute(IList xValues, IList yValues) 33 | { 34 | if ((xValues == null) || (xValues.Count <= 0) || (yValues == null) || (yValues.Count <= 0)) 35 | { 36 | string msg = String.Format("[{0}] Null or empty data series.", GetType().Name); 37 | Context.Log(msg, MessageType.Error, false); 38 | return Constants.EmptySeries; 39 | } 40 | 41 | if (xValues.Count != yValues.Count) 42 | { 43 | string msg = String.Format("[{0}] Data series have different length. X.Len:{1}; Y.Len:{2}", GetType().Name, xValues.Count, yValues.Count); 44 | Context.Log(msg, MessageType.Warning, false); 45 | //return Constants.EmptySeries; 46 | } 47 | 48 | int len = Math.Min(xValues.Count, yValues.Count); 49 | List controlPoints = new List(); 50 | for (int j = 0; j < len; j++) 51 | { 52 | InteractivePointLight ip = new InteractivePointLight(); 53 | ip.Value = new Point(xValues[j], yValues[j]); 54 | //ip.Tooltip = String.Format("F:{0}; D:{1}", f, yStr); 55 | 56 | controlPoints.Add(new InteractiveObject(ip)); 57 | } 58 | 59 | // ReSharper disable once UseObjectOrCollectionInitializer 60 | InteractiveSeries res = new InteractiveSeries(); // Здесь так надо -- мы делаем новую улыбку 61 | res.ControlPoints = new ReadOnlyCollection(controlPoints); 62 | 63 | return res; 64 | } 65 | 66 | public InteractiveSeries Execute(double xVal, double yVal, int barNum) 67 | { 68 | // 1. Если локальный накопитель еще не проинициализирован -- делаем это 69 | if (m_controlPoints == null) 70 | m_controlPoints = new List(); 71 | 72 | // 3. Добавляем новую точку в локальный накопитель 73 | InteractivePointLight ip = new InteractivePointLight(); 74 | ip.Value = new Point(xVal, yVal); 75 | //ip.Tooltip = String.Format("F:{0}; D:{1}", f, yStr); 76 | 77 | m_controlPoints.Add(new InteractiveObject(ip)); 78 | 79 | // 5. Если мы еще не добрались до правого края графика -- возвращаем пустую серию 80 | int barsCount = ContextBarsCount; 81 | if (barNum < barsCount - 1) 82 | return Constants.EmptySeries; 83 | 84 | // 7. На правом краю графика возвращаем подготовленную серию точек 85 | // ReSharper disable once UseObjectOrCollectionInitializer 86 | InteractiveSeries res = new InteractiveSeries(); // Здесь так надо -- мы делаем новую улыбку 87 | res.ControlPoints = new ReadOnlyCollection(m_controlPoints); 88 | 89 | return res; 90 | } 91 | 92 | public void Dispose() 93 | { 94 | if (m_controlPoints != null) 95 | { 96 | // Ни в коем случае нельзя чистить коллекцию! Только обнуляем указатель. 97 | //m_controlPoints.Clear(); 98 | m_controlPoints = null; 99 | } 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Options/QuoteIvMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TSLab.Script.Handlers.Options 4 | { 5 | public enum QuoteIvMode 6 | { 7 | Relative = 0, 8 | Absolute = 1, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Options/RaiseException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | 5 | using TSLab.Script.Optimization; 6 | using TSLab.Script.Options; 7 | 8 | namespace TSLab.Script.Handlers.Options 9 | { 10 | /// 11 | /// \~english Raise exception 12 | /// \~russian Выбросить исключение по команде юзера 13 | /// 14 | #if !DEBUG 15 | [HandlerInvisible] 16 | #endif 17 | [HandlerCategory(HandlerCategories.OptionsBugs)] 18 | [HelperName("Raise exception", Language = Constants.En)] 19 | [HelperName("Исключение", Language = Constants.Ru)] 20 | [InputsCount(1)] 21 | [Input(0, TemplateTypes.SECURITY | TemplateTypes.OPTION_SERIES | TemplateTypes.OPTION, Name = Constants.AnyOption)] 22 | [OutputsCount(1)] 23 | [OutputType(TemplateTypes.DOUBLE)] 24 | [Description("Выбросить исключение по команде юзера")] 25 | [HelperDescription("Raise exception", Constants.En)] 26 | public class RaiseException : BaseContextHandler, IValuesHandlerWithNumber, IDisposable 27 | { 28 | private bool m_raise = false; 29 | 30 | #region Parameters 31 | /// 32 | /// Свойство надо привязать к кнопке 33 | /// 34 | [HandlerParameter(Name = "Raise exception", NotOptimized = false, IsVisibleInBlock = true, Default = "false")] 35 | public bool Raise 36 | { 37 | get { return m_raise; } 38 | set { m_raise = value; } 39 | } 40 | #endregion Parameters 41 | 42 | public double Execute(IOption opt, int barNumber) 43 | { 44 | return Execute(opt.UnderlyingAsset, barNumber); 45 | } 46 | 47 | public double Execute(IOptionSeries optSer, int barNumber) 48 | { 49 | return Execute(optSer.UnderlyingAsset, barNumber); 50 | } 51 | 52 | public double Execute(ISecurity sec, int barNumber) 53 | { 54 | if (m_raise) 55 | { 56 | var msg = String.Format("[{0}] Raise exception! VariableId: {1}", 57 | GetType().Name, VariableId); 58 | Context.Log(msg, MessageType.Warning, true); 59 | 60 | throw new Exception(msg); 61 | } 62 | 63 | return 1; 64 | } 65 | 66 | public void Dispose() 67 | { 68 | if (Context != null) // если скрипт не исполнялся - контекст будет null, подписки на события тоже не будет 69 | Context.Log(String.Format("[DEBUG:{0}] {1} disposed", GetType().Name, VariableId)); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Options/SmileNodeInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using TSLab.Script.Options; 4 | 5 | namespace TSLab.Script.Handlers.Options 6 | { 7 | /// 8 | /// \~english Information about tradable smile node 9 | /// \~russian Информация о торгуемом узле улыбки 10 | /// 11 | public class SmileNodeInfo 12 | { 13 | public double F; 14 | public double dT; 15 | /// Безрисковая ставка В ПРОЦЕНТАХ 16 | public double RiskFreeRate; 17 | public double Sigma; 18 | /// Цена опциона ИЛИ волатильность задачи котирования 19 | public double OptPx; 20 | /// Сдвиг котировки опциона (в шагах цены) при использовании в качестве задачи котирования 21 | public int ShiftOptPx; 22 | public bool Expired; 23 | public double Strike; 24 | public string Symbol; 25 | public string DSName; 26 | public string FullName; 27 | public ISecurity Security; 28 | public OptionPxMode PxMode; 29 | public StrikeType OptionType; 30 | public IOptionStrikePair Pair; 31 | 32 | public DateTime ScriptTime; 33 | public DateTime CalendarTime; 34 | 35 | public double Qty = 0; 36 | public DateTime? ClickTime; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Options/SmileSelector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | using TSLab.Script.CanvasPane; 5 | 6 | namespace TSLab.Script.Handlers.Options 7 | { 8 | /// 9 | /// \~english Select one of several available smiles using handler parameter 10 | /// \~russian Выбрать одну из улыбок на основании параметра блока 11 | /// 12 | [HandlerCategory(HandlerCategories.OptionsTickByTick)] 13 | [HelperName("Select smile", Language = Constants.En)] 14 | [HelperName("Выбрать улыбку", Language = Constants.Ru)] 15 | [HandlerAlwaysKeep] 16 | [InputsCount(2, 3)] 17 | [Input(0, TemplateTypes.INTERACTIVESPLINE, Name = "Market")] 18 | [Input(1, TemplateTypes.INTERACTIVESPLINE, Name = "Model")] 19 | [Input(2, TemplateTypes.INTERACTIVESPLINE, Name = "Exchange")] 20 | [OutputType(TemplateTypes.INTERACTIVESPLINE)] 21 | [Description("Выбрать одну из улыбок на основании параметра блока")] 22 | [HelperDescription("Select one of several available smiles using handler parameter", Constants.En)] 23 | public class SmileSelector : IValuesHandlerWithNumber 24 | { 25 | private const string MsgId = "SmileSelector"; 26 | 27 | private int m_smileIndex = 0; 28 | 29 | #region Parameters 30 | /// 31 | /// \~english Input index (start from 1) 32 | /// \~russian Индекс входа (начинается с 1) 33 | /// 34 | [HelperName("Input index", Constants.En)] 35 | [HelperName("Индекс входа", Constants.Ru)] 36 | [Description("Индекс входа (начинается с 1)")] 37 | [HelperDescription("Input index (start from 1)", Language = Constants.En)] 38 | [HandlerParameter(true, NotOptimized = false, IsVisibleInBlock = true, 39 | Default = "1", Min = "1", Max = "3", Step = "1")] 40 | public int SmileIndex 41 | { 42 | get { return m_smileIndex; } 43 | set { m_smileIndex = value; } 44 | } 45 | #endregion Parameters 46 | 47 | /// 48 | /// Обработчик для двух улыбок 49 | /// 50 | public InteractiveSeries Execute(InteractiveSeries marketSmile, InteractiveSeries modelSmile, int barNum) 51 | { 52 | InteractiveSeries res = SelectSmile(m_smileIndex, 53 | marketSmile, modelSmile); 54 | return res; 55 | } 56 | 57 | /// 58 | /// Обработчик для трех улыбок 59 | /// 60 | public InteractiveSeries Execute(InteractiveSeries marketSmile, InteractiveSeries modelSmile, 61 | InteractiveSeries exchangeSmile, int barNum) 62 | { 63 | InteractiveSeries res = SelectSmile(m_smileIndex, 64 | marketSmile, modelSmile, exchangeSmile); 65 | return res; 66 | } 67 | 68 | internal static InteractiveSeries SelectSmile(int index, params InteractiveSeries[] smiles) 69 | { 70 | if ((smiles == null) || (smiles.Length <= 0) || 71 | (index < 0) || (smiles.Length <= index)) 72 | return null; 73 | 74 | InteractiveSeries res = smiles[index]; 75 | return res; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Options/SmileSkewMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TSLab.Utils; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// \~english Algorythm to get smile skew at the money 8 | /// \~russian Режим вычисления наклона улыбки на деньгах 9 | /// 10 | public enum SmileSkewMode 11 | { 12 | /// \~english Raw skew \~russian Размерный наклон 13 | //[LocalizeDisplayName("BasePxMode.FixedPx")] 14 | [LocalizeDescription("SmileSkewMode.RawSkew")] 15 | RawSkew, 16 | 17 | /// \~english Exchange skew \~russian Биржевой наклон 18 | //[LocalizeDisplayName("BasePxMode.LastTrade")] 19 | [LocalizeDescription("SmileSkewMode.ExchangeSkew")] 20 | ExchangeSkew, 21 | 22 | /// \~english True skew \~russian Истинный наклон 23 | //[LocalizeDisplayName("BasePxMode.BidAskMidPoint")] 24 | [LocalizeDescription("SmileSkewMode.RescaledSkew")] 25 | RescaledSkew, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Options/SmileTransformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TSLab.Utils; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// \~english Smile transformation 8 | /// \~russian Вид преобразования улыбки 9 | /// 10 | public enum SmileTransformation 11 | { 12 | /// 13 | /// \~english No changes 14 | /// \~russian Без изменений 15 | /// 16 | //[LocalizeDisplayName("SmileTransformation.None")] 17 | [LocalizeDescription("SmileTransformation.None")] 18 | None, 19 | 20 | /// 21 | /// \~english Simmetrise in linear coordinates 22 | /// \~russian Симметризовать в линейных координатах 23 | /// 24 | //[LocalizeDisplayName("SmileTransformation.Simmetrise")] 25 | [LocalizeDescription("SmileTransformation.Simmetrise")] 26 | Simmetrise, 27 | 28 | /// 29 | /// \~english Simmetrise in logarythmic coordinates 30 | /// \~russian Симметризовать в логарифмических координатах 31 | /// 32 | //[LocalizeDisplayName("SmileTransformation.LogSimmetrise")] 33 | [LocalizeDescription("SmileTransformation.LogSimmetrise")] 34 | LogSimmetrise, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Options/SmileType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TSLab.Utils; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | // ВАЖНО: по целочисленным значениям этого перечисления будет работать блок SmileSelector 7 | // поэтому их надо менять синхронно 8 | 9 | /// 10 | /// \~english Smile type 11 | /// \~russian Тип улыбки 12 | /// 13 | public enum SmileType 14 | { 15 | /// \~english Market smile \~russian Рыночная улыбка 16 | //[LocalizeDisplayName("SmileType.Market")] 17 | [LocalizeDescription("SmileType.Market")] 18 | Market = 0, 19 | 20 | /// \~english Model smile (it is used for delta-hedge) \~russian Модельная улыбка (используется для дельта-хеджа) 21 | //[LocalizeDisplayName("SmileType.Model")] 22 | [LocalizeDescription("SmileType.Model")] 23 | Model = 1, 24 | 25 | /// \~english Exchange smile (if exists) \~russian Биржевая улыбка (если транслируется провайдером) 26 | //[LocalizeDisplayName("SmileType.Exchange")] 27 | [LocalizeDescription("SmileType.Exchange")] 28 | Exchange = 2, 29 | 30 | ///// \~english Fit to option quotes \~russian Подгон под опционные котировки 31 | //FitToQuotes, 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Options/Smiles.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | 6 | using TSLab.DataSource; 7 | using TSLab.Script.Options; 8 | 9 | namespace TSLab.Script.Handlers.Options 10 | { 11 | /// 12 | /// \~english Options bid prices. Strike is ignored if there is no demand in it. 13 | /// \~russian Цены покупки опционов. Если цены покупки нет, страйк игнорируется. 14 | /// 15 | [HelperName("Bid smile", Language = Constants.En)] 16 | [HelperName("Улыбка по бидам", Language = Constants.Ru)] 17 | [Description("Цены покупки опционов. Если цены покупки нет, страйк игнорируется.")] 18 | [HelperDescription("Options bid prices. Strike is ignored if there is no demand in it.", Constants.En)] 19 | public class BidSmile : OptionSeriesBaseN 20 | { 21 | protected override IEnumerable Calculate(IOptionStrike[] strikes, int barNum) 22 | { 23 | return strikes.Where(st => 24 | { 25 | var security = st.Security; 26 | return !security.IsDisposed && security.Bars.Count > barNum && st.Security.Bars[barNum] is IBar && 27 | ((IBar)st.Security.Bars[barNum]).Bid > 0; 28 | }) 29 | .Select(st => new Double2 { V1 = st.Strike, V2 = ((IBar)st.Security.Bars[barNum]).Bid }); 30 | } 31 | } 32 | 33 | /// 34 | /// \~english Options ask prices. Strike is ignored if there is no offer in it. 35 | /// \~russian Цены продажи опционов. Если цены продажи нет, страйк игнорируется. 36 | /// 37 | [HelperName("Ask smile", Language = Constants.En)] 38 | [HelperName("Улыбка по оферам", Language = Constants.Ru)] 39 | [Description("Цена продажи опционов. Если цены нет, страйк игнорируется.")] 40 | [HelperDescription("Options ask prices. Strike is ignored if there is no offer in it.", Constants.En)] 41 | public class AskSmile : OptionSeriesBaseN 42 | { 43 | protected override IEnumerable Calculate(IOptionStrike[] strikes, int barNum) 44 | { 45 | return strikes.Where(st => 46 | { 47 | var security = st.Security; 48 | return !security.IsDisposed && security.Bars.Count > barNum && st.Security.Bars[barNum] is IBar && 49 | ((IBar)st.Security.Bars[barNum]).Ask > 0; 50 | }) 51 | .Select(st => new Double2 { V1 = st.Strike, V2 = ((IBar)st.Security.Bars[barNum]).Ask }); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Options/StrikeSelectionMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics.CodeAnalysis; 3 | using TSLab.Utils; 4 | 5 | namespace TSLab.Script.Handlers.Options 6 | { 7 | /// 8 | /// \~english Strike selection algorythm 9 | /// \~russian Режим выбора страйка 10 | /// 11 | public enum StrikeSelectionMode 12 | { 13 | /// 14 | /// \~english Fixed strike given in handler's settings 15 | /// \~russian Фиксированный страйк, указанный в настройках блока 16 | /// 17 | //[LocalizeDisplayName("StrikeSelectionMode.FixedStrike")] 18 | [LocalizeDescription("StrikeSelectionMode.FixedStrike")] 19 | FixedStrike, 20 | 21 | /// \~english Nearest strike to ATM \~russian Ближайший к деньгам 22 | //[LocalizeDisplayName("StrikeSelectionMode.NearestATM")] 23 | [LocalizeDescription("StrikeSelectionMode.NearestATM")] 24 | [SuppressMessage("StyleCopPlus.StyleCopPlusRules", "SP0100:AdvancedNamingRules", Justification = "Reviewed. Suppression is OK here.")] 25 | NearestATM, 26 | 27 | /// \~english Smallest strike \~russian Минимальный страйк 28 | //[LocalizeDisplayName("StrikeSelectionMode.MinStrike")] 29 | [LocalizeDescription("StrikeSelectionMode.MinStrike")] 30 | MinStrike, 31 | 32 | /// \~english Biggest strike \~russian Максимальный страйк 33 | //[LocalizeDisplayName("StrikeSelectionMode.MaxStrike")] 34 | [LocalizeDescription("StrikeSelectionMode.MaxStrike")] 35 | MaxStrike, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Options/TestSecurityDescription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | using TSLab.Script.Options; 5 | 6 | namespace TSLab.Script.Handlers.Options 7 | { 8 | /// 9 | /// Тест заполнения SecurityDescription при выключенном источнике. 10 | /// 11 | [HandlerCategory(Constants.Bugs)] 12 | [HelperName("Test Security Description")] 13 | [InputsCount(1)] 14 | [Input(0, TemplateTypes.SECURITY | TemplateTypes.OPTION_SERIES | TemplateTypes.OPTION, Name = Constants.AnyOption)] 15 | [OutputsCount(1)] 16 | [OutputType(TemplateTypes.DOUBLE)] 17 | [Description("Тест заполнения SecurityDescription при выключенном источнике.")] 18 | public class TestSecurityDescription : BaseContextHandler, IValuesHandlerWithNumber 19 | { 20 | #region Parameters 21 | #endregion Parameters 22 | 23 | /// 24 | /// Метод под флаг TemplateTypes.OPTION, чтобы подключаться к источнику-серии 25 | /// 26 | public double Execute(IOption opt, int barNumber) 27 | { 28 | return Execute(opt.UnderlyingAsset, barNumber); 29 | } 30 | 31 | /// 32 | /// Метод под флаг TemplateTypes.OPTION_SERIES, чтобы подключаться к источнику-серии 33 | /// 34 | public double Execute(IOptionSeries optSer, int barNumber) 35 | { 36 | double res = Execute(optSer.UnderlyingAsset, barNumber); 37 | 38 | if (barNumber < m_context.BarsCount - 1) 39 | return res; 40 | 41 | double accum = 0; 42 | foreach (IOptionStrike strike in optSer.GetStrikes()) 43 | { 44 | ISecurity sec = strike.Security; 45 | accum += Execute(sec, barNumber); 46 | } 47 | 48 | return res + accum; 49 | } 50 | 51 | /// 52 | /// Метод под флаг TemplateTypes.SECURITY, чтобы подключаться к источнику-серии 53 | /// 54 | public double Execute(ISecurity sec, int barNumber) 55 | { 56 | if (barNumber < m_context.BarsCount - 1) 57 | return Double.NaN; 58 | 59 | if (sec.SecurityDescription == null) 60 | m_context.Log("NOT INITIALIZED!", MessageType.Error, true); 61 | else 62 | { 63 | string msg = String.Format("Symbol: {0}; Expired: {1}; ExpirationDate:{2}", sec.Symbol, sec.SecurityDescription.Expired, sec.SecurityDescription.ExpirationDate); 64 | m_context.Log(msg, MessageType.Info, true); 65 | } 66 | 67 | return DateTime.Now.TimeOfDay.Seconds; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Options/TimeRemainMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TSLab.Utils; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// \~english Time to expiry algorythms 8 | /// \~russian Алгоритмы расчета времени до экспирации 9 | /// 10 | public enum TimeRemainMode 11 | { 12 | /// \~english Plain calendar time \~russian Равномерное календарное время 13 | //[LocalizeDisplayName("TimeRemainMode.PlainCalendar")] 14 | [LocalizeDescription("TimeRemainMode.PlainCalendar")] 15 | PlainCalendar, 16 | 17 | /// \~english Plain calendar time except weekends \~russian Равномерное календарное время без выходных дней 18 | //[LocalizeDisplayName("TimeRemainMode.PlainCalendarWithoutWeekends")] 19 | [LocalizeDescription("TimeRemainMode.PlainCalendarWithoutWeekends")] 20 | PlainCalendarWithoutWeekends, 21 | 22 | /// \~english Plain calendar time except weekends and holidays \~russian Равномерное календарное время без выходных и праздничных дней 23 | //[LocalizeDisplayName("TimeRemainMode.PlainCalendarWithoutHolidays")] 24 | [LocalizeDescription("TimeRemainMode.PlainCalendarWithoutHolidays")] 25 | PlainCalendarWithoutHolidays, 26 | 27 | /// \~english Trading time following RTS schedule \~russian Торговое время в соответствии с расписанием работы РТС 28 | //[LocalizeDisplayName("TimeRemainMode.RtsTradingTime")] 29 | [LocalizeDescription("TimeRemainMode.RtsTradingTime")] 30 | RtsTradingTime, 31 | 32 | /// \~english Liquid.Pro trading time following RTS schedule \~russian Взвешенное торговое время по алгоритму Liquid.Pro в соответствии с расписанием работы РТС 33 | //[LocalizeDisplayName("TimeRemainMode.LiquidProRtsTradingTime")] 34 | [LocalizeDescription("TimeRemainMode.LiquidProRtsTradingTime")] 35 | LiquidProRtsTradingTime, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Options/TotalCommission.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using TSLab.Script.Options; 4 | 5 | namespace TSLab.Script.Handlers.Options 6 | { 7 | /// 8 | /// \~english Total commission including closed positions 9 | /// \~russian Полная комиссия за время жизни скрипта (включая закрытые позиции) 10 | /// 11 | [HandlerCategory(HandlerCategories.OptionsPositions)] 12 | [HelperName("Total Commission", Language = Constants.En)] 13 | [HelperName("Полная комиссия", Language = Constants.Ru)] 14 | [InputsCount(1)] 15 | [Input(0, TemplateTypes.SECURITY | TemplateTypes.OPTION_SERIES | TemplateTypes.OPTION, Name = Constants.AnyOption)] 16 | [OutputType(TemplateTypes.DOUBLE)] 17 | [Description("Полная комиссия за время жизни скрипта (включая закрытые позиции)")] 18 | [HelperDescription("Total commission including closed positions", Constants.En)] 19 | public class TotalCommission : IValuesHandlerWithNumber, IDoubleReturns 20 | { 21 | #region Parameters 22 | #endregion Parameters 23 | 24 | public double Execute(ISecurity sec, int barNumber) 25 | { 26 | double res = 0; 27 | var positions = sec.Positions.GetClosedOrActiveForBar(barNumber); 28 | foreach (IPosition pos in positions) 29 | { 30 | res += pos.EntryCommission; 31 | 32 | if (!pos.IsActiveForBar(barNumber)) 33 | { 34 | res += pos.ExitCommission; 35 | } 36 | } 37 | return res; 38 | } 39 | 40 | public double Execute(IOptionSeries optSer, int barNumber) 41 | { 42 | double res = Execute(optSer.UnderlyingAsset, barNumber); 43 | 44 | foreach (var strike in optSer.GetStrikes()) 45 | { 46 | double comm = Execute(strike.Security, barNumber); 47 | res += comm; 48 | } 49 | 50 | return res; 51 | } 52 | 53 | public double Execute(IOption opt, int barNumber) 54 | { 55 | double res = Execute(opt.UnderlyingAsset, barNumber); 56 | 57 | foreach (var ser in opt.GetSeries()) 58 | { 59 | double comm = Execute(ser, barNumber); 60 | res += comm; 61 | } 62 | 63 | return res; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Options/TotalProfitAlgo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TSLab.Utils; 3 | 4 | namespace TSLab.Script.Handlers.Options 5 | { 6 | /// 7 | /// \~english Profit calculation algorythm (position type) 8 | /// \~russian Алгоритм подсчета профита (тип позиций) 9 | /// 10 | public enum TotalProfitAlgo 11 | { 12 | /// \~english All positions (both real and virtual) \~russian Все позиции (вместе реальные и виртуальные) 13 | //[LocalizeDisplayName("TotalProfitAlgo.")] 14 | [LocalizeDescription("TotalProfitAlgo.AllPositions")] 15 | AllPositions = 0, 16 | /// \~english Only real positions \~russian Только реальные позиции 17 | //[LocalizeDisplayName("TotalProfitAlgo.")] 18 | [LocalizeDescription("TotalProfitAlgo.RealPositions")] 19 | RealPositions = 1, 20 | /// \~english Only virtual positions \~russian Только виртуальные позиции 21 | //[LocalizeDisplayName("TotalProfitAlgo.")] 22 | [LocalizeDescription("TotalProfitAlgo.VirtualPositions")] 23 | VirtualPositions = 2, 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Options/VerticalLine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | 5 | namespace TSLab.Script.Handlers.Options 6 | { 7 | /// 8 | /// \~english Vertical line for CanvasPane (no interaction with user) 9 | /// \~russian Вертикальная линия без возможности взаимодействия с пользователем 10 | /// 11 | [HandlerCategory(HandlerCategories.Options)] 12 | [HelperName("Vertical Line", Language = Constants.En)] 13 | [HelperName("Вертикальная линия", Language = Constants.Ru)] 14 | [InputsCount(1)] 15 | [Input(0, TemplateTypes.DOUBLE)] 16 | [OutputType(TemplateTypes.DOUBLE2)] 17 | //[Obsolete("Недостаточно просто рисовать линию. Надо ещё взаимодействовать с пользователем. Используйте VerticalLine2.")] 18 | [Description("Вертикальная линия без возможности взаимодействия с пользователем")] 19 | [HelperDescription("Vertical line for CanvasPane (no interaction with user)", Constants.En)] 20 | public class VerticalLine : IContextUses, IStreamHandler 21 | { 22 | private IContext m_context; 23 | private double m_sigmaLow = 0.10, m_sigmaHigh = 0.50; 24 | 25 | public IContext Context 26 | { 27 | get { return m_context; } 28 | set { m_context = value; } 29 | } 30 | 31 | #region Parameters 32 | /// 33 | /// \~english Low level of this marker (in percents) 34 | /// \~russian Нижний уровень маркера (в процентах) 35 | /// 36 | [HelperName("Sigma Low, %", Constants.En)] 37 | [HelperName("Нижний уровень, %", Constants.Ru)] 38 | [ReadOnly(true)] 39 | [Description("Нижний уровень маркера (в процентах)")] 40 | [HelperDescription("Low level of this marker (in percents)", Language = Constants.En)] 41 | [HandlerParameter(true, "10", Min = "0", Max = "10000000", Step = "0.01", NotOptimized = true)] 42 | public double SigmaLowPct 43 | { 44 | get { return m_sigmaLow * Constants.PctMult; } 45 | set 46 | { 47 | if (value > 0) 48 | m_sigmaLow = value / Constants.PctMult; 49 | } 50 | } 51 | 52 | /// 53 | /// \~english High level of this marker (in percents) 54 | /// \~russian Верхний уровень маркера (в процентах) 55 | /// 56 | [HelperName("Sigma High, %", Constants.En)] 57 | [HelperName("Верхний уровень, %", Constants.Ru)] 58 | [ReadOnly(true)] 59 | [Description("Верхний уровень маркера (в процентах)")] 60 | [HelperDescription("High level of this marker (in percents)", Language = Constants.En)] 61 | [HandlerParameter(true, "50", Min = "0", Max = "10000000", Step = "0.01", NotOptimized = true)] 62 | public double SigmaHighPct 63 | { 64 | get { return m_sigmaHigh * Constants.PctMult; } 65 | set 66 | { 67 | if (value > 0) 68 | m_sigmaHigh = value / Constants.PctMult; 69 | } 70 | } 71 | #endregion Parameters 72 | 73 | public IList Execute(IList prices) 74 | { 75 | List res = new List(); 76 | 77 | if (prices.Count <= 0) 78 | return res; 79 | 80 | double f = prices[prices.Count - 1]; 81 | res.Add(new Double2(f, m_sigmaLow)); 82 | res.Add(new Double2(f, m_sigmaHigh)); 83 | 84 | return res; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /ProfitExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace TSLab.Script.Handlers 5 | { 6 | internal static class ProfitExtensions 7 | { 8 | public static double GetProfit(this ISecurity security, int barNum) 9 | { 10 | var result = security.Positions.GetProfit(barNum); 11 | return result; 12 | } 13 | 14 | private static double GetProfit(this IEnumerable positions, int barNum) 15 | { 16 | var result = positions.Sum(item => item.GetProfit(barNum)); 17 | return result; 18 | } 19 | 20 | public static double GetProfit(this IPosition position, int barNum) 21 | { 22 | var result = position.EntryBarNum > barNum ? 0 : position.IsActiveForBar(barNum) ? position.CurrentProfit(barNum) : position.Profit(); 23 | return result; 24 | } 25 | 26 | public static double GetAccumulatedProfit(this ISecurity security, int barNum) 27 | { 28 | var result = security.Positions.GetAccumulatedProfit(barNum); 29 | return result; 30 | } 31 | 32 | private static double GetAccumulatedProfit(this IEnumerable positions, int barNum) 33 | { 34 | var result = positions.Sum(item => GetAccumulatedProfit(item, barNum)); 35 | return result; 36 | } 37 | 38 | public static double GetAccumulatedProfit(this IPosition position, int barNum) 39 | { 40 | var result = position.EntryBarNum > barNum ? 0 : position.IsActiveForBar(barNum) ? position.GetAccumulatedProfit(barNum) : position.Profit(); 41 | return result; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Sources of the built-in handlers 2 | 3 | Исходные файлы встроенных обработчиков 4 | -------------------------------------------------------------------------------- /ResettableControlledBoolConst.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | 6 | using TSLab.Script.Handlers.Options; 7 | using TSLab.Script.Optimization; 8 | using TSLab.Utils; 9 | 10 | namespace TSLab.Script.Handlers 11 | { 12 | [HandlerCategory(HandlerCategories.TradeMath)] 13 | [HelperName("Resettable Controlled Boolean Constant", Language = Constants.En)] 14 | [HelperName("Сбрасываемая управляемая логическая константа", Language = Constants.Ru)] 15 | [InputsCount(2)] 16 | [Input(0, TemplateTypes.BOOL)] 17 | [Input(1, TemplateTypes.BOOL)] 18 | [OutputsCount(1)] 19 | [OutputType(TemplateTypes.BOOL)] 20 | [Description("Сбрасываемая управляемая логическая константа (переключатель). " + 21 | "При поступлении на вход значения 'Истина' данный блок выдает значение из поля 'Значение', при поступлении на вход значения 'Ложь' используется 'Значение по умолчанию'. " + 22 | "Второй вход определяет чему равно 'Значение'. Если в нем больше истин, то 'Значение' становится равно 'Значению по умолчанию'.")] 23 | [HelperDescription("Resettable controlled boolean constant (switch). " + 24 | "If input is TRUE the result is taken from a field 'Value', otherwise the result is taken from a field 'Default value'. " + 25 | "Second input determines 'Value'. If it contains more TRUE, then 'Value' is set to 'Default value'.", Constants.En)] 26 | public sealed class ResettableControlledBoolConst : ITwoSourcesHandler, IBooleanReturns, IStreamHandler, IValuesHandlerWithNumber, IBooleanInputs, IContextUses 27 | { 28 | public IContext Context { get; set; } 29 | 30 | /// 31 | /// \~english A value to return as output of a handler when input is true 32 | /// \~russian Значение на выходе блока, если на вход подать 'Истина' 33 | /// 34 | [HelperName("Value", Constants.En)] 35 | [HelperName("Значение", Constants.Ru)] 36 | [Description("Значение на выходе блока, если на вход подать 'Истина'")] 37 | [HelperDescription("A value to return as output of a handler when input is true", Constants.En)] 38 | [HandlerParameter] 39 | public BoolOptimProperty Value { get; set; } 40 | 41 | /// 42 | /// \~english A value to return as output of a handler when input is false 43 | /// \~russian Значение на выходе блока, если на вход подать 'Ложь' 44 | /// 45 | [HelperName("Default value", Constants.En)] 46 | [HelperName("Значение по умолчанию", Constants.Ru)] 47 | [Description("Значение на выходе блока, если на вход подать 'Ложь'")] 48 | [HelperDescription("A value to return as output of a handler when input is false", Constants.En)] 49 | [HandlerParameter(NotOptimized = true)] 50 | public bool DefaultValue { get; set; } 51 | 52 | public IList Execute(IList source, IList resetValues) 53 | { 54 | if (source == null) 55 | throw new ArgumentNullException(nameof(source)); 56 | 57 | if (resetValues == null) 58 | throw new ArgumentNullException(nameof(resetValues)); 59 | 60 | var count = Math.Min(source.Count, resetValues.Count); 61 | if (count == 0) 62 | return EmptyArrays.Bool; 63 | 64 | if (resetValues[count - 1]) 65 | Value.Value = DefaultValue; 66 | 67 | var firstValue = source[0]; 68 | if (source.Take(count).All(item => item == firstValue)) 69 | return new ConstList(count, firstValue ? Value : DefaultValue); 70 | 71 | var result = Context?.GetArray(count) ?? new bool[count]; 72 | for (var i = 0; i < result.Length; i++) 73 | result[i] = source[i] ? Value : DefaultValue; 74 | 75 | return result; 76 | } 77 | 78 | public bool Execute(bool source, bool resetValue, int number) 79 | { 80 | if (resetValue && number == Context.BarsCount - (Context.IsLastBarUsed ? 1 : 2)) 81 | Value.Value = DefaultValue; 82 | 83 | var result = source ? Value : DefaultValue; 84 | return result; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /ResultForOptimization.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TSLab.Script.Handlers 4 | { 5 | [HandlerCategory(HandlerCategories.TradeMath)] 6 | [InputsCount(1)] 7 | [Input(0, TemplateTypes.DOUBLE)] 8 | [OutputsCount(0)] 9 | public class ResultForOptimization : IOneSourceHandler, IValuesHandler, IDoubleInputs, IDoubleReturns, IContextUses 10 | { 11 | public IContext Context { set; get; } 12 | 13 | public double Execute(double value, int barNum) 14 | { 15 | Context.ScriptResult = value; 16 | return value; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SellsHandler.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using TSLab.Script.Handlers.Options; 3 | 4 | namespace TSLab.Script.Handlers 5 | { 6 | [HandlerCategory(HandlerCategories.VolumeAnalysis)] 7 | [HelperName("Sells", Language = Constants.En)] 8 | [HelperName("Продажи", Language = Constants.Ru)] 9 | [InputsCount(1)] 10 | [Input(0, TemplateTypes.SECURITY, Name = Constants.SecuritySource)] 11 | [OutputsCount(1)] 12 | [OutputType(TemplateTypes.DOUBLE)] 13 | [Description("Показывает характеристики (количество или суммарный объем) сделок на продажу")] 14 | [HelperDescription("A handler calculates statistics (amount or total volume) of a short trades", Constants.En)] 15 | public sealed class SellsHandler : BuysSellsHandler 16 | { 17 | protected override double GetValue(ICachedTradeHistogram histogram) 18 | { 19 | return histogram.BidQuantity; 20 | } 21 | 22 | protected override int GetCount(ICachedTradeHistogram histogram) 23 | { 24 | return histogram.BidTradesCount; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ShrinkedList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace TSLab.Script.Handlers 6 | { 7 | public sealed class ShrinkedList : IList 8 | { 9 | private readonly List m_list; 10 | 11 | public ShrinkedList(int capacity) 12 | { 13 | if (capacity < 1) 14 | throw new ArgumentOutOfRangeException(nameof(capacity)); 15 | 16 | m_list = new List(capacity); 17 | } 18 | 19 | public IEnumerator GetEnumerator() 20 | { 21 | return m_list.GetEnumerator(); 22 | } 23 | 24 | IEnumerator IEnumerable.GetEnumerator() 25 | { 26 | return m_list.GetEnumerator(); 27 | } 28 | 29 | public void Add(T item) 30 | { 31 | if (m_list.Count == m_list.Capacity) 32 | m_list.RemoveAt(0); 33 | 34 | m_list.Add(item); 35 | } 36 | 37 | public void Clear() 38 | { 39 | m_list.Clear(); 40 | } 41 | 42 | public bool Contains(T item) 43 | { 44 | return m_list.Contains(item); 45 | } 46 | 47 | public void CopyTo(T[] array, int arrayIndex) 48 | { 49 | m_list.CopyTo(array, arrayIndex); 50 | } 51 | 52 | public bool Remove(T item) 53 | { 54 | return m_list.Remove(item); 55 | } 56 | 57 | public int Count 58 | { 59 | get { return m_list.Count; } 60 | } 61 | 62 | public bool IsReadOnly 63 | { 64 | get { return ((IList)m_list).IsReadOnly; } 65 | } 66 | 67 | public int IndexOf(T item) 68 | { 69 | return m_list.IndexOf(item); 70 | } 71 | 72 | public void Insert(int index, T item) 73 | { 74 | m_list.Insert(index, item); 75 | } 76 | 77 | public void RemoveAt(int index) 78 | { 79 | m_list.RemoveAt(index); 80 | } 81 | 82 | public T this[int index] 83 | { 84 | get { return m_list[index]; } 85 | set { m_list[index] = value; } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /SpecifiedQuantityPriceAtTradeHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using TSLab.DataSource; 6 | 7 | namespace TSLab.Script.Handlers 8 | { 9 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 10 | public sealed class SpecifiedQuantityPriceAtTradeHandler : ISpecifiedQuantityPriceAtTradeHandler 11 | { 12 | public IContext Context { get; set; } 13 | 14 | [HandlerParameter(true, "0", Min = "0", Max = "2147483647", Step = "1", EditorMin = "0", EditorMax = "2147483647")] 15 | public double Quantity { get; set; } 16 | 17 | [HandlerParameter(true, nameof(SpecifiedTradeDirection.Any))] 18 | public SpecifiedTradeDirection Direction { get; set; } 19 | 20 | public IList Execute(ISecurity security) 21 | { 22 | Func isValidTradeFunc; 23 | if (Direction == SpecifiedTradeDirection.Any) 24 | isValidTradeFunc = IsValidAnyTrade; 25 | else if (Direction == SpecifiedTradeDirection.Buy) 26 | isValidTradeFunc = IsValidBuyTrade; 27 | else if (Direction == SpecifiedTradeDirection.Sell) 28 | isValidTradeFunc = IsValidSellTrade; 29 | else 30 | throw new InvalidEnumArgumentException(nameof(Direction), (int)Direction, typeof(SpecifiedTradeDirection)); 31 | 32 | var barsCount = Context.BarsCount; 33 | var results = Context.GetArray(barsCount); 34 | var tradesCache = Context.GetTradesCache(security); 35 | var price = 0D; 36 | 37 | for (var i = 0; i < barsCount; i++) 38 | { 39 | var trade = tradesCache.GetTrades(i).LastOrDefault(isValidTradeFunc); 40 | if (trade != null) 41 | price = trade.Price; 42 | 43 | results[i] = price; 44 | } 45 | return results; 46 | } 47 | 48 | private bool IsValidAnyTrade(ITrade trade) 49 | { 50 | return trade.Quantity > Quantity; 51 | } 52 | 53 | private bool IsValidBuyTrade(ITrade trade) 54 | { 55 | return trade.Direction == TradeDirection.Buy && trade.Quantity > Quantity; 56 | } 57 | 58 | private bool IsValidSellTrade(ITrade trade) 59 | { 60 | return trade.Direction == TradeDirection.Sell && trade.Quantity > Quantity; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /SumForTimeFrameHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using TSLab.DataSource; 6 | using TSLab.Script.Handlers.Options; 7 | 8 | namespace TSLab.Script.Handlers 9 | { 10 | // TODO: у этого кубика нет описания. Судя по коду что-то вроде "сумма значений в пределах указанного таймфрейма" 11 | [HandlerCategory(HandlerCategories.Indicators)] 12 | [HelperName("Sum for time frame", Language = Constants.En)] 13 | [HelperName("Сумма за таймфрейм", Language = Constants.Ru)] 14 | [InputsCount(1)] 15 | [Input(0, TemplateTypes.DOUBLE)] 16 | [OutputsCount(1)] 17 | [OutputType(TemplateTypes.DOUBLE)] 18 | [Description("Сумма за таймфрейм")] 19 | [HelperDescription("Sum for time frame", Constants.En)] 20 | public sealed class SumForTimeFrameHandler : IDoubleStreamAndValuesHandler 21 | { 22 | public IContext Context { get; set; } 23 | 24 | public bool IsGapTolerant => true; 25 | 26 | /// 27 | /// \~english Timeframe (format D.HH:MM:SS) 28 | /// \~russian Интервал (формат Д.ЧЧ:ММ:СС) 29 | /// 30 | [HelperName("Timeframe", Constants.En)] 31 | [HelperName("Интервал", Constants.Ru)] 32 | [Description("Интервал (формат Д.ЧЧ:ММ:СС)")] 33 | [HelperDescription("Timeframe (format D.HH:MM:SS)", Constants.En)] 34 | [HandlerParameter(true, "1:0:0", Min = "0:0:0", Max = "365.0:0:0", Step = "0:1:0", EditorMin = "0:0:0", EditorMax = "365.0:0:0")] 35 | public TimeSpan TimeFrame { get; set; } 36 | 37 | private DateTime m_firstDateTime; 38 | private DateTime m_lastDateTime; 39 | private double m_sum; 40 | private int m_index = -1; 41 | 42 | public IList Execute(IList values) 43 | { 44 | var security = Context.Runtime.Securities.First(); 45 | var bars = security.Bars; 46 | var count = Math.Min(bars.Count, values.Count); 47 | 48 | if (count == 0) 49 | return new ConstList(values.Count, 0); 50 | 51 | var results = Context?.GetArray(values.Count) ?? new double[values.Count]; 52 | TimeFrameUtils.GetFirstBounds(TimeFrame, bars[0].Date, out var firstDateTime, out var lastDateTime); 53 | var sum = 0D; 54 | 55 | for (var i = 0; i < count; i++) 56 | { 57 | var barDate = bars[i].Date; 58 | if (barDate >= lastDateTime) 59 | { 60 | TimeFrameUtils.GetBounds(TimeFrame, barDate, ref firstDateTime, ref lastDateTime); 61 | sum = 0; 62 | } 63 | results[i] = sum += values[i]; 64 | } 65 | for (var i = count; i < results.Length; i++) 66 | results[i] = sum; 67 | 68 | return results; 69 | } 70 | 71 | public double Execute(double value, int index) 72 | { 73 | if (index < m_index) 74 | throw new InvalidOperationException(); 75 | 76 | if (index == m_index) 77 | return m_sum; 78 | 79 | var security = Context.Runtime.Securities.First(); 80 | var bars = security.Bars; 81 | var count = Math.Min(bars.Count, index + 1); 82 | 83 | if (count == 0) 84 | return 0; 85 | 86 | if (m_firstDateTime == default(DateTime)) 87 | TimeFrameUtils.GetFirstBounds(TimeFrame, bars[index].Date, out m_firstDateTime, out m_lastDateTime); 88 | 89 | for (var i = m_index + 1; i < count; i++) 90 | { 91 | var barDate = bars[i].Date; 92 | if (barDate >= m_lastDateTime) 93 | { 94 | TimeFrameUtils.GetBounds(TimeFrame, barDate, ref m_firstDateTime, ref m_lastDateTime); 95 | m_sum = 0; 96 | } 97 | m_sum += value; 98 | } 99 | m_index = index; 100 | return m_sum; 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /TextHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using TSLab.Script.Handlers.Options; 5 | 6 | namespace TSLab.Script.Handlers 7 | { 8 | [HandlerCategory(HandlerCategories.TradeMath)] 9 | [HelperName("Text", Language = Constants.En)] 10 | [HelperName("Текст", Language = Constants.Ru)] 11 | [InputsCount(0)] 12 | [Description("Блок без входов. Содержит редактируемый строковый параметр, который будет возвращаться из блока в качестве результата его работы.")] 13 | [HelperDescription("This block has no entries. It has an editable text parameter which returns as a result of its work.", Constants.En)] 14 | public sealed class TextHandler : IValuesHandler, IStringReturns, ICustomListValues 15 | { 16 | /// 17 | /// \~english Text (string) 18 | /// \~russian Текст (строка) 19 | /// 20 | [HelperName("Text", Constants.En)] 21 | [HelperName("Текст", Constants.Ru)] 22 | [Description("Текст (строка)")] 23 | [HelperDescription("Text (string)", Constants.En)] 24 | [HandlerParameter(Default = "*")] 25 | public string Text { get; set; } 26 | 27 | public string Execute() 28 | { 29 | return Text; 30 | } 31 | 32 | public IEnumerable GetValuesForParameter(string paramName) 33 | { 34 | return new[] { Text }; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /TradeMath/OrderBookPrice.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TSLab.Script.Handlers.Options; 3 | 4 | namespace TSLab.Script.Handlers 5 | { 6 | 7 | [HandlerCategory(HandlerCategories.TradeMath)] 8 | [HelperName("OrderBookPrice", Language = Constants.En)] 9 | [HelperName("OrderBookPrice", Language = Constants.Ru)] 10 | [InputsCount(1)] 11 | [Input(0, TemplateTypes.SECURITY, Name = Constants.SecuritySource)] 12 | [OutputsCount(1)] 13 | [OutputType(TemplateTypes.DOUBLE)] 14 | public sealed class OrderBookPrice : IBar2ValueDoubleHandler 15 | { 16 | [HandlerParameter] 17 | public bool Buy { get; set; } 18 | [HandlerParameter(Min = "0", Default = "0")] 19 | public int Index { get; set; } 20 | 21 | public double Execute(ISecurity sec, int barNum) 22 | { 23 | var qds = Buy ? sec.GetBuyQueue(0) : sec.GetSellQueue(0); 24 | if (qds?.Count > 0 && Index >= 0 && qds.Count > Index) 25 | { 26 | var qd = qds[Index]; 27 | return qd?.Price ?? 0.0; 28 | } 29 | 30 | return 0d; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /TradeMath/OrderBookQty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TSLab.Script.Handlers.Options; 3 | 4 | namespace TSLab.Script.Handlers 5 | { 6 | [HandlerCategory(HandlerCategories.TradeMath)] 7 | [HelperName("OrderBookQuantity", Language = Constants.En)] 8 | [HelperName("OrderBookQuantity", Language = Constants.Ru)] 9 | [InputsCount(1)] 10 | [Input(0, TemplateTypes.SECURITY, Name = Constants.SecuritySource)] 11 | [OutputsCount(1)] 12 | [OutputType(TemplateTypes.DOUBLE)] 13 | public sealed class OrderBookQty : IBar2ValueDoubleHandler 14 | { 15 | [HandlerParameter] 16 | public bool Buy { get; set; } 17 | [HandlerParameter(Min = "0", Default= "0")] 18 | public int Index { get; set; } 19 | 20 | public double Execute(ISecurity sec, int barNum) 21 | { 22 | var qds = Buy ? sec.GetBuyQueue(0) : sec.GetSellQueue(0); 23 | if (qds?.Count > 0 && Index >= 0 && qds.Count > Index) 24 | { 25 | var qd = qds[Index]; 26 | return qd?.Quantity ?? 0.0; 27 | } 28 | 29 | return 0d; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /TradeMath/OrderBookTotal.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TSLab.Script.Handlers.Options; 3 | 4 | namespace TSLab.Script.Handlers 5 | { 6 | [HandlerCategory(HandlerCategories.TradeMath)] 7 | [HelperName("OrderBookTotal", Language = Constants.En)] 8 | [HelperName("OrderBookTotal", Language = Constants.Ru)] 9 | [InputsCount(1)] 10 | [Input(0, TemplateTypes.SECURITY, Name = Constants.SecuritySource)] 11 | [OutputsCount(1)] 12 | [OutputType(TemplateTypes.DOUBLE)] 13 | public class OrderBookTotal : IBar2ValueDoubleHandler 14 | { 15 | [HandlerParameter] 16 | public bool Buy { get; set; } 17 | [HandlerParameter(Min = "0", Default = "0")] 18 | public int NumberRows { get; set; } 19 | 20 | public double Execute(ISecurity sec, int barNum) 21 | { 22 | if (NumberRows > 0) 23 | { 24 | var qds = Buy ? sec.GetBuyQueue(0) : sec.GetSellQueue(0); 25 | if (qds?.Count > 0) 26 | { 27 | var cnt = qds.Count > NumberRows ? NumberRows : qds.Count; 28 | double total = 0d; 29 | for (int i = 0; i < cnt; i++) 30 | { 31 | var qd = qds[i]; 32 | total += qd.Quantity; 33 | } 34 | return total; 35 | } 36 | } 37 | 38 | return 0d; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /TradeStatisticsBarsCountHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using System.Linq; 4 | 5 | using TSLab.Script.Handlers.Options; 6 | 7 | namespace TSLab.Script.Handlers 8 | { 9 | // TODO: английское описание 10 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 11 | [HelperName("Trade Statistics Strings Count", Language = Constants.En)] 12 | [HelperName("Количество строк торговой статистики", Language = Constants.Ru)] 13 | [InputsCount(1)] 14 | [Input(0, TemplateTypes.TRADE_STATISTICS | TemplateTypes.LAST_CONTRACTS_TRADE_STATISTICS)] 15 | [OutputsCount(1)] 16 | [OutputType(TemplateTypes.DOUBLE)] 17 | [Description("Блок 'Количество строк торговой статистики' выдает количество строк торговой статистики, соответствующее выбранному фильтру.")] 18 | [HelperDescription("", Constants.En)] 19 | public sealed class TradeStatisticsBarsCountHandler : TradeStatisticsBarsHandler, ITradeStatisticsBarsCountHandler 20 | { 21 | protected override double GetResult(IBaseTradeStatisticsWithKind tradeStatistics, IEnumerable bars) 22 | { 23 | return bars.Count(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /TradeStatisticsBarsSumHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using System.Linq; 4 | 5 | using TSLab.Script.Handlers.Options; 6 | 7 | namespace TSLab.Script.Handlers 8 | { 9 | // TODO: английское описание 10 | // TODO: удачно ли здесь использовать слово 'string' как перевод слова 'строка'? 11 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 12 | [HelperName("Trade Statistics Strings Sum", Language = Constants.En)] 13 | [HelperName("Сумма строк торговой статистики", Language = Constants.Ru)] 14 | [InputsCount(1)] 15 | [Input(0, TemplateTypes.TRADE_STATISTICS | TemplateTypes.LAST_CONTRACTS_TRADE_STATISTICS)] 16 | [OutputsCount(1)] 17 | [OutputType(TemplateTypes.DOUBLE)] 18 | [Description("Блок 'Сумма строк торговой статистики' выдает значение, основанное на сумме значений строк торговой статистики.")] 19 | [HelperDescription("", Constants.En)] 20 | public sealed class TradeStatisticsBarsSumHandler : TradeStatisticsBarsHandler, ITradeStatisticsBarsCountHandler 21 | { 22 | protected override double GetResult(IBaseTradeStatisticsWithKind tradeStatistics, IEnumerable bars) 23 | { 24 | return bars.Sum(item => tradeStatistics.GetValue(item)); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /TradeStatisticsBaseExtremumPriceHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using TSLab.Script.Handlers.Options; 6 | 7 | namespace TSLab.Script.Handlers 8 | { 9 | //[HandlerCategory(HandlerCategories.ClusterAnalysis)] 10 | // Не стоит навешивать на абстрактные классы атрибуты категорий и описания входов/выходов. Это снижает гибкость управления в перспективе. 11 | 12 | /// 13 | /// Базовый класс для расчета экстремумов торговой стаистистики. 14 | /// На вход подается Торговая Статистика, на выход идут числа. 15 | /// 16 | public abstract class TradeStatisticsBaseExtremumPriceHandler : ITradeStatisticsBaseExtremumPriceHandler 17 | { 18 | protected sealed class Extremum 19 | { 20 | public Extremum(ITradeHistogramBar bar, double value, double price) 21 | { 22 | Bar = bar; 23 | Value = value; 24 | Price = price; 25 | } 26 | 27 | public ITradeHistogramBar Bar { get; } 28 | public double Value { get; } 29 | public double Price { get; } 30 | } 31 | 32 | public string VariableId { get; set; } 33 | 34 | public IContext Context { get; set; } 35 | 36 | /// 37 | /// \~english Extremum kind (minimum, maximum). 38 | /// \~russian Вид экстремума (минимум, максимум). 39 | /// 40 | [HelperName("Extremum kind", Constants.En)] 41 | [HelperName("Вид экстремума", Constants.Ru)] 42 | [Description("Вид экстремума (минимум, максимум)")] 43 | [HelperDescription("Extremum kind (minimum, maximum).", Constants.En)] 44 | [HandlerParameter(true, nameof(ExtremumPriceMode.Minimum))] 45 | public ExtremumPriceMode PriceMode { get; set; } 46 | 47 | public abstract IList Execute(IBaseTradeStatisticsWithKind tradeStatistics); 48 | 49 | protected Extremum GetExtremum(IBaseTradeStatisticsWithKind tradeStatistics, int barIndex, ref double lastPrice) 50 | { 51 | var bars = tradeStatistics.GetAggregatedHistogramBars(barIndex); 52 | if (bars.Count == 0) 53 | return new Extremum(null, double.NaN, lastPrice); 54 | 55 | if (bars.Count == 1) 56 | { 57 | var bar = bars[0]; 58 | return new Extremum(bar, Math.Abs(tradeStatistics.GetValue(bar)), lastPrice = bar.AveragePrice); 59 | } 60 | IEnumerable orderedBars; 61 | switch (PriceMode) 62 | { 63 | case ExtremumPriceMode.Minimum: 64 | orderedBars = bars; 65 | break; 66 | case ExtremumPriceMode.Maximum: 67 | orderedBars = bars.Reverse(); 68 | break; 69 | default: 70 | throw new InvalidEnumArgumentException(nameof(PriceMode), (int)PriceMode, PriceMode.GetType()); 71 | } 72 | var extremumBar = orderedBars.First(); 73 | var extremumValue = Math.Abs(tradeStatistics.GetValue(extremumBar)); 74 | 75 | foreach (var bar in orderedBars.Skip(1)) 76 | { 77 | var value = Math.Abs(tradeStatistics.GetValue(bar)); 78 | if (extremumValue < value) 79 | { 80 | extremumBar = bar; 81 | extremumValue = value; 82 | } 83 | } 84 | return new Extremum(extremumBar, extremumValue, lastPrice = extremumBar.AveragePrice); 85 | } 86 | 87 | protected virtual string GetParametersStateId() 88 | { 89 | return PriceMode.ToString(); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /TradeStatisticsExtendedBarsCountHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using System.Linq; 4 | 5 | using TSLab.Script.Handlers.Options; 6 | 7 | namespace TSLab.Script.Handlers 8 | { 9 | // TODO: английское описание 10 | // TODO: удачно ли здесь использовать слово 'string' как перевод слова 'строка'? 11 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 12 | [HelperName("Trade Statistics Extended Strings Count 1", Language = Constants.En)] 13 | [HelperName("Расширенное количество строк торговой статистики 1", Language = Constants.Ru)] 14 | [InputsCount(1)] 15 | [Input(0, TemplateTypes.TRADE_STATISTICS | TemplateTypes.LAST_CONTRACTS_TRADE_STATISTICS)] 16 | [OutputsCount(1)] 17 | [OutputType(TemplateTypes.DOUBLE)] 18 | [Description("Блок 'Расширенное количество строк торговой статистики 1' выдает количество строк торговой статистики, соответствующее выбранному фильтру.")] 19 | [HelperDescription("", Constants.En)] 20 | public sealed class TradeStatisticsExtendedBarsCountHandler : TradeStatisticsExtendedBarsHandler, ITradeStatisticsExtendedBarsCountHandler 21 | { 22 | protected override double GetResult(IBaseTradeStatisticsWithKind tradeStatistics, IEnumerable bars) 23 | { 24 | return bars.Count(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /TradeStatisticsExtendedBarsCountHandler2.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using System.Linq; 4 | 5 | using TSLab.Script.Handlers.Options; 6 | 7 | namespace TSLab.Script.Handlers 8 | { 9 | // TODO: английское описание 10 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 11 | [HelperName("Trade Statistics Extended Strings Count 2", Language = Constants.En)] 12 | [HelperName("Расширенное количество строк торговой статистики 2", Language = Constants.Ru)] 13 | [InputsCount(1)] 14 | [Input(0, TemplateTypes.TRADE_STATISTICS | TemplateTypes.LAST_CONTRACTS_TRADE_STATISTICS)] 15 | [OutputsCount(1)] 16 | [OutputType(TemplateTypes.DOUBLE)] 17 | [Description("Блок 'Расширенное количество строк торговой статистики 2' выдает количество строк торговой статистики, соответствующее выбранному фильтру.")] 18 | [HelperDescription("", Constants.En)] 19 | public sealed class TradeStatisticsExtendedBarsCountHandler2 : TradeStatisticsExtendedBarsHandler2, ITradeStatisticsExtendedBarsCountHandler2 20 | { 21 | protected override double GetResult(IBaseTradeStatisticsWithKind tradeStatistics, IEnumerable bars) 22 | { 23 | return bars.Count(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /TradeStatisticsExtendedBarsHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | 4 | using TSLab.Script.Handlers.Options; 5 | 6 | namespace TSLab.Script.Handlers 7 | { 8 | // Не стоит навешивать на абстрактные классы атрибуты категорий и описания входов/выходов 9 | public abstract class TradeStatisticsExtendedBarsHandler : TradeStatisticsBaseExtendedBarsHandler, ITradeStatisticsExtendedBarsHandler 10 | { 11 | [HandlerParameter(true, NotOptimized = true)] 12 | public bool UseTrimTradesCount { get; set; } 13 | 14 | [HandlerParameter(true, "0", Min = "0", Max = "2147483647", Step = "1", EditorMin = "0")] 15 | public int TrimTradesCount { get; set; } 16 | 17 | [HandlerParameter(true, NotOptimized = true)] 18 | public bool UseTrimQuantity { get; set; } 19 | 20 | [HandlerParameter(true, "0", Min = "0", Max = "999999999999999", Step = "1", EditorMin = "0")] 21 | public double TrimQuantity { get; set; } 22 | 23 | [HandlerParameter(true, NotOptimized = true)] 24 | public bool UseTrimAskQuantity { get; set; } 25 | 26 | [HandlerParameter(true, "0", Min = "0", Max = "999999999999999", Step = "1", EditorMin = "0")] 27 | public double TrimAskQuantity { get; set; } 28 | 29 | [HandlerParameter(true, NotOptimized = true)] 30 | public bool UseTrimBidQuantity { get; set; } 31 | 32 | [HandlerParameter(true, "0", Min = "0", Max = "999999999999999", Step = "1", EditorMin = "0")] 33 | public double TrimBidQuantity { get; set; } 34 | 35 | [HandlerParameter(true, NotOptimized = true)] 36 | public bool UseTrimDeltaAskBidQuantity { get; set; } 37 | 38 | [HandlerParameter(true, "0", Min = "-999999999999999", Max = "999999999999999", Step = "1")] 39 | public double TrimDeltaAskBidQuantity { get; set; } 40 | 41 | [HandlerParameter(true, "false", NotOptimized = true)] 42 | public bool UseTrimRelativeDeltaAskBidQuantityPercent { get; set; } 43 | 44 | [HandlerParameter(true, "0", Min = "-100", Max = "100", Step = "1")] 45 | public double TrimRelativeDeltaAskBidQuantityPercent { get; set; } 46 | 47 | /// 48 | /// \~english Comparison operator for trimming (greater, greater or equal, less, less or equal, equal, not equal). 49 | /// \~russian Оператор сравнения для формирования отсечек (больше, больше или равно, меньше, меньше или равно, равно, не равно). 50 | /// 51 | [HelperName("Comparison operator", Constants.En)] 52 | [HelperName("Режим сравнения отсечки", Constants.Ru)] 53 | [Description("Оператор сравнения для формирования отсечек (больше, больше или равно, меньше, меньше или равно, равно, не равно).")] 54 | [HelperDescription("Comparison operator for trimming (greater, greater or equal, less, less or equal, equal, not equal).", Constants.En)] 55 | [HandlerParameter(true, nameof(ComparisonMode.GreaterOrEqual))] 56 | public ComparisonMode TrimComparisonMode { get; set; } 57 | 58 | public IList Execute(IBaseTradeStatisticsWithKind tradeStatistics) 59 | { 60 | return Execute( 61 | tradeStatistics, 62 | new TrimContext(UseTrimTradesCount, TrimTradesCount, TrimComparisonMode), 63 | new TrimContext(UseTrimQuantity, TrimQuantity, TrimComparisonMode), 64 | new TrimContext(UseTrimAskQuantity, TrimAskQuantity, TrimComparisonMode), 65 | new TrimContext(UseTrimBidQuantity, TrimBidQuantity, TrimComparisonMode), 66 | new TrimContext(UseTrimDeltaAskBidQuantity, TrimDeltaAskBidQuantity, TrimComparisonMode), 67 | new TrimContext(UseTrimRelativeDeltaAskBidQuantityPercent, TrimRelativeDeltaAskBidQuantityPercent, TrimComparisonMode)); 68 | } 69 | 70 | protected override string GetParametersStateId() 71 | { 72 | return string.Join( 73 | ".", 74 | UseTrimTradesCount, 75 | TrimTradesCount, 76 | UseTrimQuantity, 77 | TrimQuantity, 78 | UseTrimAskQuantity, 79 | TrimAskQuantity, 80 | UseTrimBidQuantity, 81 | TrimBidQuantity, 82 | UseTrimDeltaAskBidQuantity, 83 | TrimDeltaAskBidQuantity, 84 | UseTrimRelativeDeltaAskBidQuantityPercent, 85 | TrimRelativeDeltaAskBidQuantityPercent, 86 | TrimComparisonMode); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /TradeStatisticsExtendedBarsSumHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using System.Linq; 4 | 5 | using TSLab.Script.Handlers.Options; 6 | 7 | namespace TSLab.Script.Handlers 8 | { 9 | // TODO: английское описание 10 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 11 | [HelperName("Trade Statistics Extended Strings Sum 1", Language = Constants.En)] 12 | [HelperName("Расширенная сумма строк торговой статистики 1", Language = Constants.Ru)] 13 | [InputsCount(1)] 14 | [Input(0, TemplateTypes.TRADE_STATISTICS | TemplateTypes.LAST_CONTRACTS_TRADE_STATISTICS)] 15 | [OutputsCount(1)] 16 | [OutputType(TemplateTypes.DOUBLE)] 17 | [Description("Блок 'Расширенная сумма строк торговой статистики 1' выдает значение, основанное на сумме значений строк торговой статистики.")] 18 | [HelperDescription("", Constants.En)] 19 | public sealed class TradeStatisticsExtendedBarsSumHandler : TradeStatisticsExtendedBarsHandler, ITradeStatisticsExtendedBarsSumHandler 20 | { 21 | /// 22 | /// \~english Kind of a trade statistics (trades count, trade volume, buy count, sell count, buy and sell difference, relative buy and sell difference). 23 | /// \~russian Вид торговой статистики (количество сделок, объем торгов, количество покупок, количество продаж, разница количества покупок и продаж, относительная разница количества покупок и продаж). 24 | /// 25 | [HelperName("Kind", Constants.En)] 26 | [HelperName("Вид", Constants.Ru)] 27 | [Description("Вид торговой статистики (количество сделок, объем торгов, количество покупок, количество продаж, разница количества покупок и продаж, относительная разница количества покупок и продаж).")] 28 | [HelperDescription("Kind of a trade statistics (trades count, trade volume, buy count, sell count, buy and sell difference, relative buy and sell difference).", Constants.En)] 29 | [HandlerParameter(true, nameof(TradeStatisticsKind.TradesCount))] 30 | public TradeStatisticsKind Kind { get; set; } 31 | 32 | protected override double GetResult(IBaseTradeStatisticsWithKind tradeStatistics, IEnumerable bars) 33 | { 34 | return bars.Sum(item => tradeStatistics.GetValue(item, Kind)); 35 | } 36 | 37 | protected override string GetParametersStateId() 38 | { 39 | return base.GetParametersStateId() + "." + Kind; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /TradeStatisticsExtendedBarsSumHandler2.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using System.Linq; 4 | 5 | using TSLab.Script.Handlers.Options; 6 | 7 | namespace TSLab.Script.Handlers 8 | { 9 | // TODO: английское описание 10 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 11 | [HelperName("Trade Statistics Extended Strings Sum 2", Language = Constants.En)] 12 | [HelperName("Расширенная сумма строк торговой статистики 2", Language = Constants.Ru)] 13 | [InputsCount(1)] 14 | [Input(0, TemplateTypes.TRADE_STATISTICS | TemplateTypes.LAST_CONTRACTS_TRADE_STATISTICS)] 15 | [OutputsCount(1)] 16 | [OutputType(TemplateTypes.DOUBLE)] 17 | [Description("Блок 'Расширенная сумма строк торговой статистики 2', выдает значение, основанное на сумме значений строк торговой статистики.")] 18 | [HelperDescription("", Constants.En)] 19 | public sealed class TradeStatisticsExtendedBarsSumHandler2 : TradeStatisticsExtendedBarsHandler2, ITradeStatisticsExtendedBarsSumHandler2 20 | { 21 | /// 22 | /// \~english Kind of a trade statistics (trades count, trade volume, buy count, sell count, buy and sell difference, relative buy and sell difference). 23 | /// \~russian Вид торговой статистики (количество сделок, объем торгов, количество покупок, количество продаж, разница количества покупок и продаж, относительная разница количества покупок и продаж). 24 | /// 25 | [HelperName("Kind", Constants.En)] 26 | [HelperName("Вид", Constants.Ru)] 27 | [Description("Вид торговой статистики (количество сделок, объем торгов, количество покупок, количество продаж, разница количества покупок и продаж, относительная разница количества покупок и продаж).")] 28 | [HelperDescription("Kind of a trade statistics (trades count, trade volume, buy count, sell count, buy and sell difference, relative buy and sell difference).", Constants.En)] 29 | [HandlerParameter(true, nameof(TradeStatisticsKind.TradesCount))] 30 | public TradeStatisticsKind Kind { get; set; } 31 | 32 | protected override double GetResult(IBaseTradeStatisticsWithKind tradeStatistics, IEnumerable bars) 33 | { 34 | return bars.Sum(item => tradeStatistics.GetValue(item, Kind)); 35 | } 36 | 37 | protected override string GetParametersStateId() 38 | { 39 | return base.GetParametersStateId() + "." + Kind; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /TradeStatisticsExtendedExtremumPriceHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using TSLab.Script.Handlers.Options; 4 | 5 | namespace TSLab.Script.Handlers 6 | { 7 | // TODO: английское описание 8 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 9 | [HelperName("Trade Statistics Extended Extremum Price 1", Language = Constants.En)] 10 | [HelperName("Расширенная экстремальная цена торговой статистики 1", Language = Constants.Ru)] 11 | [InputsCount(1)] 12 | [Input(0, TemplateTypes.TRADE_STATISTICS | TemplateTypes.LAST_CONTRACTS_TRADE_STATISTICS)] 13 | [OutputsCount(1)] 14 | [OutputType(TemplateTypes.DOUBLE)] 15 | [Description("Блок 'Расширенная экстремальная цена торговой статистики 1' показывает максимальное значение торговой статистики при экстремальной цене.")] 16 | [HelperDescription("", Constants.En)] 17 | public sealed class TradeStatisticsExtendedExtremumPriceHandler : TradeStatisticsBaseExtendedExtremumPriceHandler, ITradeStatisticsExtendedExtremumPriceHandler 18 | { 19 | [HandlerParameter(true, NotOptimized = true)] 20 | public bool UseTrimTradesCount { get; set; } 21 | 22 | [HandlerParameter(true, "0", Min = "0", Max = "2147483647", Step = "1", EditorMin = "0")] 23 | public int TrimTradesCount { get; set; } 24 | 25 | [HandlerParameter(true, NotOptimized = true)] 26 | public bool UseTrimQuantity { get; set; } 27 | 28 | [HandlerParameter(true, "0", Min = "0", Max = "999999999999999", Step = "1", EditorMin = "0")] 29 | public double TrimQuantity { get; set; } 30 | 31 | [HandlerParameter(true, NotOptimized = true)] 32 | public bool UseTrimAskQuantity { get; set; } 33 | 34 | [HandlerParameter(true, "0", Min = "0", Max = "999999999999999", Step = "1", EditorMin = "0")] 35 | public double TrimAskQuantity { get; set; } 36 | 37 | [HandlerParameter(true, NotOptimized = true)] 38 | public bool UseTrimBidQuantity { get; set; } 39 | 40 | [HandlerParameter(true, "0", Min = "0", Max = "999999999999999", Step = "1", EditorMin = "0")] 41 | public double TrimBidQuantity { get; set; } 42 | 43 | [HandlerParameter(true, NotOptimized = true)] 44 | public bool UseTrimDeltaAskBidQuantity { get; set; } 45 | 46 | [HandlerParameter(true, "0", Min = "-999999999999999", Max = "999999999999999", Step = "1")] 47 | public double TrimDeltaAskBidQuantity { get; set; } 48 | 49 | [HandlerParameter(true, "false", NotOptimized = true)] 50 | public bool UseTrimRelativeDeltaAskBidQuantityPercent { get; set; } 51 | 52 | [HandlerParameter(true, "0", Min = "-100", Max = "100", Step = "1")] 53 | public double TrimRelativeDeltaAskBidQuantityPercent { get; set; } 54 | 55 | [HandlerParameter(true, nameof(ComparisonMode.GreaterOrEqual))] 56 | public ComparisonMode TrimComparisonMode { get; set; } 57 | 58 | public override IList Execute(IBaseTradeStatisticsWithKind tradeStatistics) 59 | { 60 | return Execute( 61 | tradeStatistics, 62 | new TrimContext(UseTrimTradesCount, TrimTradesCount, TrimComparisonMode), 63 | new TrimContext(UseTrimQuantity, TrimQuantity, TrimComparisonMode), 64 | new TrimContext(UseTrimAskQuantity, TrimAskQuantity, TrimComparisonMode), 65 | new TrimContext(UseTrimBidQuantity, TrimBidQuantity, TrimComparisonMode), 66 | new TrimContext(UseTrimDeltaAskBidQuantity, TrimDeltaAskBidQuantity, TrimComparisonMode), 67 | new TrimContext(UseTrimRelativeDeltaAskBidQuantityPercent, TrimRelativeDeltaAskBidQuantityPercent, TrimComparisonMode)); 68 | } 69 | 70 | protected override string GetParametersStateId() 71 | { 72 | return string.Join( 73 | ".", 74 | base.GetParametersStateId(), 75 | UseTrimTradesCount, 76 | TrimTradesCount, 77 | UseTrimQuantity, 78 | TrimQuantity, 79 | UseTrimAskQuantity, 80 | TrimAskQuantity, 81 | UseTrimBidQuantity, 82 | TrimBidQuantity, 83 | UseTrimDeltaAskBidQuantity, 84 | TrimDeltaAskBidQuantity, 85 | UseTrimRelativeDeltaAskBidQuantityPercent, 86 | TrimRelativeDeltaAskBidQuantityPercent, 87 | TrimComparisonMode); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /TradeStatisticsLowerEdgeHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using System.Linq; 4 | 5 | using TSLab.Script.Handlers.Options; 6 | 7 | namespace TSLab.Script.Handlers 8 | { 9 | // TODO: английское описание 10 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 11 | [HelperName("Trade Statistics Lower Edge", Language = Constants.En)] 12 | [HelperName("Нижний уровень торговой статистики", Language = Constants.Ru)] 13 | [InputsCount(1)] 14 | [Input(0, TemplateTypes.TRADE_STATISTICS | TemplateTypes.LAST_CONTRACTS_TRADE_STATISTICS)] 15 | [OutputsCount(1)] 16 | [OutputType(TemplateTypes.DOUBLE)] 17 | [Description("Кубик 'Нижний уровень торговой статистики' позволяет установить в процентном значении отсечку данных по нижнему уровню. Данный блок соединяется с блоком 'Торговая статистика'.")] 18 | [HelperDescription("", Constants.En)] 19 | public sealed class TradeStatisticsLowerEdgeHandler : TradeStatisticsEdgeHandler 20 | { 21 | protected override double GetFirstPrice(IReadOnlyList bars) 22 | { 23 | return bars.First().MinPrice; 24 | } 25 | 26 | protected override double GetLastPrice(IReadOnlyList bars) 27 | { 28 | return bars.Last().MaxPrice; 29 | } 30 | 31 | protected override IEnumerable GetOrderedBars(IEnumerable bars) 32 | { 33 | return bars; 34 | } 35 | 36 | protected override double GetPrice(ITradeHistogramBar bar, double coefficient) 37 | { 38 | double result; 39 | if (coefficient < 0.5) 40 | result = bar.MinPrice + (bar.AveragePrice - bar.MinPrice) * coefficient * 2; 41 | else if (coefficient > 0.5) 42 | result = bar.AveragePrice + (bar.MaxPrice - bar.AveragePrice) * (coefficient - 0.5) * 2; 43 | else 44 | result = bar.AveragePrice; 45 | 46 | return result; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /TradeStatisticsUpperEdgeHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using System.Linq; 4 | 5 | using TSLab.Script.Handlers.Options; 6 | 7 | namespace TSLab.Script.Handlers 8 | { 9 | // TODO: английское описание 10 | [HandlerCategory(HandlerCategories.ClusterAnalysis)] 11 | [HelperName("Trade Statistics Upper Edge", Language = Constants.En)] 12 | [HelperName("Верхний уровень торговой статистики", Language = Constants.Ru)] 13 | [InputsCount(1)] 14 | [Input(0, TemplateTypes.TRADE_STATISTICS | TemplateTypes.LAST_CONTRACTS_TRADE_STATISTICS)] 15 | [OutputsCount(1)] 16 | [OutputType(TemplateTypes.DOUBLE)] 17 | [Description("Блок 'Верхний уровень торговой статистики' позволяет установить в процентном значении отсечки данных по верхнему уровню. Данный блок соединяется с блоком 'Торговая статистика'.")] 18 | [HelperDescription("", Constants.En)] 19 | public sealed class TradeStatisticsUpperEdgeHandler : TradeStatisticsEdgeHandler 20 | { 21 | protected override double GetFirstPrice(IReadOnlyList bars) 22 | { 23 | return bars.Last().MaxPrice; 24 | } 25 | 26 | protected override double GetLastPrice(IReadOnlyList bars) 27 | { 28 | return bars.First().MinPrice; 29 | } 30 | 31 | protected override IEnumerable GetOrderedBars(IEnumerable bars) 32 | { 33 | return bars.Reverse(); 34 | } 35 | 36 | protected override double GetPrice(ITradeHistogramBar bar, double coefficient) 37 | { 38 | double result; 39 | if (coefficient < 0.5) 40 | result = bar.MaxPrice + (bar.AveragePrice - bar.MaxPrice) * coefficient * 2; 41 | else if (coefficient > 0.5) 42 | result = bar.AveragePrice + (bar.MinPrice - bar.AveragePrice) * (coefficient - 0.5) * 2; 43 | else 44 | result = bar.AveragePrice; 45 | 46 | return result; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Trix.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | 5 | using TSLab.Script.Handlers.Options; 6 | using TSLab.Script.Helpers; 7 | 8 | // ReSharper disable InconsistentNaming 9 | namespace TSLab.Script.Handlers 10 | { 11 | [HandlerCategory(HandlerCategories.Indicators)] 12 | [HelperName("TRIX", Language = Constants.En)] 13 | [HelperName("TRIX", Language = Constants.Ru)] 14 | [InputsCount(1)] 15 | [Input(0, TemplateTypes.DOUBLE)] 16 | [OutputsCount(1)] 17 | [OutputType(TemplateTypes.DOUBLE)] 18 | [Description("Тройное экспоненциальное скользящее.")] 19 | [HelperDescription("The Triple Exponential Average.", Constants.En)] 20 | public sealed class TRIX : DoubleStreamAndValuesHandlerWithPeriod 21 | { 22 | private double m_lastEma3; 23 | private EMA m_ema1; 24 | private EMA m_ema2; 25 | private EMA m_ema3; 26 | 27 | public override bool IsGapTolerant 28 | { 29 | get { return IsSimple; } 30 | } 31 | 32 | public override IList Execute(IList source) 33 | { 34 | if (source == null) 35 | throw new ArgumentNullException(nameof(source)); 36 | 37 | IList ema3; 38 | if (IsSimple) 39 | ema3 = source; 40 | else 41 | { 42 | var ema1 = Series.EMA(source, Period, Context); 43 | var ema2 = Series.EMA(ema1, Period, Context); 44 | Context?.ReleaseArray((Array)ema1); 45 | ema3 = Series.EMA(ema2, Period, Context); 46 | Context?.ReleaseArray((Array)ema2); 47 | } 48 | var result = Context?.GetArray(source.Count) ?? new double[source.Count]; 49 | for (var i = 1; i < result.Length; i++) 50 | { 51 | var lastEma3 = ema3[i - 1]; 52 | result[i] = lastEma3 != 0 ? (ema3[i] - lastEma3) / lastEma3 : 0; 53 | } 54 | Context?.ReleaseArray((Array)ema3); 55 | return result; 56 | } 57 | 58 | protected override void InitExecuteContext() 59 | { 60 | m_lastEma3 = 0; 61 | if (IsSimple) 62 | return; 63 | 64 | m_ema1 = new EMA { Context = Context, Period = Period }; 65 | m_ema2 = new EMA { Context = Context, Period = Period }; 66 | m_ema3 = new EMA { Context = Context, Period = Period }; 67 | } 68 | 69 | protected override void ClearExecuteContext() 70 | { 71 | m_lastEma3 = 0; 72 | m_ema1 = null; 73 | m_ema2 = null; 74 | m_ema3 = null; 75 | } 76 | 77 | protected override void InitForGap() 78 | { 79 | if (IsSimple) 80 | m_lastEma3 = m_executeContext.GetSourceForGap(m_executeContext.Index - 1); 81 | else 82 | { 83 | var firstIndex = Math.Max(m_executeContext.LastIndex + 1, m_executeContext.Index - 4 * Period); 84 | for (var i = firstIndex; i < m_executeContext.Index; i++) 85 | { 86 | var source = m_executeContext.GetSourceForGap(i); 87 | var ema1 = m_ema1.Execute(source, i); 88 | var ema2 = m_ema2.Execute(ema1, i); 89 | var ema3 = m_ema3.Execute(ema2, i); 90 | m_lastEma3 = ema3; 91 | } 92 | } 93 | } 94 | 95 | protected override double Execute() 96 | { 97 | double ema3; 98 | if (IsSimple) 99 | ema3 = m_executeContext.Source; 100 | else 101 | { 102 | var ema1 = m_ema1.Execute(m_executeContext.Source, m_executeContext.Index); 103 | var ema2 = m_ema2.Execute(ema1, m_executeContext.Index); 104 | ema3 = m_ema3.Execute(ema2, m_executeContext.Index); 105 | } 106 | var result = m_lastEma3 != 0 ? (ema3 - m_lastEma3) / m_lastEma3 : 0; 107 | m_lastEma3 = ema3; 108 | return result; 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /ValueSupportedIndicator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace TSLab.Script.Handlers 5 | { 6 | [Obsolete] 7 | [InputsCount(1)] 8 | [Input(0, TemplateTypes.DOUBLE, Name = "ItemConnector.Src")] 9 | public abstract class ValueSupportedIndicator : IValuesHandlerWithNumber, IDoubleReturns, IContextUses 10 | { 11 | private double[] m_result, m_source; 12 | 13 | public double Execute(double source, int i) 14 | { 15 | if (i < 0 || i >= Context.BarsCount) 16 | throw new ArgumentOutOfRangeException(nameof(i)); 17 | 18 | if (m_result == null) 19 | { 20 | m_result = Context.GetArray(Context.BarsCount); 21 | m_source = Context.GetArray(Context.BarsCount); 22 | } 23 | m_source[i] = source; 24 | return Execute(m_source, m_result, i); 25 | } 26 | 27 | protected abstract double Execute(IList source, IList result, int num); 28 | 29 | public IContext Context { get; set; } 30 | } 31 | 32 | [Obsolete] 33 | public abstract class ValueSupportedIndicatorWithPeriod : ValueSupportedIndicator 34 | { 35 | private int m_period = 1; 36 | 37 | [HandlerParameter(true, "20", Min = "10", Max = "100", Step = "5", EditorMin = "1")] 38 | public int Period 39 | { 40 | get { return m_period; } 41 | set { m_period = Math.Max(value, 1); } 42 | } 43 | } 44 | 45 | [InputsCount(2)] 46 | [Input(0, TemplateTypes.DOUBLE)] 47 | [Input(1, TemplateTypes.DOUBLE)] 48 | public abstract class ValueSupportedComparer : IValuesHandlerWithNumber, IBooleanReturns, IContextUses 49 | { 50 | private bool[] m_data; 51 | private double[] m_source1, m_source2; 52 | 53 | public bool Execute(double source1, double source2, int i) 54 | { 55 | if (m_data == null) 56 | { 57 | m_data = Context.GetArray(Context.BarsCount); 58 | m_source1 = Context.GetArray(Context.BarsCount); 59 | m_source2 = Context.GetArray(Context.BarsCount); 60 | } 61 | m_source1[i] = source1; 62 | m_source2[i] = source2; 63 | return Execute(m_source1, m_source2, m_data, i); 64 | } 65 | 66 | protected abstract bool Execute(IList source1, IList source2, IList data, int num); 67 | 68 | public IContext Context { get; set; } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /VolumeForPeriodHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | using TSLab.Script.Handlers.Options; 5 | 6 | namespace TSLab.Script.Handlers 7 | { 8 | [HandlerCategory(HandlerCategories.VolumeAnalysis)] 9 | [HelperName("Volume for period", Language = Constants.En)] 10 | [HelperName("Объём за период", Language = Constants.Ru)] 11 | [InputsCount(1)] 12 | [Input(0, TemplateTypes.SECURITY, Name = Constants.SecuritySource)] 13 | [OutputsCount(1)] 14 | [OutputType(TemplateTypes.DOUBLE)] 15 | [Description("Объём за период (суммарный или средний)")] 16 | [HelperDescription("Volume for period (total or average)", Constants.En)] 17 | public sealed class VolumeForPeriodHandler : ValueForPeriodHandler 18 | { 19 | protected override double GetValue(ISecurity security, int barIndex) 20 | { 21 | return security.Bars[barIndex].Volume; 22 | } 23 | } 24 | } 25 | --------------------------------------------------------------------------------