从方法中仅向用户公开重要逻辑
Exposing only important logic to the user from a method
RsiStrategy
是一个 class 应该由用户修改,所以它适合他的愿望。有那个循环,例如。 if (i < StartupCandleCount - 1)
暴露给用户,不是很好,因为用户不关心它。用户关心的,是指标人口和buy/sell条件。你们能给我一些解决方法吗?
public interface IStrategy
{
IReadOnlyList<TradeAdvice> Prepare(IReadOnlyList<Ohlcv> candles);
}
public abstract class StrategyBase : IStrategy
{
public abstract IReadOnlyList<TradeAdvice> Prepare(IReadOnlyList<Ohlcv> candles);
}
public class RsiStrategy : StrategyBase
{
public override IReadOnlyList<TradeAdvice> Prepare(IReadOnlyList<Ohlcv> candles)
{
var result = new List<TradeAdvice>();
var rsiPeriod = 4;
var rsi = candles.Rsi(rsiPeriod);
for (int i = 0; i < candles.Count; i++)
{
if (i < StartupCandleCount - 1)
result.Add(TradeAdvice.WarmupData);
else 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.NoAction);
}
return result;
}
}
预计
我期待类似下面的内容和关于 if (i < StartupCandleCount - 1)
的逻辑,并且该循环可能应该移至摘要 class。
private void PopulateIndicators()
{
var rsi = candles.Rsi(14);
var ema = candles.Ema(6);
// these have to be returned somehow
}
// TODO: I could of course pass current and previous item to the method,
// but I want to be access anything, e.g. rsi[i - 42]. That's basically shifting right
public void BuyCondition()
{
return rsi[i] < 45 && rsi[i] > rsi[i - 1])
}
public void SellCondition()
{
return rsi[i] > 70;
}
一种可能的解决方案是让所有策略实现来自 StrategyBase
、public abstract TradeAdvice Advise(IReadOnlyList<Ohlcv> candles, int index);
的抽象方法
StrategyBase
将生成预热数据交易建议,运行 循环用于其余部分并为每个项目调用 Advise
。每个策略都将只实现这个 Advise
方法,而 Prepare
应该只由 StrategyBase
实现。
使用 index
参数,策略知道它为哪个项目提供建议。
如果在循环 运行 之前需要一些准备工作,应该有一个 protected abstract void StrategyBase.Prepare
方法。但是接口的方法应该重命名为 Run
或 Execute
之类的东西。所以:
public interface IStrategy
{
IReadOnlyList<TradeAdvice> Execute(IReadOnlyList<Ohlcv> candles);
}
public abstract class StrategyBase : IStrategy
{
protected abstract void Prepare(IReadOnlyList<Ohlcv> candles);
protected abstract TradeAdvice Advise(int index);
public IReadOnlyList<TradeAdvice> Execute(IReadOnlyList<Ohlcv> candles)
{
// Call Prepare once, fill up WarmupData, call Advise once per the rest of the items
}
}
public class RsiStrategy : StrategyBase
{
protected override void Prepare(IReadOnlyList<Ohlcv> candles)
{
// Calculate rsi and save it and all the rest to class fields
}
protected override TradeAdvice Advise(int index)
{
// return advice using index and class fields
}
}
RsiStrategy
是一个 class 应该由用户修改,所以它适合他的愿望。有那个循环,例如。 if (i < StartupCandleCount - 1)
暴露给用户,不是很好,因为用户不关心它。用户关心的,是指标人口和buy/sell条件。你们能给我一些解决方法吗?
public interface IStrategy
{
IReadOnlyList<TradeAdvice> Prepare(IReadOnlyList<Ohlcv> candles);
}
public abstract class StrategyBase : IStrategy
{
public abstract IReadOnlyList<TradeAdvice> Prepare(IReadOnlyList<Ohlcv> candles);
}
public class RsiStrategy : StrategyBase
{
public override IReadOnlyList<TradeAdvice> Prepare(IReadOnlyList<Ohlcv> candles)
{
var result = new List<TradeAdvice>();
var rsiPeriod = 4;
var rsi = candles.Rsi(rsiPeriod);
for (int i = 0; i < candles.Count; i++)
{
if (i < StartupCandleCount - 1)
result.Add(TradeAdvice.WarmupData);
else 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.NoAction);
}
return result;
}
}
预计
我期待类似下面的内容和关于 if (i < StartupCandleCount - 1)
的逻辑,并且该循环可能应该移至摘要 class。
private void PopulateIndicators()
{
var rsi = candles.Rsi(14);
var ema = candles.Ema(6);
// these have to be returned somehow
}
// TODO: I could of course pass current and previous item to the method,
// but I want to be access anything, e.g. rsi[i - 42]. That's basically shifting right
public void BuyCondition()
{
return rsi[i] < 45 && rsi[i] > rsi[i - 1])
}
public void SellCondition()
{
return rsi[i] > 70;
}
一种可能的解决方案是让所有策略实现来自 StrategyBase
、public abstract TradeAdvice Advise(IReadOnlyList<Ohlcv> candles, int index);
StrategyBase
将生成预热数据交易建议,运行 循环用于其余部分并为每个项目调用 Advise
。每个策略都将只实现这个 Advise
方法,而 Prepare
应该只由 StrategyBase
实现。
使用 index
参数,策略知道它为哪个项目提供建议。
如果在循环 运行 之前需要一些准备工作,应该有一个 protected abstract void StrategyBase.Prepare
方法。但是接口的方法应该重命名为 Run
或 Execute
之类的东西。所以:
public interface IStrategy
{
IReadOnlyList<TradeAdvice> Execute(IReadOnlyList<Ohlcv> candles);
}
public abstract class StrategyBase : IStrategy
{
protected abstract void Prepare(IReadOnlyList<Ohlcv> candles);
protected abstract TradeAdvice Advise(int index);
public IReadOnlyList<TradeAdvice> Execute(IReadOnlyList<Ohlcv> candles)
{
// Call Prepare once, fill up WarmupData, call Advise once per the rest of the items
}
}
public class RsiStrategy : StrategyBase
{
protected override void Prepare(IReadOnlyList<Ohlcv> candles)
{
// Calculate rsi and save it and all the rest to class fields
}
protected override TradeAdvice Advise(int index)
{
// return advice using index and class fields
}
}