syntax = "proto3";

package btrpc;

import "google/api/annotations.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";

option go_package = "github.com/thrasher-corp/gocryptotrader/backtester/btrpc";

// struct definitions
message StrategySettings {
  string name = 1;
  bool use_simultaneous_signal_processing = 2;
  bool disable_usd_tracking = 3;
  repeated CustomSettings custom_settings = 4;
}

message CustomSettings {
  string key_field = 1;
  string key_value = 2;
}

message ExchangeLevelFunding {
  string exchange_name = 1;
  string asset = 2;
  string currency = 3;
  string initial_funds = 4;
  string transfer_fee = 5;
}

message FundingSettings {
  bool use_exchange_level_funding = 1;
  repeated ExchangeLevelFunding exchange_level_funding = 2;
}

message PurchaseSide {
  string minimum_size = 1;
  string maximum_size = 2;
  string maximum_total = 3;
}

message SpotDetails {
  string initial_base_funds = 1;
  string initial_quote_funds = 2;
}

message FuturesDetails {
  Leverage leverage = 1;
}

message CurrencySettings {
  string exchange_name = 1;
  string asset = 2;
  string base = 3;
  string quote = 4;
  PurchaseSide buy_side = 5;
  PurchaseSide sell_side = 6;
  string min_slippage_percent = 7;
  string max_slippage_percent = 8;
  string maker_fee_override = 9;
  string taker_fee_override = 10;
  string maximum_holdings_ratio = 11;
  bool skip_candle_volume_fitting = 12;
  bool use_exchange_order_limits = 13;
  bool use_exchange_pnl_calculation = 14;
  SpotDetails spot_details = 15;
  FuturesDetails futures_details = 16;
}

message ApiData {
  google.protobuf.Timestamp start_date = 1;
  google.protobuf.Timestamp end_date = 2;
  bool inclusive_end_date = 3;
}

message DbConfig {
  bool enabled = 1;
  bool verbose = 2;
  string driver = 3;
  string host = 4;
  uint32 port = 5;
  string username = 6;
  string password = 7;
  string database = 8;
  string ssl_mode = 9;
}

message DbData {
  google.protobuf.Timestamp start_date = 1;
  google.protobuf.Timestamp end_date = 2;
  DbConfig config = 3;
  string path = 4;
  bool inclusive_end_date = 5;
}

message CsvData {
  string path = 1;
}

message DatabaseConnectionDetails {
  string host = 1;
  uint32 port = 2;
  string user_name = 3;
  string password = 4;
  string database = 5;
  string ssl_mode = 6;
}

message DatabaseConfig {
  bool enabled = 1;
  bool verbose = 2;
  string driver = 3;
  DatabaseConnectionDetails config = 4;
}

message DatabaseData {
  google.protobuf.Timestamp start_date = 1;
  google.protobuf.Timestamp end_date = 2;
  DatabaseConfig config = 3;
  string path = 4;
  bool inclusive_end_date = 5;
}

message CSVData {
  string path = 1;
}

message LiveData {
  int64 new_event_timeout = 1;
  int64 data_check_timer = 2;
  bool real_orders = 3;
  bool close_positions_on_stop = 4;
  int64 data_request_retry_tolerance = 5;
  int64 data_request_retry_wait_time = 6;
  bool use_real_orders = 7;
  repeated Credentials credentials = 8;
}

message Credentials {
  string exchange = 1;
  ExchangeCredentials keys = 2;
}

message ExchangeCredentials {
  string key = 1;
  string secret = 2;
  string client_id = 3;
  string pem_key = 4;
  string sub_account = 5;
  string one_time_password = 6;
}

message DataSettings {
  google.protobuf.Duration interval = 1;
  string datatype = 2;
  ApiData api_data = 3;
  DatabaseData database_data = 4;
  CSVData csv_data = 5;
  LiveData live_data = 6;
}

message Leverage {
  bool can_use_leverage = 1;
  string maximum_orders_with_leverage_ratio = 2;
  string maximum_leverage_rate = 3;
  string maximum_collateral_leverage_rate = 4;
}

message PortfolioSettings {
  Leverage leverage = 1;
  PurchaseSide buy_side = 2;
  PurchaseSide sell_side = 3;
}

message StatisticSettings {
  string risk_free_rate = 1;
}

message Config {
  string nickname = 1;
  string goal = 2;
  StrategySettings strategy_settings = 3;
  FundingSettings funding_settings = 4;
  repeated CurrencySettings currency_settings = 5;
  DataSettings data_settings = 6;
  PortfolioSettings portfolio_settings = 7;
  StatisticSettings statistic_settings = 8;
}

message TaskSummary {
  string id = 1;
  string strategy_name = 2;
  string date_loaded = 3;
  string date_started = 4;
  string date_ended = 5;
  bool closed = 6;
  bool live_testing = 7;
  bool real_orders = 8;
}

// Requests and responses
message ExecuteStrategyFromFileRequest {
  string strategy_file_path = 1;
  bool do_not_run_immediately = 2;
  bool do_not_store = 3;
  google.protobuf.Timestamp start_time_override = 4;
  google.protobuf.Timestamp end_time_override = 5;
  google.protobuf.Duration interval_override = 6;
}

message ExecuteStrategyResponse {
  TaskSummary task = 1;
}

message ExecuteStrategyFromConfigRequest {
  bool do_not_run_immediately = 1;
  bool do_not_store = 2;
  btrpc.Config config = 3;
}

message ListAllTasksRequest {}

message ListAllTasksResponse {
  repeated TaskSummary tasks = 1;
}

message StopTaskRequest {
  string id = 1;
}

message StopTaskResponse {
  TaskSummary stopped_task = 1;
}

message StartTaskRequest {
  string id = 1;
}

message StartTaskResponse {
  bool started = 1;
}

message StartAllTasksRequest {}

message StartAllTasksResponse {
  repeated string tasks_started = 1;
}

message StopAllTasksRequest {}

message StopAllTasksResponse {
  repeated TaskSummary tasks_stopped = 1;
}

message ClearTaskRequest {
  string id = 1;
}

message ClearTaskResponse {
  TaskSummary cleared_task = 1;
}

message ClearAllTasksRequest {}

message ClearAllTasksResponse {
  repeated TaskSummary cleared_tasks = 1;
  repeated TaskSummary remaining_tasks = 2;
}

service BacktesterService {
  rpc ExecuteStrategyFromFile(ExecuteStrategyFromFileRequest) returns (ExecuteStrategyResponse) {
    option (google.api.http) = {post: "/v1/executestrategyfromfile"};
  }
  rpc ExecuteStrategyFromConfig(ExecuteStrategyFromConfigRequest) returns (ExecuteStrategyResponse) {
    option (google.api.http) = {post: "/v1/executestrategyfromconfig"};
  }
  rpc ListAllTasks(ListAllTasksRequest) returns (ListAllTasksResponse) {
    option (google.api.http) = {get: "/v1/listalltasks"};
  }
  rpc StartTask(StartTaskRequest) returns (StartTaskResponse) {
    option (google.api.http) = {post: "/v1/starttask"};
  }
  rpc StartAllTasks(StartAllTasksRequest) returns (StartAllTasksResponse) {
    option (google.api.http) = {post: "/v1/startalltasks"};
  }
  rpc StopTask(StopTaskRequest) returns (StopTaskResponse) {
    option (google.api.http) = {post: "/v1/stoptask"};
  }
  rpc StopAllTasks(StopAllTasksRequest) returns (StopAllTasksResponse) {
    option (google.api.http) = {post: "/v1/stopalltasks"};
  }
  rpc ClearTask(ClearTaskRequest) returns (ClearTaskResponse) {
    option (google.api.http) = {delete: "/v1/cleartask"};
  }
  rpc ClearAllTasks(ClearAllTasksRequest) returns (ClearAllTasksResponse) {
    option (google.api.http) = {delete: "/v1/clearalltasks"};
  }
}
