У меня есть классы LiveTradeManager и PaperTradeManager, которые наследуются от TradeManagerBase. Целью TradeManagerBase было создание таких свойств, как Pair, StrategyName и т. Д., Которые можно свободно использовать в производных классах.
Мне кажется, что этот дизайн слишком накладной, потому что я делаю оболочку свойств для тех же свойств. Вызов просто Pair вместо TradeOptions.Pair на самом деле не имеет большого значения, верно? Поскольку сейчас это так, мне потребовалось бы время, если бы я захотел добавить дополнительное свойство из-за дублирования свойств.
Кстати, классы ExchangeOptions и TradeOptions являются параметрами appsettings.json.
Может быть, есть лучший способ справиться с этим? Вместо этого я думал о шаблоне проектирования фабричного метода. Хотите поделиться своими мыслями?
ConcurrentBag<Trade> Trades
вероятно, должен быть внешний класс, например. TradesMemoryStore что ли? Что ты тоже об этом думаешь?
Я как бы хочу придерживаться принципов DRY и KISS.
public static class TradeManagerFactory
{
public static async Task<ITradeManager> BuildAsync(IExchangeClient exchangeClient, ExchangeOptions exchangeOptions, TradeOptions tradeOptions)
{
ITradeManager tradeManager = new LiveTradeManager(exchangeClient, exchangeOptions, tradeOptions);
await tradeManager.InitializeAsync().ConfigureAwait(false);
return tradeManager;
}
}
public interface ITradeManager
{
Task InitializeAsync();
Task RunAsync();
}
public abstract class TradeManagerBase : ITradeManager
{
protected static ConcurrentBag<Trade> Trades { get; private set; }
protected IExchangeClient ExchangeClient { get; }
protected ExchangeOptions ExchangeOptions { get; }
protected TradeOptions TradeOptions { get; }
protected TradeManagerBase(IExchangeClient exchangeClient, ExchangeOptions exchangeOptions, TradeOptions tradeOptions)
{
Trades = new ConcurrentBag<Trade>();
ExchangeClient = exchangeClient;
ExchangeOptions = exchangeOptions;
TradeOptions = tradeOptions;
}
protected ITradingStrategy StrategyResolver { get; private set; }
protected Exchange Exchange { get; private set; }
protected string Pair { get; private set; }
protected string StrategyName { get; private set; }
protected Timeframe Timeframe { get; private set; }
protected int StartupCandleCount { get; private set; }
protected Wallet CurrentWallet { get; private set; }
protected decimal TradableBalanceRatio { get; private set; }
protected string BuyOrderType { get; private set; }
protected string SellOrderType { get; private set; }
public async Task InitializeAsync()
{
StrategyResolver = StrategyUtils.GetStrategyInstance(TradeOptions.StrategyName);
if (StrategyResolver.IsNull())
{
throw new Exception($"The strategy "{TradeOptions.StrategyName}" could not be found.");
}
Exchange = ExchangeOptions.Exchange;
Pair = TradeOptions.Pair;
StrategyName = StrategyResolver.GetStrategyName();
Timeframe = TradeOptions.Timeframe.ToTimeframe();
StartupCandleCount = StrategyResolver.GetStartupCandleCount();
TradableBalanceRatio = TradeOptions.TradableBalanceRatio;
BuyOrderType = TradeOptions.BuyOrderType;
SellOrderType = TradeOptions.SellOrderType;
}
public abstract Task RunAsync();
}
public class LiveTradeManager : TradeManagerBase
{
private static readonly ILog _logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.Name);
public LiveTradeManager(
IExchangeClient exchangeClient,
ExchangeOptions exchangeOptions,
TradeOptions tradeOptions)
: base(exchangeClient, exchangeOptions, tradeOptions)
{
}
public override async Task RunAsync()
{
...
}
}
```