如何解决无法将 Frame<int, string> 转换为 List<OHLCV>,因此我可以计算指标并定位其结果 完全可测试的代码编辑
我正在尝试使用 deedle 在 C# 中重新创建使用 Pandas (this one) 的 Python 代码。基本上,我正在为两件事而苦苦挣扎。
- 我想在计算指标时使用
Rsi(this IReadOnlyList<OHLCV> source...
重载。现在我正在使用List<decimal>
。 - 如何将
loc
转换为 C#?
dataframe.loc[
(
qtpylib.crossed_above(dataframe['ema20'],dataframe['ema50']) &
(dataframe['ha_close'] > dataframe['ema20']) &
(dataframe['ha_open'] < dataframe['ha_close']) # green bar
),'buy'] = 1
在我下面的示例中,被质疑的方法称为 PopulateIndicators
。我想用上面提到的 foreach
之类的东西替换 loc
循环,并使代码看起来更像 python 代码(例如,将其拆分为三个方法等)。
完全可测试的代码
using Binance.Net;
using Binance.Net.Enums;
using deedle;
using System;
using System.Collections.Generic;
using System.Linq;
namespace deedleFrameTests
{
public class OHLCV
{
public DateTime Timestamp { get; set; }
public decimal Open { get; set; }
public decimal High { get; set; }
public decimal Low { get; set; }
public decimal Close { get; set; }
public decimal Volume { get; set; }
}
public static partial class IndicatorExtensions
{
private static IReadOnlyList<decimal?> FixIndicatorOrdering(IReadOnlyList<decimal> source,int outBegIdx,int outNbElement)
{
var outValues = new List<decimal?>();
var validItems = source.Take(outNbElement);
for (int i = 0; i < outBegIdx; i++)
outValues.Add(null);
foreach (var value in validItems)
outValues.Add(value);
return outValues;
}
public static IReadOnlyList<decimal?> Rsi(this IReadOnlyList<OHLCV> source,int period = 14)
{
var rsiValues = new decimal[source.Count];
var closes = source.Select(e => e.Close).ToArray();
var result = TALib.Core.Rsi(closes,source.Count - 1,rsiValues,out int outBegIdx,out int outNbElement,period);
if (result == TALib.Core.RetCode.Success)
{
return FixIndicatorOrdering(rsiValues.ToList(),outBegIdx,outNbElement);
}
throw new Exception("Could not calculate RSI.");
}
public static IReadOnlyList<decimal?> Rsi(this List<decimal> source,int period = 14)
{
var rsiValues = new decimal[source.Count];
var result = TALib.Core.Rsi(source.ToArray(),outNbElement);
}
throw new Exception("Could not calculate RSI.");
}
}
public class TestStrategy
{
public enum TradeAdvice
{
Buy,Sell,Hold
}
public List<TradeAdvice> PopulateIndicatorsNodeedle(List<OHLCV> candles)
{
var result = new List<TradeAdvice>();
var rsiPeriod = 2;
var rsi = candles.Rsi(rsiPeriod);
for (int i = 0; i < candles.Count; i++)
{
if (rsi[i] < 45 && rsi[i] > rsi[i - 1])
result.Add(TradeAdvice.Buy);
else if (rsi[i] > 70)
result.Add(TradeAdvice.Sell);
else
result.Add(TradeAdvice.Hold);
}
return result;
}
public List<TradeAdvice> PopulateIndicators(Frame<int,string> frame)
{
var closes = frame.GetColumn<decimal>("Close").Values.ToList();
var indicator = closes.Rsi(2);
frame.AddColumn("rsi",indicator);
var rsi = frame.GetColumn<decimal>("rsi").Realign(Enumerable.Range(0,closes.Count)).FillMissing(0m);
var rsiShifted = frame.GetColumn<decimal>("rsi").Shift(1).Realign(Enumerable.Range(0,closes.Count)).FillMissing(0m);
var result = new List<TradeAdvice>();
for (int i = 0; i < closes.Count; i++)
{
if (rsi[i] < 45 && rsi[i] > rsiShifted[i])
result.Add(TradeAdvice.Buy);
else if (rsi[i] > 70)
result.Add(TradeAdvice.Sell);
else
result.Add(TradeAdvice.Hold);
}
return result;
}
}
public class Program
{
public static void Main(string[] args)
{
var candles = new BinanceClient().Spot.Market.GetKlines("TRXUSDT",KlineInterval.OneMinute).Data?
.Select(x => new OHLCV
{
Timestamp = x.OpenTime,Open = x.Open,High = x.High,Close = x.Close,Low = x.Low,Volume = x.BaseVolume
}).ToList();
var frame = Frame.Fromrecords(candles);
var strategy = new TestStrategy();
var advices = strategy.PopulateIndicatorsNodeedle(candles);
var advices2 = strategy.PopulateIndicators(frame);
var areEqual = Enumerable.SequenceEqual(advices,advices2);
Console.ReadLine();
}
}
}
编辑
我只解决了问题的第一部分(closes
从 List<decimal>
到 List<OHLCV>
)。这个问题帮助了我Convert a Deedle Dataframe into a C# List of Custom Class。
剩下的问题仍未解决。
public List<TradeAdvice> PopulateIndicators(Frame<int,string> df)
{
var closes = df.Rows.Select(row =>
new OHLCV
{
Timestamp = row.Value.GetAs<DateTime>("Timestamp"),Open = row.Value.GetAs<decimal>("Open"),High = row.Value.GetAs<decimal>("High"),Low = row.Value.GetAs<decimal>("Low"),Close = row.Value.GetAs<decimal>("Close"),Volume = row.Value.GetAs<decimal>("Volume")
}).Observations.Select(e => e.Value).ToList();
//var closes = df.GetColumn<decimal>("Close").Values.ToList();
var indicator = closes.Rsi(2);
df.AddColumn("rsi",indicator);
var rsi = df.GetColumn<decimal>("rsi").Realign(Enumerable.Range(0,closes.Count)).FillMissing(0m);
var rsiShifted = df.GetColumn<decimal>("rsi").Shift(1).Realign(Enumerable.Range(0,closes.Count)).FillMissing(0m);
var result = new List<TradeAdvice>();
for (int i = 0; i < closes.Count; i++)
{
if (rsi[i] < 45 && rsi[i] > rsiShifted[i])
result.Add(TradeAdvice.Buy);
else if (rsi[i] > 70)
result.Add(TradeAdvice.Sell);
else
result.Add(TradeAdvice.Hold);
}
return result;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。