/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* 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.
*/
using Python.Runtime;
using QuantConnect.Orders;
using QuantConnect.Orders.Fills;
using QuantConnect.Securities;
using System.Collections.Generic;
namespace QuantConnect.Python
{
///
/// Wraps a object that represents a model that simulates order fill events
///
public class FillModelPythonWrapper : FillModel
{
private readonly dynamic _model;
///
/// Constructor for initialising the class with wrapped object
///
/// Represents a model that simulates order fill events
public FillModelPythonWrapper(PyObject model)
{
_model = model;
using (Py.GIL())
{
_model.SetPythonWrapper(this);
}
}
///
/// Return an order event with the fill details
///
/// A parameters object containing the security and order
/// Order fill information detailing the average price and quantity filled.
public override Fill Fill(FillModelParameters parameters)
{
Parameters = parameters;
using (Py.GIL())
{
return (_model.Fill(parameters) as PyObject).GetAndDispose();
}
}
///
/// Limit Fill Model. Return an order event with the fill details.
///
/// Stock Object to use to help model limit fill
/// Order to fill. Alter the values directly if filled.
/// Order fill information detailing the average price and quantity filled.
public override OrderEvent LimitFill(Security asset, LimitOrder order)
{
using (Py.GIL())
{
return (_model.LimitFill(asset, order) as PyObject).GetAndDispose();
}
}
///
/// Limit if Touched Fill Model. Return an order event with the fill details.
///
/// Asset we're trading this order
/// Order to Check, return filled if true
/// Order fill information detailing the average price and quantity filled.
public override OrderEvent LimitIfTouchedFill(Security asset, LimitIfTouchedOrder order)
{
using (Py.GIL())
{
return (_model.LimitIfTouchedFill(asset, order) as PyObject).GetAndDispose();
}
}
///
/// Model the slippage on a market order: fixed percentage of order price
///
/// Asset we're trading this order
/// Order to update
/// Order fill information detailing the average price and quantity filled.
public override OrderEvent MarketFill(Security asset, MarketOrder order)
{
using (Py.GIL())
{
return (_model.MarketFill(asset, order) as PyObject).GetAndDispose();
}
}
///
/// Market on Close Fill Model. Return an order event with the fill details
///
/// Asset we're trading with this order
/// Order to be filled
/// Order fill information detailing the average price and quantity filled.
public override OrderEvent MarketOnCloseFill(Security asset, MarketOnCloseOrder order)
{
using (Py.GIL())
{
return (_model.MarketOnCloseFill(asset, order) as PyObject).GetAndDispose();
}
}
///
/// Market on Open Fill Model. Return an order event with the fill details
///
/// Asset we're trading with this order
/// Order to be filled
/// Order fill information detailing the average price and quantity filled.
public override OrderEvent MarketOnOpenFill(Security asset, MarketOnOpenOrder order)
{
using (Py.GIL())
{
return (_model.MarketOnOpenFill(asset, order) as PyObject).GetAndDispose();
}
}
///
/// Stop Limit Fill Model. Return an order event with the fill details.
///
/// Asset we're trading this order
/// Stop Limit Order to Check, return filled if true
/// Order fill information detailing the average price and quantity filled.
public override OrderEvent StopLimitFill(Security asset, StopLimitOrder order)
{
using (Py.GIL())
{
return (_model.StopLimitFill(asset, order) as PyObject).GetAndDispose();
}
}
///
/// Stop Market Fill Model. Return an order event with the fill details.
///
/// Asset we're trading this order
/// Trailing Stop Order to check, return filled if true
/// Order fill information detailing the average price and quantity filled.
public override OrderEvent StopMarketFill(Security asset, StopMarketOrder order)
{
using (Py.GIL())
{
return (_model.StopMarketFill(asset, order) as PyObject).GetAndDispose();
}
}
///
/// Trailing Stop Fill Model. Return an order event with the fill details.
///
/// Asset we're trading this order
/// Stop Order to Check, return filled if true
/// Order fill information detailing the average price and quantity filled.
public override OrderEvent TrailingStopFill(Security asset, TrailingStopOrder order)
{
using (Py.GIL())
{
return (_model.TrailingStopFill(asset, order) as PyObject).GetAndDispose();
}
}
///
/// Default combo market fill model for the base security class. Fills at the last traded price for each leg.
///
/// Order to fill
/// Fill parameters for the order
/// Order fill information detailing the average price and quantity filled for each leg. If any of the fills fails, none of the orders will be filled and the returned list will be empty
public override List ComboMarketFill(Order order, FillModelParameters parameters)
{
using (Py.GIL())
{
return (_model.ComboMarketFill(order, parameters) as PyObject).GetAndDispose>();
}
}
///
/// Default combo limit fill model for the base security class. Fills at the sum of prices for the assets of every leg.
///
/// Order to fill
/// Fill parameters for the order
/// Order fill information detailing the average price and quantity filled for each leg. If any of the fills fails, none of the orders will be filled and the returned list will be empty
public override List ComboLimitFill(Order order, FillModelParameters parameters)
{
using (Py.GIL())
{
return (_model.ComboLimitFill(order, parameters) as PyObject).GetAndDispose>();
}
}
///
/// Default combo limit fill model for the base security class. Fills at the limit price for each leg
///
/// Order to fill
/// Fill parameters for the order
/// Order fill information detailing the average price and quantity filled for each leg. If any of the fills fails, none of the orders will be filled and the returned list will be empty
public override List ComboLegLimitFill(Order order, FillModelParameters parameters)
{
using (Py.GIL())
{
return (_model.ComboLegLimitFill(order, parameters) as PyObject).GetAndDispose>();
}
}
///
/// Get the minimum and maximum price for this security in the last bar:
///
/// Security asset we're checking
/// The order direction, decides whether to pick bid or ask
protected override Prices GetPrices(Security asset, OrderDirection direction)
{
using (Py.GIL())
{
return (_model.GetPrices(asset, direction) as PyObject).GetAndDispose();
}
}
///
/// Get the minimum and maximum price for this security in the last bar:
///
/// Security asset we're checking
/// The order direction, decides whether to pick bid or ask
/// This method was implemented temporarily to help the refactoring of fill models (GH #4567)
internal Prices GetPricesInternal(Security asset, OrderDirection direction)
{
return GetPrices(asset, direction);
}
}
}