Backtesting.execution

Execution API module for trade execution across different brokers.

Execution

Wrapper class for batch trade execution with validation.

Source code in Backtesting/execution.py
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
class Execution:
    """Wrapper class for batch trade execution with validation."""

    def __init__(self, api: ExecutionAPI):
        """Initialize execution wrapper with API adapter.

        Args:
            api: ExecutionAPI instance to use for trade execution.

        Raises:
            ConnectionError: If API is not connected.
        """
        self.api = api
        if not self.api.is_connected():
            raise ConnectionError("Execution API is not connected")

    def execute(self, output: List[Tuple[str, int, int, float]], time_step: int) -> List[bool]:
        """Execute all trades from output array with validation.

        Args:
            output: List of trade tuples (stock, shares, flag, price).
            time_step: Current time step.

        Returns:
            List of bools indicating success/failure for each trade.
        """
        results = []

        for trade in output:
            stock, shares, flag, desired_price = trade #the fourth argument is unnecessary just wanted to keep the output object consistent

            # Validate trade tuple
            if not isinstance(stock, str) or not isinstance(shares, int) or not isinstance(flag, int):
                print(f"Invalid trade format: {trade}")
                results.append(False)
                continue

            if shares <= 0:
                print(f"Invalid shares amount: {shares}")
                results.append(False)
                continue

            if flag not in [-1, 1]:
                print(f"Invalid flag: {flag} (must be -1 for sell or 1 for buy)")
                results.append(False)
                continue

            # Execute the trade
            success = self.api.execute_trade(stock, shares, flag, time_step)
            results.append(success)

        return results

    def set_api(self, api: ExecutionAPI):
        """Change execution API adapter at runtime.

        Args:
            api: New ExecutionAPI instance.

        Raises:
            ConnectionError: If new API is not connected.
        """
        self.api = api
        if not self.api.is_connected():
            raise ConnectionError("Execution API is not connected")

__init__(api)

Initialize execution wrapper with API adapter.

Parameters:
  • api (ExecutionAPI) –

    ExecutionAPI instance to use for trade execution.

Raises:
  • ConnectionError

    If API is not connected.

Source code in Backtesting/execution.py
151
152
153
154
155
156
157
158
159
160
161
162
def __init__(self, api: ExecutionAPI):
    """Initialize execution wrapper with API adapter.

    Args:
        api: ExecutionAPI instance to use for trade execution.

    Raises:
        ConnectionError: If API is not connected.
    """
    self.api = api
    if not self.api.is_connected():
        raise ConnectionError("Execution API is not connected")

execute(output, time_step)

Execute all trades from output array with validation.

Parameters:
  • output (List[Tuple[str, int, int, float]]) –

    List of trade tuples (stock, shares, flag, price).

  • time_step (int) –

    Current time step.

Returns:
  • List[bool]

    List of bools indicating success/failure for each trade.

Source code in Backtesting/execution.py
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
def execute(self, output: List[Tuple[str, int, int, float]], time_step: int) -> List[bool]:
    """Execute all trades from output array with validation.

    Args:
        output: List of trade tuples (stock, shares, flag, price).
        time_step: Current time step.

    Returns:
        List of bools indicating success/failure for each trade.
    """
    results = []

    for trade in output:
        stock, shares, flag, desired_price = trade #the fourth argument is unnecessary just wanted to keep the output object consistent

        # Validate trade tuple
        if not isinstance(stock, str) or not isinstance(shares, int) or not isinstance(flag, int):
            print(f"Invalid trade format: {trade}")
            results.append(False)
            continue

        if shares <= 0:
            print(f"Invalid shares amount: {shares}")
            results.append(False)
            continue

        if flag not in [-1, 1]:
            print(f"Invalid flag: {flag} (must be -1 for sell or 1 for buy)")
            results.append(False)
            continue

        # Execute the trade
        success = self.api.execute_trade(stock, shares, flag, time_step)
        results.append(success)

    return results

set_api(api)

Change execution API adapter at runtime.

Parameters:
Raises:
  • ConnectionError

    If new API is not connected.

Source code in Backtesting/execution.py
201
202
203
204
205
206
207
208
209
210
211
212
def set_api(self, api: ExecutionAPI):
    """Change execution API adapter at runtime.

    Args:
        api: New ExecutionAPI instance.

    Raises:
        ConnectionError: If new API is not connected.
    """
    self.api = api
    if not self.api.is_connected():
        raise ConnectionError("Execution API is not connected")

ExecutionAPI

Bases: ABC

Abstract base class for execution API implementations.

Source code in Backtesting/execution.py
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class ExecutionAPI(ABC):
    """Abstract base class for execution API implementations."""

    @abstractmethod
    def execute_trade(self, stock: str, num_shares: int, flag: int, time_step: int) -> bool:
        """Execute a single trade.

        Args:
            stock: Stock symbol.
            num_shares: Number of shares to trade.
            flag: 1 for buy, -1 for sell.
            time_step: Current time step.

        Returns:
            True if trade executed successfully, False otherwise.
        """
        pass

    @abstractmethod
    def is_connected(self) -> bool:
        """Check if API connection is active."""
        pass

execute_trade(stock, num_shares, flag, time_step) abstractmethod

Execute a single trade.

Parameters:
  • stock (str) –

    Stock symbol.

  • num_shares (int) –

    Number of shares to trade.

  • flag (int) –

    1 for buy, -1 for sell.

  • time_step (int) –

    Current time step.

Returns:
  • bool

    True if trade executed successfully, False otherwise.

Source code in Backtesting/execution.py
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
@abstractmethod
def execute_trade(self, stock: str, num_shares: int, flag: int, time_step: int) -> bool:
    """Execute a single trade.

    Args:
        stock: Stock symbol.
        num_shares: Number of shares to trade.
        flag: 1 for buy, -1 for sell.
        time_step: Current time step.

    Returns:
        True if trade executed successfully, False otherwise.
    """
    pass

is_connected() abstractmethod

Check if API connection is active.

Source code in Backtesting/execution.py
23
24
25
26
@abstractmethod
def is_connected(self) -> bool:
    """Check if API connection is active."""
    pass

MockExecutionAPI

Bases: ExecutionAPI

Mock execution API for backtesting. No actual trades executed.

Source code in Backtesting/execution.py
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class MockExecutionAPI(ExecutionAPI):
    """Mock execution API for backtesting. No actual trades executed."""

    def __init__(self):
        """Initialize mock execution API."""
        self.connected = True

    def execute_trade(self, stock: str, num_shares: int, flag: int, time_step: int) -> bool:
        """Mock trade execution. Required for backtesting with historical prices.

        Args:
            stock: Stock symbol.
            num_shares: Number of shares to trade.
            flag: 1 for buy, -1 for sell.
            time_step: Current time step.

        Returns:
            Always returns True (no actual execution).
        """
        return True 

    def is_connected(self) -> bool:
        """Always returns True for mock API."""
        return self.connected

__init__()

Initialize mock execution API.

Source code in Backtesting/execution.py
31
32
33
def __init__(self):
    """Initialize mock execution API."""
    self.connected = True

execute_trade(stock, num_shares, flag, time_step)

Mock trade execution. Required for backtesting with historical prices.

Parameters:
  • stock (str) –

    Stock symbol.

  • num_shares (int) –

    Number of shares to trade.

  • flag (int) –

    1 for buy, -1 for sell.

  • time_step (int) –

    Current time step.

Returns:
  • bool

    Always returns True (no actual execution).

Source code in Backtesting/execution.py
35
36
37
38
39
40
41
42
43
44
45
46
47
def execute_trade(self, stock: str, num_shares: int, flag: int, time_step: int) -> bool:
    """Mock trade execution. Required for backtesting with historical prices.

    Args:
        stock: Stock symbol.
        num_shares: Number of shares to trade.
        flag: 1 for buy, -1 for sell.
        time_step: Current time step.

    Returns:
        Always returns True (no actual execution).
    """
    return True 

is_connected()

Always returns True for mock API.

Source code in Backtesting/execution.py
49
50
51
def is_connected(self) -> bool:
    """Always returns True for mock API."""
    return self.connected

PaperAlpacaExecutionAPI

Bases: ExecutionAPI

Alpaca paper trading execution API implementation.

Source code in Backtesting/execution.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
class PaperAlpacaExecutionAPI(ExecutionAPI):
    """Alpaca paper trading execution API implementation."""

    def __init__(self, api_key: str, secret_key: str, base_url: str = None):
        """Initialize Alpaca paper trading API client.

        Args:
            api_key: Alpaca API key.
            secret_key: Alpaca secret key.
            base_url: Optional base URL for API (defaults to paper trading).
        """
        self.api_key = api_key
        self.secret_key = secret_key
        self.base_url = base_url

    def execute_trade(self, stock: str, num_shares: int, flag: int, time_step: int) -> bool:
        """Execute trade via Alpaca paper trading API.

        Args:
            stock: Stock symbol.
            num_shares: Number of shares to trade.
            flag: 1 for buy, -1 for sell.
            time_step: Current time step.

        Returns:
            True if trade executed successfully, False otherwise.
        """
        try:
            # Example implementation:
            # order = self.client.submit_order(
            #     symbol=stock,
            #     qty=shares,
            #     side="buy" if flag == 1 else "sell",
            #     type="market",
            #     time_in_force="day"
            # )
            # return order.status == "filled"
            print(f"[ALPACA] Would execute: {stock}, {num_shares} shares, flag={flag}")
            return True
        except Exception as e:
            print(f"Error executing trade: {e}")
            return False

    def is_connected(self) -> bool:
        """Check Alpaca API connection status."""
        return True

__init__(api_key, secret_key, base_url=None)

Initialize Alpaca paper trading API client.

Parameters:
  • api_key (str) –

    Alpaca API key.

  • secret_key (str) –

    Alpaca secret key.

  • base_url (str, default: None ) –

    Optional base URL for API (defaults to paper trading).

Source code in Backtesting/execution.py
103
104
105
106
107
108
109
110
111
112
113
def __init__(self, api_key: str, secret_key: str, base_url: str = None):
    """Initialize Alpaca paper trading API client.

    Args:
        api_key: Alpaca API key.
        secret_key: Alpaca secret key.
        base_url: Optional base URL for API (defaults to paper trading).
    """
    self.api_key = api_key
    self.secret_key = secret_key
    self.base_url = base_url

execute_trade(stock, num_shares, flag, time_step)

Execute trade via Alpaca paper trading API.

Parameters:
  • stock (str) –

    Stock symbol.

  • num_shares (int) –

    Number of shares to trade.

  • flag (int) –

    1 for buy, -1 for sell.

  • time_step (int) –

    Current time step.

Returns:
  • bool

    True if trade executed successfully, False otherwise.

Source code in Backtesting/execution.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
def execute_trade(self, stock: str, num_shares: int, flag: int, time_step: int) -> bool:
    """Execute trade via Alpaca paper trading API.

    Args:
        stock: Stock symbol.
        num_shares: Number of shares to trade.
        flag: 1 for buy, -1 for sell.
        time_step: Current time step.

    Returns:
        True if trade executed successfully, False otherwise.
    """
    try:
        # Example implementation:
        # order = self.client.submit_order(
        #     symbol=stock,
        #     qty=shares,
        #     side="buy" if flag == 1 else "sell",
        #     type="market",
        #     time_in_force="day"
        # )
        # return order.status == "filled"
        print(f"[ALPACA] Would execute: {stock}, {num_shares} shares, flag={flag}")
        return True
    except Exception as e:
        print(f"Error executing trade: {e}")
        return False

is_connected()

Check Alpaca API connection status.

Source code in Backtesting/execution.py
143
144
145
def is_connected(self) -> bool:
    """Check Alpaca API connection status."""
    return True

PolygonExecutionAPI

Bases: ExecutionAPI

Polygon.io execution API implementation.

Source code in Backtesting/execution.py
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
class PolygonExecutionAPI(ExecutionAPI):
    """Polygon.io execution API implementation."""

    def __init__(self, api_key: str):
        """Initialize Polygon execution API client.

        Args:
            api_key: Polygon.io API key.
        """
        self.api_key = api_key
        self.connected = False
        # Initialize Polygon client here
        # from polygon import RESTClient
        # self.client = RESTClient(api_key)

    def execute_trade(self, stock: str, num_shares: int, flag: int, time_step: int) -> bool:
        """Execute trade via Polygon API.

        Args:
            stock: Stock symbol.
            num_shares: Number of shares to trade.
            flag: 1 for buy, -1 for sell.
            time_step: Current time step.

        Returns:
            True if trade executed successfully, False otherwise.
        """
        try:
            # Example implementation:
            # order = self.client.place_order(
            #     symbol=stock,
            #     qty=shares,
            #     side="buy" if flag == 1 else "sell",
            #     type="market"
            # )
            # return order.status == "filled"
            print(f"[POLYGON] Would execute: {stock}, {num_shares} shares, flag={flag}")
            return True
        except Exception as e:
            print(f"Error executing trade: {e}")
            return False

    def is_connected(self) -> bool:
        """Check Polygon API connection status."""
        return self.connected

__init__(api_key)

Initialize Polygon execution API client.

Parameters:
  • api_key (str) –

    Polygon.io API key.

Source code in Backtesting/execution.py
56
57
58
59
60
61
62
63
def __init__(self, api_key: str):
    """Initialize Polygon execution API client.

    Args:
        api_key: Polygon.io API key.
    """
    self.api_key = api_key
    self.connected = False

execute_trade(stock, num_shares, flag, time_step)

Execute trade via Polygon API.

Parameters:
  • stock (str) –

    Stock symbol.

  • num_shares (int) –

    Number of shares to trade.

  • flag (int) –

    1 for buy, -1 for sell.

  • time_step (int) –

    Current time step.

Returns:
  • bool

    True if trade executed successfully, False otherwise.

Source code in Backtesting/execution.py
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
def execute_trade(self, stock: str, num_shares: int, flag: int, time_step: int) -> bool:
    """Execute trade via Polygon API.

    Args:
        stock: Stock symbol.
        num_shares: Number of shares to trade.
        flag: 1 for buy, -1 for sell.
        time_step: Current time step.

    Returns:
        True if trade executed successfully, False otherwise.
    """
    try:
        # Example implementation:
        # order = self.client.place_order(
        #     symbol=stock,
        #     qty=shares,
        #     side="buy" if flag == 1 else "sell",
        #     type="market"
        # )
        # return order.status == "filled"
        print(f"[POLYGON] Would execute: {stock}, {num_shares} shares, flag={flag}")
        return True
    except Exception as e:
        print(f"Error executing trade: {e}")
        return False

is_connected()

Check Polygon API connection status.

Source code in Backtesting/execution.py
95
96
97
def is_connected(self) -> bool:
    """Check Polygon API connection status."""
    return self.connected