Get Positions history
Is there a way to get the list of all positions not just the open ones?
Looking into the PositionsCollection class I only see how to get the open positions. There is a GetClosedPositionById but I haven't found a way to get the historical list of positions (closed positions alà Position History panel).
Thanks!
The best way to get any historical data is using reports (in your case "Positions History Report"), our API inlcudes some classes for working with them. You can get any data from any report available in PTMC (don't forget this list depends on broker). Algorithm in a few words: select necessary report, specify parameters, call ReceiveData and analyse result.
I'll ask our developer to prepare example for CodeBase.
Thanks for your help guys!
@Williams Keeping a list of order/position ids in the strategy is not an option in my case because I have more than one strategy per account. I could keep this list in some persistent shared storage (like file or database) but it would never be as precise and consistent as directly querying the "source of truth" :).
@Bogdan The Report class looks promising. If it contains what I can see in the Position History panel then I think I have everything I need.
BTW, I tried getting the report by name using "Position History Report" but no luck. I always get null. Maybe I misspelled the name or that report with that name does not really exist.
Report r = Report.GetReportByName("Position History Report");
I will wait for the CodeBase example. For sure it will be very helpful.
dreyes
Hi,
You can use a while-loop to get the values:
Here's my code
Now, I did what the documentation said, but it has me passing the received data to a variable, instead of an array. But anyhow, I tried to print it, with no luck. Maybe another member can assist you. I don't see any other method or property. Also, you can print the name and id on the same line and just access the report by id.
Anyhow, I got you at least halfway there.
Thanks for using NETScript.
NOTE: Include "using PTLRuntime.NETScript.Report;"
Same as Williams, I have been trying to retrieve the data from any report with no luck. I always get an empty DataTable array.
Report[] reports = Report.GetAllReports(); foreach (var report in reports) { DataTable[] tables = report.RecieveData(); if (tables.Length > 0) { Print(report.Id, ": ", report.Name, " Data Received"); } }
DataTable[] tables = report.RecieveData();
You got this to compile?
When I attempted this before, I couldn't and still can't. But one thing I noticed is that you don't have a foreach-loop to cycle through your DataTable array. You will need two foreach-loops in this case. One to print out all the reports and one to print out the info that those reports hold.
Yep, it compiles (I'm using Visual Studio, just in case). You need to include:
using System.Data;
But with var and letting the compile to determine implicitly the type should be same.
But one thing I noticed is that you don't have a foreach-loop to cycle through your DataTable array
You are right. I am not iterating through all DataTable rows/items. This is because there is nothing to cycle through because the Length is always 0 :(. This way is how I know that none of the reports contain data. Because I never get the Print log with the Data Received message.
Hahaha,
Yeah I was having my dumb moment. I was thinking that DataTable was part of NETScript.
And yeah, even with the code that you had, you would have received something with the if-statement if it wasn't empty. Good point and you silenced me :).
I'm glad that Alexey and Vlad were able to provide you with something.
Have a great weekend guys!
using System;using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using PTLRuntime.NETScript;
using PTLRuntime.NETScript.Report;
using System.Data;
namespace ReportExample
{
public class ReportExample : NETStrategy
{
public ReportExample()
: base()
{
}
void GetReportExample()
{
// Print all available reports
Print("All reports:");
Report[] allReports = Report.GetAllReports();
for (int i = 0; i < allReports.Length; i++)
Print(allReports[i].Name);
// Try to get "Positions History Report"
Report r = Report.GetReportByName("Positions History Report");
if (r != null)
{
// Print all available parameters for this report
Print("\r\nParameters:");
foreach (KeyValuePair<string, ReportParameter> pair in r.ReportParameters)
Print(pair.Value.Name);
// Specify some parameters
((DateTimeReportParameter)r.ReportParameters["fromDate"]).Value = new DateTime(2016, 08, 9);
((DateTimeReportParameter)r.ReportParameters["toDate"]).Value = new DateTime(2016, 08, 12);
// Get report and print result
Print("\r\nStart getting report...");
DataTable[] tables = r.RecieveData();
if (tables != null && tables.Length > 0)
{
DataTable table = tables[0];
Print("Report received successfully. Rows int report: " + table.Rows.Count);
// Print columns headers
string row = "";
for (int i = 0; i < table.Columns.Count; i++)
row = row + table.Columns[i].ColumnName+" | ";
Print(row);
// Print rows
for (int i = 0; i < table.Rows.Count; i++)
{
row = "";
for (int j = 0; j < table.Columns.Count; j++)
row = row + table.Rows[i][j]+" | ";
Print(row);
}
}
else
Print("Fail to get data!");
}
else
Print("Fail to find report!");
}
public override void OnQuote()
{
if (firstTime)
{
GetReportExample();
firstTime = false;
}
}
bool firstTime = true;
}
}
Thanks for the sample code! Now I see how the ReportParameters are intended to be used.
I tried the code provided but I always get Fail to find the report. I don't know why but this concrete report "Positions History Report" does not exist. It is not even listed in all reports:
All reports:
Balance Report
Balance Summary Report
Trades Report
Performance history report
Account Statement
Fund Investor Action History Report
Order Book Report
Commissions report
Removed Orders Report
Order History Report
Trades Report
Order History Report
Event History Report
Open Positions Report
Balance Summary Report
Fund Request History Report
Fund Gain History Report
Order Book History
Balance Report
Account operation report (settled)
Order Book Report
Fail to find report!
Just in case it is useful, I am using PTMC version 1.0.40 build 02/08/2016 connected to a Protrader Demo.
It means that report not available on this server for your user. Our support has enabled it. But main idea of this example is to show how to get access for any report data, the same data like you see in Reports panel in terminal. So you can check all reports, find the best for your purposes and use it in your code.
I have had some "free" time to resume on this topic and @Burhay Vlad code has turned to be really helpful (Thanks @Burhay Vlad). It made me realise that it actually works :). I can get actual data from Report. Well, actually, the problem was not I was doing something specially wrong because I tried my code directly in the Trading System and voilà! All the report data was there in the Logs tab.
Stubbornly I was always running my code on AlgoStudio where I have not been able to retrieve report data. Is Report supposed to work in AlgoStudio? That is, with backtesting data?
Thanks!
Here you have a contrived strategy that shows report data when run on Trading System but fails to do it when run on AlgoStudio:
using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Drawing; using PTLRuntime.NETScript; using PTLRuntime.NETScript.Report; using System.Data; namespace ReportExample { public class ReportExample : NETStrategy { void GetReportExample() { Report r = Report.GetReportByName("Order Book History"); if (r != null) { ((DateTimeReportParameter)r.ReportParameters["fromDate"]).Value = startTime; ((DateTimeReportParameter)r.ReportParameters["toDate"]).Value = Instruments.Current.LastQuote.Time; ((AccountsReportParameter)r.ReportParameters["login"]).Value = new List<Account>(Accounts.GetSortedAccounts()); DataTable[] tables = r.RecieveData(); if (tables != null && tables.Length > 0) { DataTable table = tables[0]; Print("Report received successfully. Rows int report: " + table.Rows.Count); string row = ""; for (int i = 0; i < table.Columns.Count; i++) row = row + table.Columns[i].ColumnName+" | "; Print(row); for (int i = 0; i < table.Rows.Count; i++) { row = ""; for (int j = 0; j < table.Columns.Count; j++) row = row + table.Rows[i][j]+" | "; Print(row); } } else Print("Fail to get data!"); } else Print("Fail to find report!"); } public override void OnQuote() { if (quotes == 0) { startTime = Instruments.Current.LastQuote.Time; } if (quotes % 100 == 1) { OpenPosition(); } if (quotes % 100 == 2) { GetReportExample(); } quotes += 1; } int quotes = 0; DateTime startTime = DateTime.Now; void OpenPosition() { NewOrderRequest request = new NewOrderRequest { MagicNumber = 0, Instrument = Instruments.Current, Account = Accounts.Current, Type = OrdersType.Market, Side = Operation.Buy, Amount = 1, Price = Ask, StopLossOffset = 0.001, TakeProfitOffset = 0.001 }; Orders.Send(request); } } }
Dear Dreyes
Thanks for your unquenchable interest in PTMC, nothing makes PTMC team proud more than people engaged in community and Algo coding. You got the point how reports schema works in terminal. Though same behavior won't work in Algo back-testing at a time being, because it is not designed this way. Once user operate in terminal a constant server connection established, that way r.RecieveData() works, but back in Algo Studio any strategy testing must be assured by downloaded database snapshot which later cached and used in testing. So that is why r.RecieveData() returns nothing during debugging. At this point this topic is under consideration so please stay tuned. Definitely PTMC DevOps interested in such feature in upcoming AlgoStudio's versions. However, owing lack of related information, one way to achieve it is just randomly emulate data during catching a snapshot. But this functionality should fully meat tester's expectations. I have already add a feature request: https://protrader.org/request/implement-a-reports-d...
That's good news! I am going to upvote this feature request right now :).
Emulating a trading environment under a controlled lab or testing environment as close as possible to a real one is something that makes Algo development and testing easier. You can start/stop/restart/speed up/slow down the flow of quotes. You can play the same scenario again and again. You can even create synthetic scenarios.
As a developer, I will always celebrate any progress in that direction. I see AlgoStudio as a potential development product per se (regardless it is integrated in Visual Studio or as a separate application).
Keep up with the good work guys!
This topic was started in 08.08.2016, today (17/07/2018), as the original question sais: is there a way to get the list of all positions not just the open ones?
Has there been any improvement?
I'm looking for a way to get the result of closed positions and calculate the total win or loss of some specific EA (identified by its ID).
(edited)
By the way, the code above doesn't work in the AlgoStudio.
It means that report not available on this server for your user. Our support has enabled it. But main idea of this example is to show how to get access for any report data, the same data like you see in Reports panel in terminal. So you can check all reports, find the best for your purposes and use it in your code. Show more Shorten
Hello Bogdan Alexey,
So, do you means that is necessary enable
this report manually by the support team? Why this is not enabled by
default? This can make our live much more easier.
Anyway, is possible to enable it for me?
Thanks