Commit 0a70592a authored by ZY.Li's avatar ZY.Li
Browse files

添加系统默认的SMA策略

parent cd429752
using System;
using System.Drawing;
using SmartQuant;
using QuantBox;
using NLog;
using SmartQuant.Indicators;
using SmartQuant.Optimization;
namespace OpenQuant
{
public class MyStrategy : InstrumentStrategy
{
private SMA sma1;
private SMA sma2;
private bool entryEnabled = true;
private int OCACount = 0;
private Order marketOrder;
private Order limitOrder;
private Order stopOrder;
[Parameter]
public double MoneyForInstrument = 100000;
[Parameter]
[OptimizationParameter(100, 2100, 500)]
public int Qty = 100;
[Parameter]
[OptimizationParameter(5, 25)]
public int Length1 = 14;
[Parameter]
[OptimizationParameter(26, 60)]
public int Length2 = 50;
public double StopOCALevel = 0.98;
public double LimitOCALevel = 1.05;
[OptimizationParameter(0.05, 0.10, 0.05)]
public double StopLevel = 0.05;
public StopType StopType = StopType.Trailing;
public StopMode StopMode = StopMode.Percent;
public bool CrossoverExitEnabled = true;
public bool OCAExitEnabled = true;
public bool StopExitEnabled = true;
public MyStrategy(Framework framework, string name)
: base(framework, name)
{
}
protected override void OnFill(Fill fill)
protected override void OnStrategyStart()
{
// Add money for current trading instrument's portfolio.
Portfolio.Account.Deposit(Clock.DateTime, MoneyForInstrument, CurrencyId.USD, "Initial allocation");
// Set up indicators.
sma1 = new SMA(Bars, Length1);
sma2 = new SMA(Bars, Length2);
Group("Bars", GroupField.Pad, 0);
Group("Fills", GroupField.Pad, 0);
Group("Equity", GroupField.Pad, 1);
Group("SMA1", GroupField.Pad, 0);
Group("SMA1", GroupField.Color, Color.Green);
Group("SMA2", GroupField.Pad, 0);
Group("SMA2", GroupField.Color, Color.Red);
// Create log monitor groups.
Group("Close", GroupField.LogName, "Close");
Group("Close", GroupField.StrategyName, "MyStrategy");
Group("Close", GroupField.Symbol, Instrument.Symbol);
Group("Open", GroupField.LogName, "Open");
Group("Open", GroupField.StrategyName, "MyStrategy");
Group("Open", GroupField.Symbol, Instrument.Symbol);
Group("Position", GroupField.LogName, "Position");
Group("Position", GroupField.StrategyName, "MyStrategy");
Group("Position", GroupField.Symbol, Instrument.Symbol);
}
protected override void OnStrategyStart()
protected override void OnBar(Instrument instrument, Bar bar)
{
Bars.Add(bar);
// Log open close and position info to Strategy Monitor.
Log(bar.Close, "Close");
Log(bar.Open, "Open");
if (HasPosition(instrument))
Log(Position.Side.ToString(), "Position");
else
Log("None", "Position");
// Log bars.
Log(bar, "Bars");
if (sma1.Count == 0 || sma2.Count == 0)
return;
// Log sma.
Log(sma1.Last, "SMA1");
Log(sma2.Last, "SMA2");
// Update performance.
Portfolio.Performance.Update();
// Log equity.
Log(Portfolio.Value, "Equity");
// Does the fast average cross over the slow average? If so, time to buy long.
Cross cross = sma1.Crosses(sma2, bar.DateTime);
// We only allow one active position at a time.
if (entryEnabled)
{
// If price trend is moving upward, open a long position using a market order, and send it in.
if (cross == Cross.Above)
{
marketOrder = BuyOrder(instrument, Qty, "Entry");
Send(marketOrder);
// If one cancels all exit method is desired, we
// also issue a limit (profit target) order, and
// a stop loss order in case the breakout fails.
// The OCA exit method uses a real stop loss order.
// The Stop exit method uses a stop indicator.
// Use either the OCA or Stop method, not both at once.
if (OCAExitEnabled)
{
// Create and send a profit limit order.
double profitTarget = LimitOCALevel * bar.Close;
limitOrder = SellLimitOrder(instrument, Qty, profitTarget, "Limit OCA " + OCACount);
limitOrder.OCA = "OCA " + Instrument.Symbol + " " + OCACount;
Send(limitOrder);
// Create and send a stop loss order.
double lossTarget = StopOCALevel * bar.Close;
stopOrder = SellStopOrder(instrument, Qty, lossTarget, "Stop OCA " + OCACount);
stopOrder.OCA = "OCA " + Instrument.Symbol + " " + OCACount;
Send(stopOrder);
// Bump the OCA count to make OCA group strings unique.
OCACount++;
}
entryEnabled = false;
}
}
// Else if entry is disabled on this bar, we have an open position.
else
{
// If we are using the crossover exit, and if the fast
// average just crossed below the slow average, issue a
// market order to close the existing position.
if (CrossoverExitEnabled)
{
if (cross == Cross.Below)
{
marketOrder = SellOrder(instrument, Qty, "Crossover Exit");
Send(marketOrder);
}
}
}
}
protected override void OnBar(Instrument instrument, Bar bar)
protected override void OnPositionOpened(Position position)
{
// If we want to exit trades using the Stop method, set a
// a trailing stop indicator when the position is
// first opened. The stop indicator is not a stop loss
// order that can be executed by a broker. Instead, the stop
// just fires the OnStopExecuted event when it it triggered.
if (StopExitEnabled)
AddStop(new Stop(this, position, StopLevel, StopType, StopMode));
}
protected override void OnPositionClosed(Position position)
{
// When a position is closed, cancel the limit and stop
// orders that might be associated with this position.
// But only cancel if the order has not been filled or
// not been cancelled already.
if (OCAExitEnabled && !(limitOrder.IsFilled || limitOrder.IsCancelled))
Cancel(limitOrder);
// Allow entries once again, since our position is closed.
entryEnabled = true;
}
protected override void OnFill(Fill fill)
{
// Add fill to group.
Log(fill, "Fills");
}
protected override void OnTrade(Instrument instrument, Trade trade)
protected override void OnStopExecuted(Stop stop)
{
base.OnTrade(instrument, trade);
// If our trailing stop indicator was executed,
// issue a market sell order to close the position.
marketOrder = SellOrder(Instrument, Qty, "Stop Exit");
Send(marketOrder);
}
}
}
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment