Has anybody built a paper broker that is driven off of a spreadsheet or similar? I want to track positions in unconnected accounts so that I can use the Use Live Position functionality.
Is there another way of doing this?
Is there another way of doing this?
Rename
Since nobody had a quick answer I went ahead and developed a Broker extension. It was fairly easy.
However, the one issue I'm having is when I run a strategy in the Strategy Monitor, with use Live Positions enabled, my configured positions are not being used. The strategy monitor is generating a buy signal for a symbol I already own. I verified my custom broker and account are set correctly in the PosSizer. The strategy is configured to only have 1 position.
In the Accounts windows, the configured accounts and positions are showing up correctly.
Is there something specific in the BrokerBase interface that I need to implement for the Strategy Monitor to use my configured positions?
However, the one issue I'm having is when I run a strategy in the Strategy Monitor, with use Live Positions enabled, my configured positions are not being used. The strategy monitor is generating a buy signal for a symbol I already own. I verified my custom broker and account are set correctly in the PosSizer. The strategy is configured to only have 1 position.
In the Accounts windows, the configured accounts and positions are showing up correctly.
Is there something specific in the BrokerBase interface that I need to implement for the Strategy Monitor to use my configured positions?
If your strategy allows multiple positions for the same instrument, then you can get another buy signal. That type of strategy isn't compatible with Live Positions. (It's just the most obvious explanation for little I know about what you're doing.)
The strategy does not allow for multiple positions. Here is the code for the BrokerBase. Do you see any methods that would prevent the Strategy Monitor to use Live Positions?
And the input file
CODE:
using WealthLab.Core; using System.Collections.Generic; using System.IO; using Newtonsoft.Json; using WealthLab.Backtest; using WealthLab8; using System.Drawing; namespace Extensions.Brokers.Paper { public class PaperBroker : BrokerBase { private bool _isConnected = false; //private readonly string _folder; public PaperBroker () { //_folder = WLHost.Instance.DataFolder; ReadJsonAccounts(); } public override string Name => "Paper Broker"; public override bool IsConnected => _isConnected; public override string CompanionStreamingProviderName => "Yahoo! Finance"; public override string CompanionDataProviderName => "WealthData"; private void ReadJsonAccounts() { string json = File.ReadAllText("PaperAccounts.json"); var data = JsonConvert.DeserializeObject<Data>(json) ?? throw new NullReferenceException(); var paperAccounts = data.Accounts; DisplayBrokerMessage("Reading accounts file", WLColor.Yellow); try { foreach (var acct in paperAccounts) { var brokerAccount = new BrokerAccount(this) { AccountID = acct.Id, Cash = acct.Cash, BuyingPower = acct.BuyingPower, AccountValue = acct.Balance, Nickname = acct.Name }; foreach (var pos in acct.Positions) { var posType = PositionType.Long; if (!string.IsNullOrEmpty(pos.PositionType)) posType = pos.PositionType == "Short" ? PositionType.Short : PositionType.Long; var brokerPosition = new BrokerPosition(brokerAccount) { BasisPrice = pos.CostBasis, Quantity = pos.Quantity, Symbol = pos.Symbol, PositionType = posType, CurrentPrice = pos.LastPrice, EntryDate = pos.EntryDate , SecurityType = SecurityType.Crypto, SignalDate = pos.EntryDate }; brokerAccount.Positions.Add(brokerPosition); } Accounts.Add(brokerAccount); } DisplayBrokerMessage("Connected", WLColor.Green); } catch (Exception e) { DisplayBrokerMessage("Error attempting to connected.", WLColor.Red, e); } _isConnected = true; } protected override void CancelTrade(Transaction t) { throw new NotImplementedException(); } protected override void PlaceTrade(Transaction t) { throw new NotImplementedException(); } } public class Data { public required List<Account> Accounts { get; set; } } public class Account { public required string Id { get; set; } public required string Name { get; set; } public required double Balance { get; set; } public required double BuyingPower { get; set; } public required double Cash { get; set; } public List<Position> Positions { get; set; } = []; } public class Position { public required string Symbol { get; set; } public required double Quantity { get; set; } public required double CostBasis { get; set; } public required double LastPrice { get; set; } public string PositionType { get; set; } = "Long"; public required DateTime EntryDate { get; set; } } }
And the input file
CODE:
{ "Accounts": [ { "Id": "Coinbase", "Name": "Coinbase", "Balance": 10000, "BuyingPower": 0, "Cash": 0, "Positions": [ { "Symbol": "ETH.USD", "EntryDate": "9/1/2024", "Quantity": 3.5, "CostBasis": 3500, "PositionType": "Long", "LastPrice": 3889.82 } ] } ] }
Run the strategy in a Streaming chart with CryptoCompare data. Let's see if the position shows up in the chart. It's a good place to start.
Your Response
Post
Edit Post
Login is required