1use num_enum::FromPrimitive;
2use openpine_macros::Enum;
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 Currency,
7 strategy::{CloseEntriesRule, CommissionType, QuantityType},
8};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12pub enum ScriptType {
13 Indicator(Indicator),
15 Library(Library),
17 Strategy(Strategy),
19}
20
21#[derive(Debug, Copy, Clone, Eq, PartialEq, Enum, Serialize, Deserialize)]
23pub enum Format {
24 Inherit,
26 Price,
28 Volume,
30 Percent,
32 #[openpine(name = "Mintick")]
34 MinTick,
35}
36
37#[derive(Debug, Copy, Clone, Eq, PartialEq, Default, FromPrimitive, Serialize, Deserialize)]
39#[repr(i32)]
40pub enum ScaleType {
41 #[default]
43 None = 0,
44 Left = 1,
46 Right = 2,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct Indicator {
53 pub title: String,
55 pub short_title: Option<String>,
57 pub overlay: bool,
59 pub format: Format,
61 pub precision: Option<u8>,
63 pub scale: ScaleType,
65 pub max_bars_back: Option<usize>,
67 pub timeframe: Option<String>,
69 pub timeframe_gaps: bool,
71 pub explicit_plot_zorder: bool,
73 pub max_lines_count: usize,
75 pub max_labels_count: usize,
77 pub max_boxes_count: usize,
79 pub calc_bars_count: Option<usize>,
81 pub max_polylines_count: usize,
83 pub dynamic_requests: bool,
85 pub behind_chart: bool,
87}
88
89impl ScriptType {
90 pub(crate) fn max_lines_count(&self) -> usize {
92 match self {
93 Self::Indicator(i) => i.max_lines_count,
94 Self::Strategy(s) => s.max_lines_count,
95 Self::Library(_) => unreachable!("library scripts are not executable"),
96 }
97 }
98
99 pub(crate) fn max_labels_count(&self) -> usize {
101 match self {
102 Self::Indicator(i) => i.max_labels_count,
103 Self::Strategy(s) => s.max_labels_count,
104 Self::Library(_) => unreachable!("library scripts are not executable"),
105 }
106 }
107
108 pub(crate) fn max_boxes_count(&self) -> usize {
110 match self {
111 Self::Indicator(i) => i.max_boxes_count,
112 Self::Strategy(s) => s.max_boxes_count,
113 Self::Library(_) => unreachable!("library scripts are not executable"),
114 }
115 }
116
117 pub(crate) fn max_polylines_count(&self) -> usize {
119 match self {
120 Self::Indicator(i) => i.max_polylines_count,
121 Self::Strategy(s) => s.max_polylines_count,
122 Self::Library(_) => unreachable!("library scripts are not executable"),
123 }
124 }
125}
126
127#[derive(Debug, Clone, Serialize, Deserialize)]
129pub struct Library {
130 pub title: String,
132 pub overlay: bool,
134 pub dynamic_requests: bool,
136}
137
138#[derive(Debug, Clone, Serialize, Deserialize)]
140pub struct Strategy {
141 pub title: String,
143 pub short_title: Option<String>,
145 pub overlay: bool,
147 pub format: Format,
149 pub precision: Option<u8>,
151 pub scale: ScaleType,
153 pub pyramiding: u32,
155 pub calc_on_order_fills: bool,
157 pub calc_on_every_tick: bool,
159 pub max_bars_back: Option<usize>,
161 pub backtest_fill_limits_assumption: u32,
163 pub default_qty_type: QuantityType,
165 pub default_qty_value: f64,
167 pub initial_capital: f64,
169 pub currency: Currency,
171 pub slippage: u32,
173 pub commission_type: CommissionType,
175 pub commission_value: f64,
177 pub process_orders_on_close: bool,
179 pub close_entries_rule: CloseEntriesRule,
181 pub margin_long: f64,
183 pub margin_short: f64,
185 pub explicit_plot_zorder: bool,
187 pub max_lines_count: usize,
189 pub max_labels_count: usize,
191 pub max_boxes_count: usize,
193 pub calc_bars_count: Option<usize>,
195 pub risk_free_rate: f64,
197 pub use_bar_magnifier: bool,
199 pub fill_orders_on_standard_ohlc: bool,
201 pub max_polylines_count: usize,
203 pub dynamic_requests: bool,
205 pub behind_chart: bool,
207}