DOC: updating the code docstrings

This commit is contained in:
fredfortier
2017-11-01 21:31:51 -04:00
parent 35677c553c
commit 5b6bbacab0
8 changed files with 527 additions and 193 deletions
+141 -58
View File
@@ -1,5 +1,4 @@
import abc
import re
from abc import ABCMeta, abstractmethod, abstractproperty
from datetime import timedelta
from time import sleep
@@ -16,7 +15,7 @@ from catalyst.exchange.bundle_utils import get_start_dt, \
from catalyst.exchange.exchange_bundle import ExchangeBundle
from catalyst.exchange.exchange_errors import MismatchingBaseCurrencies, \
InvalidOrderStyle, BaseCurrencyNotFoundError, SymbolNotFoundOnExchange, \
InvalidHistoryFrequencyError, PricingDataNotLoadedError, \
PricingDataNotLoadedError, \
NoDataAvailableOnExchange
from catalyst.exchange.exchange_execution import ExchangeStopLimitOrder, \
ExchangeLimitOrder, ExchangeStopOrder
@@ -53,9 +52,11 @@ class Exchange:
@property
def portfolio(self):
"""
Return the Portfolio
The exchange portfolio
:return:
Returns
-------
ExchangePortfolio
"""
if self._portfolio is None:
self._portfolio = ExchangePortfolio(
@@ -75,9 +76,16 @@ class Exchange:
def is_open(self, dt):
"""
Is the exchange open?
:param dt:
:return:
Is the exchange open
Parameters
----------
dt: Timestamp
Returns
-------
bool
"""
# TODO: implement for each exchange.
return True
@@ -90,7 +98,9 @@ class Exchange:
The application will pause if the maximum requests per minute
permitted by the exchange is exceeded.
:return boolean:
Returns
-------
bool
"""
now = pd.Timestamp.utcnow()
@@ -122,10 +132,16 @@ class Exchange:
def get_symbol(self, asset):
"""
Get the exchange specific symbol of the given asset.
The the exchange specific symbol of the specified market.
Parameters
----------
asset: TradingPair
Returns
-------
str
:param asset: Asset
:return: symbol: str
"""
symbol = None
@@ -143,17 +159,34 @@ class Exchange:
"""
Get a list of symbols corresponding to each given asset.
:param assets: Asset[]
:return:
Parameters
----------
assets: list[TradingPair]
Returns
-------
list[str]
"""
symbols = []
for asset in assets:
symbols.append(self.get_symbol(asset))
return symbols
def get_assets(self, symbols=None):
"""
The list of markets for the specified symbols.
Parameters
----------
symbols: list[str]
Returns
-------
list[TradingPair]
"""
assets = []
if symbols is not None:
@@ -168,9 +201,16 @@ class Exchange:
def get_asset(self, symbol):
"""
Find an Asset on the current exchange based on its Catalyst symbol
:param symbol: the [target]_[base] currency pair symbol
:return: Asset
The market for the specified symbol.
Parameters
----------
symbol: str
Returns
-------
TradingPair
"""
asset = None
@@ -201,7 +241,6 @@ class Exchange:
currency pair symbol. The universal symbol is contained in the
'symbol' attribute of each asset.
Notes
-----
The sid of each asset is calculated based on a numeric hash of the
@@ -210,8 +249,8 @@ class Exchange:
This method can be overridden if an exchange offers equivalent data
via its api.
"""
"""
symbol_map = self.fetch_symbol_map()
for exchange_symbol in symbol_map:
asset = symbol_map[exchange_symbol]
@@ -272,8 +311,10 @@ class Exchange:
For each executed order found, create a transaction and apply to the
Portfolio.
:return:
transactions: Transaction[]
Returns
-------
list[Transaction]
"""
transactions = list()
if self.portfolio.open_orders:
@@ -390,14 +431,20 @@ class Exchange:
"""
Get a series of field data for the specified candles.
:param candles:
:param start_dt:
:param end_dt:
:param field:
:param previous_value:
:return:
"""
Parameters
----------
candles: list[dict[str, float]]
start_dt: datetime
end_dt: datetime
data_frequency: str
field: str
previous_value: float
Returns
-------
Series
"""
dates = [candle['last_traded'] for candle in candles]
values = [candle[field] for candle in candles]
series = pd.Series(values, index=dates)
@@ -430,10 +477,11 @@ class Exchange:
Parameters
----------
assets : list of catalyst.data.Asset objects
assets : list[TradingPair]
The assets whose data is desired.
end_dt: not applicable to cryptocurrencies
end_dt: datetime
The date of the last bar
bar_count: int
The number of bars desired.
@@ -493,10 +541,11 @@ class Exchange:
Parameters
----------
assets : list of catalyst.data.Asset objects
assets : list[TradingPair]
The assets whose data is desired.
end_dt: not applicable to cryptocurrencies
end_dt: datetime
The date of the last bar.
bar_count: int
The number of bars desired.
@@ -518,9 +567,10 @@ class Exchange:
Returns
-------
A dataframe containing the requested data.
"""
DataFrame
A dataframe containing the requested data.
"""
freq, candle_size, unit, data_frequency = get_frequency(
frequency, data_frequency
)
@@ -591,7 +641,6 @@ class Exchange:
Update the portfolio cash and position balances based on the
latest ticker prices.
:return:
"""
log.debug('synchronizing portfolio with exchange {}'.format(self.name))
balances = self.get_balances()
@@ -635,16 +684,20 @@ class Exchange:
Parameters
----------
asset : Asset
asset : TradingPair
The asset that this order is for.
amount : int
The amount of shares to order. If ``amount`` is positive, this is
the number of shares to buy or cover. If ``amount`` is negative,
this is the number of shares to sell or short.
limit_price : float, optional
The limit price for the order.
stop_price : float, optional
The stop price for the order.
style : ExecutionStyle, optional
The execution style for the order.
@@ -669,6 +722,7 @@ class Exchange:
:class:`catalyst.finance.execution.ExecutionStyle`
:func:`catalyst.api.order_value`
:func:`catalyst.api.order_percent`
"""
if amount == 0:
log.warn('skipping order amount of 0')
@@ -718,8 +772,12 @@ class Exchange:
@abstractmethod
def get_balances(self):
"""
Retrieve wallet balances for the exchange
:return balances: A dict of currency => available balance
Retrieve wallet balances for the exchange.
Returns
-------
dict[TradingPair, float]
"""
pass
@@ -728,17 +786,25 @@ class Exchange:
"""
Place an order on the exchange.
:param asset : Asset
The asset that this order is for.
:param amount : int
Parameters
----------
asset: TradingPair
The target market.
amount: float
The amount of shares to order. If ``amount`` is positive, this is
the number of shares to buy or cover. If ``amount`` is negative,
this is the number of shares to sell or short.
:param style : ExecutionStyle
The execution style for the order.
:param is_buy: boolean
is_buy: bool
Is it a buy order?
:return:
style: ExecutionStyle
Returns
-------
Order
"""
pass
@@ -798,19 +864,27 @@ class Exchange:
"""
Retrieve OHLCV candles for the given assets
:param freq:
Parameters
----------
freq: str
The frequency alias per convention:
http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases
:param assets: list[TradingPair]
assets: list[TradingPair]
The targeted assets.
:param bar_count:
bar_count: int
The number of bar desired. (default 1)
:param end_dt: datetime, optional
end_dt: datetime, optional
The last bar date.
:param start_dt: datetime, optional
start_dt: datetime, optional
The first bar date.
:return dict[TradingPair, dict[str, Object]]: OHLCV data
Returns
-------
dict[TradingPair, dict[str, Object]]
A dictionary of OHLCV candles. Each TradingPair instance is
mapped to a list of dictionaries with this structure:
open: float
@@ -830,8 +904,14 @@ class Exchange:
"""
Retrieve current tick data for the given assets
:param assets:
:return:
Parameters
----------
assets: list[TradingPair]
Returns
-------
list[dict[str, float]
"""
pass
@@ -839,7 +919,6 @@ class Exchange:
def get_account(self):
"""
Retrieve the account parameters.
:return:
"""
pass
@@ -848,11 +927,15 @@ class Exchange:
"""
Retrieve the the orderbook for the given trading pair.
:param asset: TradingPair
:param order_type: str
Parameters
----------
asset: TradingPair
order_type: str
The type of orders: bid, ask or all
:param limit
limit: int
:return:
Returns
-------
list[dict[str, float]
"""
pass
+110 -8
View File
@@ -127,7 +127,13 @@ class ExchangeTradingAlgorithmBase(TradingAlgorithm):
"""
Creates a dictionary representing the state of the tracker.
Parameters
----------
start_dt: datetime
end_dt: datetime
Notes
-----
I rewrote this in an attempt to better control the stats.
I don't want things to happen magically through complex logic
pertaining to backtesting.
@@ -296,6 +302,18 @@ class ExchangeTradingAlgorithmLive(ExchangeTradingAlgorithmBase):
self.exchange.minute_reader = BcolzMinuteBarReader(root)
def signal_handler(self, signal, frame):
"""
Handles the keyboard interruption signal.
Parameters
----------
signal
frame
Returns
-------
"""
self.is_running = False
if self._analyze is None:
@@ -384,7 +402,11 @@ class ExchangeTradingAlgorithmLive(ExchangeTradingAlgorithmBase):
"""
We skip the entire performance tracker business and update the
portfolio directly.
:return:
Returns
-------
ExchangePortfolio
"""
# TODO: build cumulative portfolio
return self.perf_tracker.get_portfolio(False)
@@ -450,6 +472,17 @@ class ExchangeTradingAlgorithmLive(ExchangeTradingAlgorithmBase):
)
def add_pnl_stats(self, period_stats):
"""
Save p&l stats.
Parameters
----------
period_stats
Returns
-------
"""
starting = period_stats['starting_cash']
current = period_stats['portfolio_value']
appreciation = (current / starting) - 1
@@ -466,6 +499,17 @@ class ExchangeTradingAlgorithmLive(ExchangeTradingAlgorithmBase):
save_algo_df(self.algo_namespace, 'pnl_stats', self.pnl_stats)
def add_custom_signals_stats(self, period_stats):
"""
Save custom signals stats.
Parameters
----------
period_stats
Returns
-------
"""
log.debug('adding custom signals stats: {}'.format(self.recorded_vars))
df = pd.DataFrame(
data=[self.recorded_vars],
@@ -477,6 +521,17 @@ class ExchangeTradingAlgorithmLive(ExchangeTradingAlgorithmBase):
self.custom_signals_stats)
def add_exposure_stats(self, period_stats):
"""
Save exposure stats.
Parameters
----------
period_stats
Returns
-------
"""
data = dict(
long_exposure=period_stats['long_exposure'],
base_currency=period_stats['ending_cash']
@@ -493,6 +548,14 @@ class ExchangeTradingAlgorithmLive(ExchangeTradingAlgorithmBase):
self.exposure_stats)
def handle_data(self, data):
"""
Wrapper around the handle_data method of each algo.
Parameters
----------
data
"""
if not self.is_running:
return
@@ -619,15 +682,16 @@ class ExchangeTradingAlgorithmLive(ExchangeTradingAlgorithmBase):
The cumulative portfolio does not contain open orders but exchange
portfolios do.
:param asset: TradingPair
:param amount: float
:param limit_price: float
:param stop_price: float
:param style: Style
:return order: Order
Parameters
----------
asset: TradingPair
amount: float
limit_price: float
stop_price: float
style: Style
order: Order
The catalyst order object or None
"""
amount, style = self._calculate_order(asset, amount,
limit_price, stop_price,
style)
@@ -689,15 +753,53 @@ class ExchangeTradingAlgorithmLive(ExchangeTradingAlgorithmBase):
'get_open_orders. Use `asset` instead.')
@api_method
def get_open_orders(self, asset=None):
"""Retrieve all of the current open orders.
Parameters
----------
asset : Asset
If passed and not None, return only the open orders for the given
asset instead of all open orders.
Returns
-------
open_orders : dict[list[Order]] or list[Order]
If no asset is passed this will return a dict mapping Assets
to a list containing all the open orders for the asset.
If an asset is passed then this will return a list of the open
orders for this asset.
"""
return self._get_open_orders(asset)
@api_method
def get_order(self, order_id, exchange_name):
"""Lookup an order based on the order id returned from one of the
order functions.
Parameters
----------
order_id : str
The unique identifier for the order.
Returns
-------
order : Order
The order object.
execution_price: float
The execution price per share of the order
"""
exchange = self.exchanges[exchange_name]
return exchange.get_order(order_id)
@api_method
def cancel_order(self, order_param, exchange_name):
"""Cancel an open order.
Parameters
----------
order_param : str or Order
The order_id or order object to cancel.
"""
exchange = self.exchanges[exchange_name]
order_id = order_param
+18 -10
View File
@@ -39,17 +39,25 @@ class BcolzExchangeBarReader(BcolzMinuteBarReader):
return self._data_frequency
def load_raw_arrays(self, fields, start_dt, end_dt, sids):
"""
Parameters
----------
fields : list of str
'open', 'high', 'low', 'close', or 'volume'
start_dt: Timestamp
Beginning of the window range.
end_dt: Timestamp
End of the window range.
sids : list of int
The asset identifiers in the window.
# if self._data_frequency == 'minute':
# return super(BcolzExchangeBarReader, self) \
# .load_raw_arrays(fields, start_dt, end_dt, sids)
#
# else:
# return self._load_daily_raw_arrays(fields, start_dt, end_dt, sids)
return self._load_raw_arrays(fields, start_dt, end_dt, sids)
def _load_raw_arrays(self, fields, start_dt, end_dt, sids):
Returns
-------
list of np.ndarray
A list with an entry per field of ndarrays with shape
(minutes in range, sids) with a dtype of float64, containing the
values for the respective field over start and end dt range.
"""
start_idx = self._find_position_of_minute(start_dt)
end_idx = self._find_position_of_minute(end_dt)
+101 -56
View File
@@ -59,7 +59,10 @@ class ExchangeBundle:
"""
Get a data writer object, either a new object or from cache
:return: BcolzMinuteBarReader or BcolzDailyBarReader
Returns
-------
BcolzMinuteBarReader | BcolzDailyBarReader
"""
if path is None:
root = get_exchange_folder(self.exchange.name)
@@ -88,7 +91,10 @@ class ExchangeBundle:
"""
Get a data writer object, either a new object or from cache
:return: BcolzMinuteBarWriter or BcolzDailyBarWriter
Returns
-------
BcolzMinuteBarWriter | BcolzDailyBarWriter
"""
root = get_exchange_folder(self.exchange.name)
path = BUNDLE_NAME_TEMPLATE.format(
@@ -144,13 +150,19 @@ class ExchangeBundle:
If the data exists, the chunk ingestion is complete.
If any data is missing we ingest the data.
:param assets: list[TradingPair]
Parameters
----------
assets: list[TradingPair]
The assets is scope.
:param start_dt:
start_dt: datetime
The chunk start date.
:param end_dt:
end_dt: datetime
The chunk end date.
:return: list[TradingPair]
data_frequency: str
Returns
-------
list[TradingPair]
The assets missing from the bundle
"""
reader = self.get_reader(data_frequency)
@@ -164,13 +176,6 @@ class ExchangeBundle:
return missing_assets
def _write(self, data, writer, data_frequency):
"""
Write data to the writer
:param df:
:param writer:
:return:
"""
try:
writer.write(
data=data,
@@ -195,6 +200,20 @@ class ExchangeBundle:
)
def get_calendar_periods_range(self, start_dt, end_dt, data_frequency):
"""
Get a list of dates for the specified range.
Parameters
----------
start_dt: datetime
end_dt: datetime
data_frequency: str
Returns
-------
list[datetime]
"""
return self.calendar.minutes_in_range(start_dt, end_dt) \
if data_frequency == 'minute' \
else self.calendar.sessions_in_range(start_dt, end_dt)
@@ -204,13 +223,14 @@ class ExchangeBundle:
"""
Ingest a DataFrame of OHLCV data for a given market.
:param ohlcv_df:
:param data_frequency:
:param asset:
:param writer:
:param path:
:param empty_rows_behavior:
:return:
Parameters
----------
ohlcv_df: DataFrame
data_frequency: str
asset: TradingPair
writer:
empty_rows_behavior: str
"""
if empty_rows_behavior is not 'ignore':
nan_rows = ohlcv_df[ohlcv_df.isnull().T.any().T].index
@@ -269,14 +289,16 @@ class ExchangeBundle:
"""
Merge a ctable bundle chunk into the main bundle for the exchange.
:param asset: TradingPair
:param data_frequency: str
:param period: str
:param writer:
:param empty_rows_behavior: str
Parameters
----------
asset: TradingPair
data_frequency: str
period: str
writer:
empty_rows_behavior: str
Ensure that the bundle does not have any missing data.
:param cleanup: bool
cleanup: bool
Remove the temp bundle directory after ingestion.
:return:
@@ -331,13 +353,19 @@ class ExchangeBundle:
def get_adj_dates(self, start, end, assets, data_frequency):
"""
Contains a date range to the trading availability of the specified pairs.
Contains a date range to the trading availability of the specified
markets.
:param start:
:param end:
:param assets:
:param data_frequency:
:return:
Parameters
----------
start: datetime
end: datetime
assets: list[TradingPair]
data_frequency: str
Returns
-------
datetime, datetime
"""
earliest_trade = None
last_entry = None
@@ -380,11 +408,17 @@ class ExchangeBundle:
Split a price data request into chunks corresponding to individual
bundles.
:param assets:
:param data_frequency:
:param start_dt:
:param end_dt:
:return:
Parameters
----------
assets: list[TradingPair]
data_frequency: str
start_dt: datetime
end_dt: datetime
Returns
-------
dict[TradingPair, list[dict(str, Object]]]
"""
reader = self.get_reader(data_frequency)
@@ -456,10 +490,12 @@ class ExchangeBundle:
"""
Determine if data is missing from the bundle and attempt to ingest it.
:param assets:
:param start_dt:
:param end_dt:
:return:
Parameters
----------
assets: list[TradingPair]
start_dt: datetime
end_dt: datetime
"""
if start_dt is None:
@@ -538,15 +574,18 @@ class ExchangeBundle:
exclude_symbols=None, start=None, end=None,
show_progress=True, environ=os.environ):
"""
Inject data based on specified parameters.
Parameters
----------
data_frequency: str
include_symbols: str
exclude_symbols: str
start: datetime
end: datetime
show_progress: bool
environ:
:param data_frequency:
:param include_symbols:
:param exclude_symbols:
:param start:
:param end:
:param show_progress:
:param environ:
:return:
"""
assets = self.get_assets(include_symbols, exclude_symbols)
@@ -562,16 +601,22 @@ class ExchangeBundle:
data_frequency, # type: str
algo_end_dt=None # type: Timestamp
):
# type: (...) -> Dict[str, Series]
"""
Retrieve price data history, ingest missing data.
:param assets:
:param end_dt:
:param bar_count:
:param field:
:param data_frequency:
:return:
Parameters
----------
assets: list[TradingPair]
end_dt: datetime
bar_count: int
field: str
data_frequency: str
algo_end_dt: datetime
Returns
-------
Series
"""
try:
series = self.get_history_window_series(
+66 -37
View File
@@ -1,16 +1,3 @@
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import abc
from time import sleep
@@ -238,6 +225,25 @@ class DataPortalExchangeLive(DataPortalExchangeBase):
field,
data_frequency,
ffill=True):
"""
Fetching price history window from the exchange.
Parameters
----------
exchange: Exchange
assets: list[TradingPair]
end_dt: datetime
bar_count: int
frequency: str
field: str
data_frequency: str
ffill: bool
Returns
-------
DataFrame
"""
df = exchange.get_history_window(
assets,
end_dt,
@@ -250,6 +256,22 @@ class DataPortalExchangeLive(DataPortalExchangeBase):
def get_exchange_spot_value(self, exchange, assets, field, dt,
data_frequency):
"""
A spot value for the exchange.
Parameters
----------
exchange: Exchange
assets: list[TradingPair]
field: str
dt: datetime
data_frequency: str
Returns
-------
float
"""
exchange_spot_values = exchange.get_spot_value(
assets, field, dt, data_frequency)
@@ -288,18 +310,21 @@ class DataPortalExchangeBacktest(DataPortalExchangeBase):
"""
Fetching price history window from the exchange bundle.
Using a try... except approach to minimize reads most of the time,
when the data exists.
Parameters
----------
exchange: Exchange
assets: list[TradingPair]
end_dt: datetime
bar_count: int
frequency: str
field: str
data_frequency: str
ffill: bool
Returns
-------
DataFrame
:param exchange:
:param assets:
:param end_dt:
:param bar_count:
:param frequency:
:param field:
:param data_frequency:
:param ffill:
:return:
"""
bundle = self.exchange_bundles[exchange.name] # type: ExchangeBundle
@@ -321,26 +346,30 @@ class DataPortalExchangeBacktest(DataPortalExchangeBase):
return df
def get_exchange_spot_value(self,
exchange, # type: Exchange
assets, # type: List[TradingPair]
field, # type: str
dt, # type: Timestamp
data_frequency # type: str
exchange,
assets,
field,
dt,
data_frequency
):
# type: (...) -> float
"""
A spot value for the exchange bundle. Try to ingest data if not in
the bundle.
:param exchange:
:param assets:
:param field:
:param dt:
:param data_frequency:
:return:
Parameters
----------
exchange: Exchange
assets: list[TradingPair]
field: str
dt: datetime
data_frequency: str
Returns
-------
float
"""
bundle = self.exchange_bundles[exchange.name]
if data_frequency == 'daily':
dt = dt.floor('1D')
else:
+40 -12
View File
@@ -4,9 +4,16 @@ from catalyst.finance.execution import LimitOrder, StopOrder, StopLimitOrder
class ExchangeLimitOrder(LimitOrder):
def get_limit_price(self, is_buy):
"""
We may be trading Satoshis with 8 decimals, we cannot round numbers
:param is_buy:
:return:
We may be trading Satoshis with 8 decimals, we cannot round numbers.
Parameters
----------
is_buy: bool
Returns
-------
float
"""
return self.limit_price
@@ -14,9 +21,16 @@ class ExchangeLimitOrder(LimitOrder):
class ExchangeStopOrder(StopOrder):
def get_stop_price(self, is_buy):
"""
We may be trading Satoshis with 8 decimals, we cannot round numbers
:param is_buy:
:return:
We may be trading Satoshis with 8 decimals, we cannot round numbers.
Parameters
----------
is_buy: bool
Returns
-------
float
"""
return self.stop_price
@@ -24,16 +38,30 @@ class ExchangeStopOrder(StopOrder):
class ExchangeStopLimitOrder(StopLimitOrder):
def get_limit_price(self, is_buy):
"""
We may be trading Satoshis with 8 decimals, we cannot round numbers
:param is_buy:
:return:
We may be trading Satoshis with 8 decimals, we cannot round numbers.
Parameters
----------
is_buy: bool
Returns
-------
float
"""
return self.limit_price
def get_stop_price(self, is_buy):
"""
We may be trading Satoshis with 8 decimals, we cannot round numbers
:param is_buy:
:return:
We may be trading Satoshis with 8 decimals, we cannot round numbers.
Parameters
----------
is_buy: bool
Returns
-------
float
"""
return self.stop_price
+31 -3
View File
@@ -3,6 +3,7 @@ from logbook import Logger
from catalyst.constants import LOG_LEVEL
from catalyst.protocol import Portfolio, Positions, Position
from catalyst.utils.deprecate import deprecated
log = Logger('ExchangePortfolio', level=LOG_LEVEL)
@@ -29,10 +30,15 @@ class ExchangePortfolio(Portfolio):
self.positions_value = 0.0
self.open_orders = dict()
def calculate_pnl(self):
log.debug('calculating pnl')
def create_order(self, order):
"""
Create an open order and store in memory.
Parameters
----------
order: Order
"""
log.debug('creating order {}'.format(order.id))
self.open_orders[order.id] = order
@@ -47,6 +53,18 @@ class ExchangePortfolio(Portfolio):
log.debug('open order added to portfolio')
def execute_order(self, order, transaction):
"""
Update the open orders and positions to apply an executed order.
Unlike with backtesting, we do not need to add slippage and fees.
The executed price includes transaction fees.
Parameters
----------
order: Order
transaction: Transaction
"""
log.debug('executing order {}'.format(order.id))
del self.open_orders[order.id]
@@ -71,7 +89,9 @@ class ExchangePortfolio(Portfolio):
log.debug('updated portfolio with executed order')
@deprecated
def execute_transaction(self, transaction):
# TODO: almost duplicate of execute_order. Not sure why Poloniex needs this.
log.debug('executing transaction {}'.format(transaction.order_id))
order_position = self.positions[transaction.asset] \
@@ -96,6 +116,14 @@ class ExchangePortfolio(Portfolio):
log.debug('updated portfolio with executed order')
def remove_order(self, order):
"""
Removing an open order.
Parameters
----------
order: Order
"""
log.info('removing cancelled order {}'.format(order.id))
del self.open_orders[order.id]
+20 -9
View File
@@ -2,12 +2,11 @@ import json
import os
import pickle
import re
from catalyst.assets._assets import TradingPair
from six.moves.urllib import request
from datetime import date, datetime
import pandas as pd
from catalyst.assets._assets import TradingPair
from six.moves.urllib import request
from catalyst.exchange.exchange_errors import ExchangeSymbolsNotFound, \
InvalidHistoryFrequencyError, InvalidHistoryFrequencyAlias
@@ -22,9 +21,15 @@ def get_exchange_folder(exchange_name, environ=None):
"""
The root path of an exchange folder.
:param exchange_name:
:param environ:
:return:
Parameters
----------
exchange_name: str
environ:
Returns
-------
str
"""
if not environ:
environ = os.environ
@@ -40,9 +45,15 @@ def get_exchange_symbols_filename(exchange_name, environ=None):
"""
The absolute path of the exchange's symbol.json file.
:param exchange_name:
:param environ:
:return:
Parameters
----------
exchange_name:
environ:
Returns
-------
str
"""
exchange_folder = get_exchange_folder(exchange_name, environ)
return os.path.join(exchange_folder, 'symbols.json')