예제 #1
0
 protected override void OnUpdate(MarketData mktData, DateTime updateTime, Price value)
 {
     if (!mktData.Levels.HasValue)
     {
         return;
     }
     Publish(updateTime, new Price(GetNearestLevel(value.Mid(), mktData.Levels.Value)));
 }
예제 #2
0
파일: ModelFXMole.cs 프로젝트: w1r2p1/MiDax
        protected override bool Sell(Signal signal, DateTime time, Price stockValue)
        {
            if (!_ptf.BookTrade(signal.Trade, signal.TradingAsset.Name))
            {
                Reset(time, stockValue.Mid(), true);
                return(false);
            }
            string tradeRef = signal.Trade == null ? "" : " " + signal.Trade.Reference;

            Log.Instance.WriteEntry(time + tradeRef + " Signal " + signal.Id + ": SELL " + signal.TradingAsset.Id + " " + stockValue.Bid + " spread: " + (stockValue.Offer - stockValue.Bid), EventLogEntryType.Information);
            return(true);
        }
예제 #3
0
파일: IndicatorWM.cs 프로젝트: w1r2p1/MiDax
        protected override Price IndicatorFunc(MarketData mktData, DateTime updateTime, Price value)
        {
            var curEma = 0m;

            if (_prevEma.HasValue)
            {
                var curPeriod = (decimal)(updateTime - _startTime).TotalMilliseconds;
                if (curPeriod > _periodMilliSeconds)
                {
                    curPeriod = _periodMilliSeconds;
                }
                var timeDecay = _timeDecayWeight * (decimal)(updateTime - _startTime).TotalSeconds;
                var k         = (curPeriod + timeDecay) / _periodMilliSeconds;
                curEma = value.Mid() * k + _prevEma.Value * (1m - k);
            }
            else
            {
                curEma = value.Mid();
            }
            _prevEma   = curEma;
            _startTime = updateTime;
            return(new Price(curEma));
        }
예제 #4
0
 protected virtual bool OnSell(Signal signal, DateTime time, Price stockValue)
 {
     if (FilterSignal(signal, time))
     {
         var pos = _ptf.GetPosition(signal.TradingAsset.Id);
         if (pos == null)
         {
             Reset(time, stockValue.Mid(), true);
             return(false);
         }
         if (pos.Quantity < 0)
         {
             Log.Instance.WriteEntry(time + " Signal " + signal.Id + ": Some trades are still open. last trade: " + signal.Trade.Id + " " + stockValue.Bid + ". Closing all positions...", EventLogEntryType.Error);
             _ptf.CloseAllPositions(time, signal.TradingAsset.Id, stockValue.Offer);
             return(false);
         }
         signal.Trade = new Trade(time, signal.TradingAsset.Id, SIGNAL_CODE.SELL, _amount, stockValue.Bid, 0);
         return(Sell(signal, time, stockValue));
     }
     return(false);
 }
예제 #5
0
        public Price CalcWMVol(MarketData mktData, DateTime updateTime, Price value)
        {
            Price avg      = base.IndicatorFunc(mktData, updateTime, value);
            var   curWMVol = 0m;

            if (_prevWMVol.HasValue)
            {
                var curPeriod = (decimal)(updateTime - _startVolTime).TotalMilliseconds;
                if (curPeriod > _periodMilliSeconds)
                {
                    curPeriod = _periodMilliSeconds;
                }
                var timeDecay = _timeDecayWeight * (decimal)(updateTime - _startTime).TotalSeconds;
                var k         = (curPeriod + timeDecay) / _periodMilliSeconds;
                curWMVol = Math.Abs(value.Mid() - _ema.TimeSeries.Last().Mid()) * k + _prevWMVol.Value * (1m - k);
            }
            else
            {
                curWMVol = 0m;
            }
            _prevWMVol    = curWMVol;
            _startVolTime = updateTime;
            return(new Price(curWMVol));
        }
예제 #6
0
        public bool Update(DateTime updateTime, Price value, Price rsi)
        {
            var curValue = value.Mid();

            if (StartValue == decimal.MinValue)
            {
                StartValue = curValue;
            }
            if (GlobalTrend == SIGNAL_CODE.BUY)
            {
                if (ReachedExtremum)
                {
                    if (curValue > LastValue)
                    {
                        PoolTrend = LastValue < StartValue ? SIGNAL_CODE.SELL : SIGNAL_CODE.BUY;
                        Depth     = LastValue < StartValue ? ExtremumValue - StartValue : ExtremumValue - LastValue;
                        return(true);
                    }
                }
                else
                {
                    if (curValue > ExtremumValue)
                    {
                        ExtremumValue = curValue;
                        ExtremumTime  = updateTime;
                    }
                    else if (curValue < ExtremumValue)
                    {
                        ReachedExtremum = true;
                    }
                }
            }
            else
            {
                if (ReachedExtremum)
                {
                    if (curValue < LastValue)
                    {
                        PoolTrend = LastValue < StartValue ? SIGNAL_CODE.SELL : SIGNAL_CODE.BUY;
                        Depth     = LastValue < StartValue ? LastValue - ExtremumValue : StartValue - ExtremumValue;
                        return(true);
                    }
                }
                else
                {
                    if (curValue < ExtremumValue)
                    {
                        ExtremumValue = curValue;
                        ExtremumTime  = updateTime;
                    }
                    else if (curValue > ExtremumValue)
                    {
                        ReachedExtremum = true;
                    }
                }
            }
            LastTime  = updateTime;
            LastValue = curValue;
            LastRsi   = rsi.Bid;
            return(false);
        }
예제 #7
0
파일: Signal.cs 프로젝트: JBetser/MiDax
 public static int comparison(Price p1, Price p2)
 {
     // precision is set to 1/10000 of bp
     return (int)(10000m * (p1.Mid() - p2.Mid()));
 }
예제 #8
0
        protected override bool Process(MarketData indicator, DateTime updateTime, Price value, ref Signal.Tick tradingOrder)
        {
            if (_calendar == null)
            {
                _calendar = new Calendar(updateTime);
            }
            IndicatorRSI rsi = (IndicatorRSI)indicator;

            if (indicator.TimeSeries.TotalMinutes(updateTime) < _timeFrameMn)
            {
                return(false);
            }
            if (!_startValue.HasValue)
            {
                _startValue = value.Mid();
            }
            Price curRsi  = rsi.TimeSeries.Last();
            Price prevRsi = rsi.TimeSeries.PrevValue(updateTime).Value.Value;

            if ((prevRsi.Bid <= 50m && curRsi.Bid >= 50m) || (curRsi.Bid <= 50m && prevRsi.Bid >= 50m))
            {
                _rsi_loss_reset = true;
            }
            //_rsiSellThreshold += Math.Max(0m, curRsi.Bid - (decimal)getSellThreshold()) / 2m;
            //_rsiBuyThreshold += Math.Min(0m, curRsi.Bid - (decimal)getBuyThreshold()) / 2m;
            var minVal = _asset.TimeSeries.Min(updateTime.AddMinutes(-_timeFrameStopLossMn), updateTime);
            var maxVal = _asset.TimeSeries.Max(updateTime.AddMinutes(-_timeFrameStopLossMn), updateTime);

            if (maxVal - minVal > _maxVol)
            {
                //WriteBlockReason(updateTime, string.Format("reset due to vol > {0}", _maxVol));
                _rsi_loss_reset = false;
            }
            minVal = _asset.TimeSeries.Min(updateTime.AddMinutes(-_timeFrameBottomMn), updateTime);
            maxVal = _asset.TimeSeries.Max(updateTime.AddMinutes(-_timeFrameBottomMn), updateTime);
            if (maxVal - minVal > _maxLongVol)
            {
                //WriteBlockReason(updateTime, string.Format("reset due to long vol > {0}", _maxLongVol));
                _rsi_loss_reset = false;
            }
            if (Math.Abs(value.Mid() - _startValue.Value) > _maxTotalVol)
            {
                WriteBlockReason(updateTime, string.Format("stopped trading due to vol > {0}", _maxTotalVol));
                _stopTrading = true;
            }
            if (_tradingStart > DateTime.MinValue)
            {
                if ((decimal)(updateTime - _tradingStart).TotalMilliseconds > _timeFrameStopLossMn * 60000m)
                {
                    _rsi_loss_reset = false;
                    return(close(_id + string.Format(" close event due to timeout, AssetStart = {0}, Value = {1}", _tradingStartValue, value.Bid), ref tradingOrder));
                }
                else
                {
                    int     idxStopLoss = -1;
                    decimal ratio       = 0m;
                    foreach (var interval in stopLossTimes)
                    {
                        idxStopLoss++;
                        if (interval.IsInside((int)(updateTime - _tradingStart).TotalMinutes))
                        {
                            ratio = interval.Ratio((decimal)(updateTime - _tradingStart).TotalMinutes);
                            break;
                        }
                    }
                    if (_signalCode == SIGNAL_CODE.BUY)
                    {
                        var assetMin    = rsi.MinAsset((int)(updateTime - _tradingStart).TotalMinutes + 1);
                        var stopWin     = stopWinValues[idxStopLoss].Value(ratio);
                        var stopBigLoss = bigStopLossValues[idxStopLoss].Value(ratio);
                        if (value.Bid >= _tradingStartValue + stopWin && curRsi.Bid >= getBuyThreshold() + 10)
                        {
                            return(close(_id + string.Format(" close event due to stop win. SELL AssetStart = {0}, LastValue = {1}, StopWin = {2}", _tradingStartValue, value.Bid, stopWin), ref tradingOrder));
                        }
                        else if (value.Bid - assetMin >= stopWin && curRsi.Bid >= getBuyThreshold() + 10)
                        {
                            if (value.Bid > _tradingStartValue)
                            {
                                return(close(_id + string.Format(" close event due to stop win. SELL AssetStart = {0}, LastValue = {1}", _tradingStartValue, value.Bid), ref tradingOrder));
                            }
                            else
                            {
                                _rsi_loss_reset = false;
                                return(close(_id + string.Format(" close event due to stop loss. SELL AssetStart = {0}, LastValue = {1}", _tradingStartValue, value.Bid), ref tradingOrder));
                            }
                        }
                        else if (value.Bid - _tradingStartValue >= stopBigLoss)
                        {
                            _rsi_loss_reset = false;
                            return(close(_id + string.Format(" close event due to stop loss. SELL AssetMin = {0}, LastValue = {1}, StopLoss = {2}", assetMin, value.Bid, stopBigLoss), ref tradingOrder));
                        }/*
                          * else if (_trend.TimeSeries.Last().Bid <= _tradingTrend - 5m && curRsi.Bid >= getBuyThreshold() + 10)
                          * {
                          * if (value.Offer > _tradingStartValue)
                          *     return close(_id + string.Format(" close event due to stop win forced by trend. SELL AssetStart = {0}, LastValue = {1}", _tradingStartValue, value.Offer), ref tradingOrder);
                          * else
                          * {
                          *     _rsi_loss_reset = false;
                          *     return close(_id + string.Format(" close event due to stop loss forced by trend. SELL AssetStart = {0}, LastValue = {1}", _tradingStartValue, value.Offer), ref tradingOrder);
                          * }
                          * }*/
                        else
                        {
                            var stopLoss    = stopLossValues[idxStopLoss].Value(ratio);
                            var bigStopLoss = bigStopLossValues[idxStopLoss].Value(ratio);
                            if ((_tradingStartValue - value.Bid >= stopLoss && curRsi.Bid >= getBuyThreshold() + 20) ||
                                (_tradingStartValue - value.Bid >= bigStopLoss))
                            {
                                _rsi_loss_reset = false;
                                return(close(_id + string.Format(" close event due to stop loss. SELL AssetStart = {0}, LastValue = {1}, StopLoss = {2}", _tradingStartValue, value.Bid, stopLoss), ref tradingOrder));
                            }
                        }
                    }
                    else
                    {
                        var assetMax    = rsi.MaxAsset((int)(updateTime - _tradingStart).TotalMinutes + 1);
                        var stopWin     = stopWinValues[idxStopLoss].Value(ratio);
                        var stopBigLoss = bigStopLossValues[idxStopLoss].Value(ratio);
                        if (value.Offer <= _tradingStartValue - stopWin && curRsi.Bid <= getSellThreshold() - 10)
                        {
                            return(close(_id + string.Format(" close event due to stop win. BUY AssetStart = {0}, LastValue = {1}, StopWin = {2}", _tradingStartValue, value.Offer, stopWin), ref tradingOrder));
                        }
                        else if (assetMax - value.Offer >= stopWin && curRsi.Bid <= getSellThreshold() - 10)
                        {
                            if (value.Offer < _tradingStartValue)
                            {
                                return(close(_id + string.Format(" close event due to stop win. BUY AssetStart = {0}, LastValue = {1}", _tradingStartValue, value.Offer), ref tradingOrder));
                            }
                            else
                            {
                                _rsi_loss_reset = false;
                                return(close(_id + string.Format(" close event due to stop loss. BUY AssetStart = {0}, LastValue = {1}", _tradingStartValue, value.Offer), ref tradingOrder));
                            }
                        }
                        else if (assetMax - value.Offer >= stopBigLoss)
                        {
                            _rsi_loss_reset = false;
                            return(close(_id + string.Format(" close event due to stop loss. BUY AssetMax = {0}, LastValue = {1}, StopLoss = {2}", assetMax, value.Offer, stopBigLoss), ref tradingOrder));
                        }/*
                          * else if (_trend.TimeSeries.Last().Bid >= _tradingTrend + 5m && curRsi.Bid <= getSellThreshold() - 10)
                          * {
                          * if (value.Offer < _tradingStartValue)
                          *     return close(_id + string.Format(" close event due to stop win forced by trend. BUY AssetStart = {0}, LastValue = {1}", _tradingStartValue, value.Offer), ref tradingOrder);
                          * else
                          * {
                          *     _rsi_loss_reset = false;
                          *     return close(_id + string.Format(" close event due to stop loss forced by trend. BUY AssetStart = {0}, LastValue = {1}", _tradingStartValue, value.Offer), ref tradingOrder);
                          * }
                          * }*/
                        else
                        {
                            var stopLoss    = stopLossValues[idxStopLoss].Value(ratio);
                            var bigStopLoss = bigStopLossValues[idxStopLoss].Value(ratio);
                            if ((value.Offer - _tradingStartValue >= stopLoss && curRsi.Bid <= getSellThreshold() - 20) ||
                                (value.Offer - _tradingStartValue >= bigStopLoss))
                            {
                                _rsi_loss_reset = false;
                                return(close(_id + string.Format(" close event due to stop loss. BUY AssetStart = {0}, LastValue = {1}, StopLoss = {2}", _tradingStartValue, value.Offer, stopLoss), ref tradingOrder));
                            }
                        }
                    }
                }
            }
            else
            {
                if (!_rsi_loss_reset || _stopTrading || maxVal - minVal < _minVol || value.Offer - value.Bid > _maxSpread)
                {
                    return(false);
                }

                /*
                 * foreach (var rsiRef in _rsiRefs)
                 * {
                 *  if (rsiRef.TimeSeries.Count > 0)
                 *  {
                 *      if (Math.Abs(curRsi.Mid() - 50m) < Math.Abs(rsiRef.TimeSeries.Last().Mid() - 50m))
                 *          return false;
                 *  }
                 * }*/
                string eventName = "";
                if (_calendar.IsNearEvent(_asset.Name, updateTime, ref eventName))
                {
                    WriteBlockReason(updateTime, "deal blocked by event: " + eventName);
                    _rsi_loss_reset = false;
                    return(false);
                }
                var rsiMax = rsi.MaxRsi(_timeFramePeakMn);
                var rsiMin = rsi.MinRsi(_timeFramePeakMn);
                //var rsiLongMax = _rsiLong.MaxRsi(_timeFrameRsiLongMn);
                //var rsiLongMin = _rsiLong.MinRsi(_timeFrameRsiLongMn);
                var rsiAdjustment   = Math.Max(0, rsi.MaxRsi(_timeFrameBottomMn) - getSellThreshold()) - Math.Max(0, getBuyThreshold() - rsi.MinRsi(_timeFrameBottomMn));
                var curEmaVeryShort = _emaVeryShort.TimeSeries.Last();
                var curEmaShort     = _emaShort.TimeSeries.Last();
                var curEmaLong      = _emaLong.TimeSeries.Last();
                var curVol          = _wmvol.TimeSeries.Last().Bid;
                if (curVol < _maxWmVol)
                {
                    WriteBlockReason(updateTime, "deal blocked due to vol < " + _maxWmVol);
                    return(false);
                }
                var curVolAvg = (_wmvol.Min() + _wmvol.Max()) / 2m;
                if (curVol < curVolAvg)
                {
                    WriteBlockReason(updateTime, "deal blocked due to vol < vol average");
                    return(false);
                }
                if ((curRsi.Bid >= getSellThreshold()) &&
                    //(curRsi.Bid - rsiAdjustment >= getSellThreshold() && curRsi.Bid >= (getSellThreshold() - 10))) && (rsiLongMax >= getSellThreshold() - 15m) &&
                    (curRsi.Bid > rsiMax - _startThreshold) && (curEmaVeryShort.Mid() + _maxShortMacDSpread > curEmaLong.Mid()) &&
                    (Math.Abs(curEmaShort.Mid() - curEmaLong.Mid()) < _maxLongMacDSpread))
                {
                    var curVolTrend = _volTrend.TimeSeries.Last().Bid;
                    if (curVolTrend > 0.5m || curVolTrend < 0m)
                    {
                        WriteBlockReason(updateTime, "deal blocked due to vol not within 0 < trend < 0.5");
                        return(false);
                    }
                    if (!_volTrendTrend.IsMin(2, curVolTrend, 0.01m) || _volTrendTrend.IsMax(2, curVolTrend, 0.02m))
                    {
                        WriteBlockReason(updateTime, "sell event blocked due to vol trend not 1mn minimum");
                        return(false);
                    }
                    tradingOrder       = _onSell;
                    _signalCode        = SIGNAL_CODE.SELL;
                    _tradingStart      = updateTime;
                    _tradingStartValue = value.Bid;
                    _tradingTrend      = _trend.TimeSeries.Last().Bid;
                    if (curRsi.Bid >= getSellThreshold())
                    {
                        Log.Instance.WriteEntry(_id + " sell event due to RSI >= getSellThreshold()");
                    }
                    //                    else if (Math.Abs(curRsi.Bid - rsiMax) < _startThreshold)
                    //                      Log.Instance.WriteEntry(_id + " sell event due highest RSI peak reached");
                    else
                    {
                        Log.Instance.WriteEntry(_id + " sell event due to adjusted RSI >= getSellThreshold()");
                    }
                    return(true);
                }
                else if ((curRsi.Bid <= getBuyThreshold()) &&
                         //(curRsi.Bid + rsiAdjustment <= getBuyThreshold() && curRsi.Bid <= (getBuyThreshold() + 10))) && (rsiLongMin <= getBuyThreshold() + 15m) &&
                         (curRsi.Bid < rsiMin + _startThreshold) && (curEmaVeryShort.Mid() - _maxShortMacDSpread < curEmaLong.Mid()) &&
                         (Math.Abs(curEmaShort.Mid() - curEmaLong.Mid()) < _maxLongMacDSpread))
                {
                    var curVolTrend = _volTrend.TimeSeries.Last().Bid;
                    if (curVolTrend < -0.5m || curVolTrend > 0m)
                    {
                        WriteBlockReason(updateTime, "deal blocked due to vol not within -0.5 < trend < 0");
                        return(false);
                    }
                    if (!_volTrendTrend.IsMax(2, curVolTrend, 0.01m) || _volTrendTrend.IsMin(2, curVolTrend, 0.02m))
                    {
                        WriteBlockReason(updateTime, "buy event blocked due to vol trend not 1mn maximum");
                        return(false);
                    }
                    tradingOrder       = _onBuy;
                    _signalCode        = SIGNAL_CODE.BUY;
                    _tradingStart      = updateTime;
                    _tradingStartValue = value.Offer;
                    _tradingTrend      = _trend.TimeSeries.Last().Bid;
                    if (curRsi.Bid <= getBuyThreshold())
                    {
                        Log.Instance.WriteEntry(_id + " buy event due to RSI <= getBuyThreshold()");
                    }
                    //                   else if (Math.Abs(curRsi.Bid - rsiMin) < _startThreshold)
                    //                     Log.Instance.WriteEntry(_id + " buy event due lowest RSI peak reached");
                    else
                    {
                        Log.Instance.WriteEntry(_id + " buy event due to adjusted RSI <= getBuyThreshold()");
                    }
                    return(true);
                }
                else
                {
                    _signalCode        = SIGNAL_CODE.HOLD;
                    _tradingStart      = DateTime.MinValue;
                    _tradingStartValue = 0m;
                }
            }
            return(false);
        }
예제 #9
0
        public Price CalcCurve(MarketData mktData, DateTime updateTime)
        {
            /*
             * var topValues = new List<KeyValuePair<decimal, decimal>>();
             * var bottomValues = new List<KeyValuePair<decimal, decimal>>();
             * var timeOrig = updateTime.AddSeconds(_periodSec * _nbCandles);
             * foreach (var candle in _trend.Candles)
             * {
             *  topValues.Add(new KeyValuePair<decimal, decimal>((decimal)(candle.EndTime - timeOrig).TotalSeconds, candle.Max));
             *  bottomValues.Add(new KeyValuePair<decimal, decimal>((decimal)(candle.StartTime - timeOrig).TotalSeconds, candle.Min));
             * }
             * var topCurve = curvature(topValues[0].Key, topValues[0].Value, topValues[1].Key, topValues[1].Value, topValues[2].Key, topValues[2].Value);
             * var bottomCurve = curvature(topValues[0].Key, topValues[0].Value, topValues[1].Key, topValues[1].Value, topValues[2].Key, topValues[2].Value);
             *
             * return new Price((topCurve + bottomCurve) / 2m);*/

            if (updateTime >= _nextCurveTime)
            {
                if (mktData.TimeSeries.Count < 2)
                {
                    return(null);
                }
                if (_nextCurveTime == DateTime.MinValue)
                {
                    _nextCurveTime = updateTime.AddSeconds(_subPeriodSeconds);
                }
                else
                {
                    _nextCurveTime = _nextCurveTime.AddSeconds(_subPeriodSeconds);
                }
                DateTime rsiTime = _nextCurveTime.AddSeconds(-_subPeriodSeconds);
                if (mktData.TimeSeries.StartTime() > rsiTime)
                {
                    return(null);
                }
                if (_curvCandles.Count == _nbCandles)
                {
                    _curvCandles.RemoveAt(0);
                }
                if (_curvCandles.Count > 0)
                {
                    _curCandle.EndTime = updateTime;
                    _curCandle         = new CurvCandle(mktData.TimeSeries.Last().Mid());
                }
                else
                {
                    _curCandle = new CurvCandle(mktData.TimeSeries.Last().Mid());
                }
                _curvCandles.Add(_curCandle);
            }
            else
            {
                _curCandle = _curvCandles.Last();
            }
            DateTime startTime = _nextCurveTime.AddSeconds(-_subPeriodSeconds);

            if (mktData.TimeSeries.StartTime() > startTime)
            {
                return(null);
            }
            var prevValStart = mktData.TimeSeries.PrevValue(startTime);

            if (!prevValStart.HasValue)
            {
                return(null);
            }
            Price valStart    = prevValStart.Value.Value;
            Price valEnd      = mktData.TimeSeries.Last();
            Price valRsiStart = prevValStart.Value.Value;
            Price valRsiEnd   = mktData.TimeSeries.Last();

            if (valEnd > valStart)
            {
                _curCandle.GainAsset = true;
                _curCandle.DiffAsset = valEnd.Mid() - valStart.Mid();
            }
            else
            {
                _curCandle.GainAsset = false;
                _curCandle.DiffAsset = valStart.Mid() - valEnd.Mid();
            }
            var sumGain   = 0m;
            var sumLosses = 0m;
            var nbGain    = 0;
            var nbLoss    = 0;

            foreach (var candle in _curvCandles)
            {
                if (candle.GainAsset)
                {
                    sumGain += candle.DiffAsset;
                    nbGain++;
                }
                else
                {
                    sumLosses += candle.DiffAsset;
                    nbLoss++;
                }
            }
            var avgGain    = nbGain == 0 ? 0 : sumGain / nbGain;
            var avgLoss    = nbLoss == 0 ? 0 : sumLosses / nbLoss;
            var stdDevGain = 0m;
            var stdDevLoss = 0m;

            foreach (var candle in _curvCandles)
            {
                if (candle.GainAsset)
                {
                    stdDevGain += (decimal)Math.Pow((double)(candle.DiffAsset - avgGain), 2.0);
                }
                else
                {
                    stdDevLoss += (decimal)Math.Pow((double)(candle.DiffAsset - avgLoss), 2.0);
                }
            }
            _curCandle.StdDevGain = nbGain == 0 ? 0m : (decimal)Math.Sqrt((double)stdDevGain / nbGain);
            _curCandle.StdDevLoss = nbLoss == 0 ? 0m : (decimal)Math.Sqrt((double)stdDevLoss / nbLoss);

            decimal curv = Math.Abs(sumLosses) < 0.1m ? (Math.Abs(sumGain) < 0.1m ? 1m : 1000m) : sumGain / sumLosses;

            if (curv > 1m)
            {
                curv = 1m / curv;
            }
            return(new Price(100m * curv));
        }
예제 #10
0
파일: Model.cs 프로젝트: JBetser/MiDax
 protected virtual bool OnSell(Signal signal, DateTime time, Price stockValue)
 {
     if (_tradingSignals != null)
     {
         if (_tradingSignals.Contains(signal.Id))
         {
             var pos = _ptf.GetPosition(signal.TradingAsset.Id);
             if (pos == null)
             {
                 Reset(time, stockValue.Mid(), true);
                 return false;
             }
             if (pos.Quantity < 0)
             {
                 Log.Instance.WriteEntry(time + " Signal " + signal.Id + ": Some trades are still open. last trade: " + signal.Trade.Id + " " + stockValue.Bid + ". Closing all positions...", EventLogEntryType.Error);
                 Portfolio.Instance.CloseAllPositions(time, signal.TradingAsset.Id, stockValue.Offer, signal);
                 return false;
             }
             signal.Trade = new Trade(time, signal.TradingAsset.Id, SIGNAL_CODE.SELL, _amount, stockValue.Bid, 0, Reset);
             return Sell(signal, time, stockValue);
         }
     }
     return false;
 }
예제 #11
0
        public Price CalcRSI(MarketData mktData, DateTime updateTime)
        {
            if (updateTime >= _nextRsiTime)
            {
                if (mktData.TimeSeries.Count < 2)
                {
                    return(null);
                }
                if (_nextRsiTime == DateTime.MinValue)
                {
                    _nextRsiTime = updateTime.AddSeconds(_subPeriodSeconds);
                }
                else
                {
                    _nextRsiTime = _nextRsiTime.AddSeconds(_subPeriodSeconds);
                }
                DateTime rsiTime = _nextRsiTime.AddSeconds(-_subPeriodSeconds);
                if (mktData.TimeSeries.StartTime() > rsiTime)
                {
                    return(null);
                }
                if (_rsiCandles.Count == _nbPeriods)
                {
                    _rsiCandles.RemoveAt(0);
                }
                if (_history.Count == 120)
                {
                    _history.RemoveAt(0);
                }
                if (_rsiCandles.Count > 0)
                {
                    _curCandle.EndTime = updateTime;
                    var curStartRsi = _rsiCandles[_rsiCandles.Count - 1].StartRsiValue + (_rsiCandles[_rsiCandles.Count - 1].GainRsi ? _rsiCandles[_rsiCandles.Count - 1].DiffRsi:
                                                                                          -_rsiCandles[_rsiCandles.Count - 1].DiffRsi);
                    _curCandle = new RsiCandle(curStartRsi, mktData.TimeSeries.Last().Mid());
                }
                else
                {
                    _curCandle = new RsiCandle(50m, mktData.TimeSeries.Last().Mid());
                }
                _rsiCandles.Add(_curCandle);
                _history.Add(_curCandle);
            }
            else
            {
                _curCandle = _rsiCandles.Last();
            }
            DateTime startTime = _nextRsiTime.AddSeconds(-_subPeriodSeconds);

            if (mktData.TimeSeries.StartTime() > startTime)
            {
                return(null);
            }
            var prevValStart = mktData.TimeSeries.PrevValue(startTime);

            if (!prevValStart.HasValue)
            {
                return(null);
            }
            Price valStart    = prevValStart.Value.Value;
            Price valEnd      = mktData.TimeSeries.Last();
            Price valRsiStart = prevValStart.Value.Value;
            Price valRsiEnd   = mktData.TimeSeries.Last();

            if (valEnd > valStart)
            {
                _curCandle.GainAsset = true;
                _curCandle.DiffAsset = valEnd.Mid() - valStart.Mid();
            }
            else
            {
                _curCandle.GainAsset = false;
                _curCandle.DiffAsset = valStart.Mid() - valEnd.Mid();
            }
            var sumGain   = 0m;
            var sumLosses = 0m;
            var nbGain    = 0;
            var nbLoss    = 0;

            foreach (var candle in _rsiCandles)
            {
                if (candle.GainAsset)
                {
                    sumGain += candle.DiffAsset;
                    nbGain++;
                }
                else
                {
                    sumLosses += candle.DiffAsset;
                    nbLoss++;
                }
            }
            var avgGain    = nbGain == 0 ? 0 : sumGain / nbGain;
            var avgLoss    = nbLoss == 0 ? 0 : sumLosses / nbLoss;
            var stdDevGain = 0m;
            var stdDevLoss = 0m;

            foreach (var candle in _rsiCandles)
            {
                if (candle.GainAsset)
                {
                    stdDevGain += (decimal)Math.Pow((double)(candle.DiffAsset - avgGain), 2.0);
                }
                else
                {
                    stdDevLoss += (decimal)Math.Pow((double)(candle.DiffAsset - avgLoss), 2.0);
                }
            }
            _curCandle.StdDevGain = nbGain == 0 ? 0m : (decimal)Math.Sqrt((double)stdDevGain / nbGain);
            _curCandle.StdDevLoss = nbLoss == 0 ? 0m : (decimal)Math.Sqrt((double)stdDevLoss / nbLoss);
            decimal rs  = Math.Abs(sumLosses) < 0.1m ? (Math.Abs(sumGain) < 0.1m ? 1m : 1000m) : sumGain / sumLosses;
            Price   rsi = new Price(100m - 100m / (1m + rs));

            if (rsi.Bid > _curCandle.StartRsiValue)
            {
                _curCandle.GainRsi = true;
                _curCandle.DiffRsi = rsi.Bid - _curCandle.StartRsiValue;
            }
            else
            {
                _curCandle.GainRsi = false;
                _curCandle.DiffRsi = _curCandle.StartRsiValue - rsi.Bid;
            }
            return(rsi);
        }
예제 #12
0
 protected override void OnUpdate(MarketData mktData, DateTime updateTime, Price value)
 {
     if (!mktData.Levels.HasValue)
         return;
     Publish(updateTime, new Price(GetNearestLevel(value.Mid(), mktData.Levels.Value)));
 }
예제 #13
0
 public static int comparison(Price p1, Price p2)
 {
     // precision is set to 1/10000 of bp
     return((int)(10000m * (p1.Mid() - p2.Mid())));
 }