Open Source Build - Big Bar Robot - JOIN IN
Open Source Build - Big Bar Robot - JOIN IN
29 Oct 2013, 01:49
Ok... I am going to try something different see if people get on board.
I am still learning C# and need to solve many problems to learn.. so I decided to post some open source projects to get people involved share the code openly.
So the first project is a robot that enters trades when the last bar in the timeframe is x times larger than the last y bars in the timeframe above.
That is if the last 15 min bar has a range that is greater than the last 4 30min bars posted and the direction is up it buys if its down it sells. The robot compares all timeframes and the higher the timeframe (e.g 1hr > the last 5 4h bars) would be a stronger signal and the volume would be higher..
At this point I am stuck on using lists.. so anyone wants to help I will post the version as we go..
// ------------------------------------------------------------------------------------------------- // // // // // ------------------------------------------------------------------------------------------------- using System; using System.Linq; using System.Collections.Generic; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.API.Requests; using cAlgo.Indicators; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.CentralStandardTime)] public class BigBarRobot : Robot { [Parameter(DefaultValue = "BigBarRobot")] public string LabelName { get; set; } [Parameter("Source")] // CLOSE, HIGH, LOW... public DataSeries Source { get; set; } [Parameter("Periods", DefaultValue = 14)] public int Periods { get; set; } [Parameter("Volume", DefaultValue = 10000, MinValue = 1000)] public int Volume { get; set; } protected int PositionsCount { //Counts the positions made by this Robot get { return Account.Positions.Count(thisRobotsCurrPos => thisRobotsCurrPos.Label == LabelName); } } //variable set outside onBar() to preserve the value on next call //ERROR HANDLER private bool LastOrderSuccessful = true; //POSITIONS private readonly List<Position> _OpenPositions = new List<Position>(); private Position LastBuyPositionOpened = null; //TRIGGER private int TriggerLevel = 1; //Variables MarketSeries Data MarketSeries min5; MarketSeries min15; MarketSeries min30; MarketSeries hour1; MarketSeries hour4; //Cummulative array of marketSeries Data private readonly List<double> _Cumm5 = new List<double>(10); private readonly List<double> _Cumm15 = new List<double>(10); private readonly List<double> _Cumm30 = new List<double>(10); private readonly List<double> _Cumm1h = new List<double>(10); private readonly List<double> _Cumm4h = new List<double>(10); //Initialising Robot the first time protected override void OnStart() { //Intialise Variables min5 = MarketData.GetSeries(Symbol.Code, TimeFrame.Minute5); min15 = MarketData.GetSeries(Symbol.Code, TimeFrame.Minute15); min30 = MarketData.GetSeries(Symbol.Code, TimeFrame.Minute30); hour1 = MarketData.GetSeries(Symbol.Code, TimeFrame.Hour); hour4 = MarketData.GetSeries(Symbol.Code, TimeFrame.Hour4); //Initialise the Cummulative Arrays to 0 Print("List initialised"); //_Cumm15[0] = 0; //_Cumm30[0] = 0; //_Cumm1h[0] = 0; //_Cumm4h[0] = 0; } //************************* //called on each onBar() or onTick() //************************* protected override void OnBar() { //-------------------------- //Do nothing if system is busy //-------------------------- if (Trade.IsExecuting) return; var lastIndex = MarketSeries.Close.Count - 1; // Get Current ranges double CurrRng5 = min5.High.LastValue - min5.Low.LastValue; double CurrRng15 = min15.High.LastValue - min15.Low.LastValue; double CurrRng30 = min30.High.LastValue - min30.Low.LastValue; double CurrRng1h = hour1.High.LastValue - hour1.Low.LastValue; double CurrRng4h = hour4.High.LastValue - hour4.Low.LastValue; // Print("h {0}", min5.High[min5.High.Count]); // Print("i {0}", min5.High[min5.High.Count - 1]); //update array of cummulative ranges of last 30 bars // Print("Val H {0}", min5.High[min5.High.Count - 1]); // Print("Val H {0}", min5.High[min5.High.Count - 2]); //Print("Val H {0}", min5.High[lastIndex - 1]); //Print("Val H {0}", min5.High[lastIndex]); for (int i = MarketSeries.High.Count - 1; i > MarketSeries.High.Count - 11; i--) { Print("Val H {0}", min5.High[i]); Print("Val Cnt {0}", MarketSeries.High.Count); // _Cumm5[i - 1] = min5.High[min5.High.Count - i] - min5.Low[min5.Low.Count - i] + _Cumm5[i]; //Print("Val H {0}", min5.High[min5.High.Count - i]); // Print("{0}", _Cumm5.Count); // double H = min5.High[i]; // double L = min5.Low[i]; // double Ct = min5.High.Sum(i); // Print("Val L{0}", min5.Low[min5.Low.Count - i]); // _Cumm5.Add(H - L); //Print("Cumm: {0}", _Cumm5[i].ToString()); // Print("H {0}", H); // Print("L {0}", L); // Print("Rng {0}", H - L); } Print("ENDDDD"); } //check if last 5 is greater than x periods of 15 //Start Functions here ... /// /// Create Conditional Buy Order /// private void ConditionalBuy() { LastOrderSuccessful = true; //Buy ONCE at each trigger level when the Buy price is under the trigger price if (LastOrderSuccessful) { Print("CO() ***** CONDITIONAL ORDER SUCCESSFUL!! *****"); } } /// /// Close all position in list of specified type /// private void CloseAllPositions(string PosType) { if (PositionsCount == 0) return; if (PosType == "Buy") { foreach (Position position in _OpenPositions) { if (position.TradeType == TradeType.Buy) { ClosePosition(position); } } } } /// /// Add newly opened position to list /// /// protected override void OnPositionOpened(Position openedPosition) { //Add to list if (openedPosition == null) return; _OpenPositions.Add(openedPosition); if (openedPosition.TradeType == TradeType.Buy) LastBuyPositionOpened = openedPosition; } /// /// Remove closed position from list /// /// protected override void OnPositionClosed(Position closedPosition) { if (closedPosition == null) return; if (_OpenPositions.Contains(closedPosition)) { _OpenPositions.Remove(closedPosition); } } /// /// Trade Statistics /// private void TradeStats(string Trade_Type) { double TotalPipProfit = 0; double TotalDollarProfit = 0; double AvgEntryPrice = 0; double TotalCommissions = 0; double AvgClosePrice = 0; double LastTradePrice = 0; double LastTradeProfit = 0; int ActivePositions = 0; if (PositionsCount == 0) { Print("Exception - No Orders"); return; } if (Trade_Type == "Buy") { // foreach (var pos in Account.Positions).where(thisRobotsCurrPos => thisRobotsCurrPos.Label == LabelName); foreach (Position position in _OpenPositions) { if (position.TradeType == TradeType.Buy) { TotalPipProfit += position.Pips; TotalDollarProfit += position.NetProfit; AvgEntryPrice += position.EntryPrice; TotalCommissions += position.Commissions; ActivePositions++; } } } AvgEntryPrice = Math.Round((AvgEntryPrice / ActivePositions), Symbol.Digits); Print("*********************************{0}", Environment.NewLine); Print("Number of Active Buy Orders = {0}", ActivePositions); Print("Total PIP Profits on all Buy Orders = {0}", TotalPipProfit); Print("Total $$ Profits on all Buy Orders = {0}", TotalDollarProfit); Print("Total Commissions Paid on Buy Orders = {0}", TotalCommissions); Print("Average Entry on Buy Orders = {0}", AvgEntryPrice); Print("Last Position opened is making {0} (PIPS)", LastBuyPositionOpened.Pips); Print("*********************************{0}", Environment.NewLine); } /// /// Create Market Buy Order, Sets New Target and Sleeps Agent /// private void Buy() { Trade.CreateBuyMarketOrder(Symbol, Volume); //Reset Trigger and send agent to sleep if (LastOrderSuccessful) Print("BO() Buy Order Successful"); } /// /// Close Single Position /// /// private void ClosePosition(Position pos) { if (pos == null) return; Trade.Close(pos); } /// /// Error Handler /// protected override void OnError(Error err) { // Print the error to the log switch (err.Code) { case ErrorCode.BadVolume: Print("Bad Volume"); LastOrderSuccessful = false; break; case ErrorCode.TechnicalError: LastOrderSuccessful = false; Print("Trade Unsuccessful - Technical Error TradeSuccessful = {0}", LastOrderSuccessful); break; case ErrorCode.NoMoney: Print("No Money"); LastOrderSuccessful = false; break; case ErrorCode.Disconnected: Print("Disconnected"); LastOrderSuccessful = false; break; case ErrorCode.MarketClosed: Print("Market Closed"); LastOrderSuccessful = false; break; } } public void DrawLine(int TriggerLevel) { int lastIndex = MarketSeries.OpenTime.Count - 1; DateTime now = MarketSeries.OpenTime[lastIndex]; DateTime end = now.AddHours(5); Colors color; switch (1) { case 1: color = Colors.Red; break; case 2: color = Colors.Green; break; case 3: color = Colors.Blue; break; default: color = Colors.MediumPurple; break; } //Print("DL() Preparing to Draw Line @ TriggerPrice = {0} from Now:{1} to End {2}", CurrTriggerLevel, now, end); // ChartObjects.DrawLine("Trigger", now, CurrTriggerLevel, end, CurrTriggerLevel, color); } //end class SmartBuy Robot } // end namespace }
Replies
jhtrader
29 Oct 2013, 22:31
RE:
Kate said:
Since you try to save last 11 values you can use array instead of list. I guess something like this:
private const int BarsCount = 11; private readonly double[] _Cumm5 = new double[BarsCount]; ... var index = min5.High.Count - 1; for (int i = 0; i < BarsCount; i++) { _Cumm5[i] = _Cumm5[i] + min5.High[index - i] - min5.Low[index - i]; }
Thanks.. I guess the benefit is that it is less resource intensive right? I will switch it over..since I dont need to dynamically resize the array. I used lists to get more familiar with them..
jhtrader
30 Oct 2013, 17:22
Arrays works fine but...
Hi,
I cannot pass in the parameter Periods when initialising the array
[Parameter("Periods", DefaultValue = 10)]
public int Periods { get; set; }
private const int blah = 10;
private readonly double[] _Cumm2 = new double[blah];
Any idea why??? I tried to set blah to Periods and I tried to put Periods directly but the compiler saw through my wicked scheme and didnt allow it.. .
Can I make the list non resisable and the values on the next bar just overrite the previous and still use lists.. ?? Currently if I want to use lists I have to clear the list at the beginning of the next bar. I cant see any real perf diff in arrays and lists.. have you had any experience with the performance diff?
hichem
30 Oct 2013, 17:41
RE: Arrays works fine but...
That will not work like that. The Parameter attribute will set the Periods variable after the creation of the _Cumm2 variable.
You should initialize the _Cumm2 variable in the Start() method of the robot is you want to use a value set by a parameter attribute.
jhtrader said:
Hi,
I cannot pass in the parameter Periods when initialising the array
[Parameter("Periods", DefaultValue = 10)]
public int Periods { get; set; }private const int blah = 10;
private readonly double[] _Cumm2 = new double[blah];Any idea why??? I tried to set blah to Periods and I tried to put Periods directly but the compiler saw through my wicked scheme and didnt allow it.. .
Can I make the list non resisable and the values on the next bar just overrite the previous and still use lists.. ?? Currently if I want to use lists I have to clear the list at the beginning of the next bar. I cant see any real perf diff in arrays and lists.. have you had any experience with the performance diff?
@hichem
jeex
03 Nov 2013, 16:55
Interesting plan
Interesting approach of prize trading. But why make the code so complex, if the strategyis so simple? I have a few questions:
What is the exit strategy?
What are TakeProfit and StopLoss based upon?
Do you have a fail safe strategy? ie. MacD or SMA?
With the simple piece of code for only the m15 bar, results are sort of promising.
int dezeBar = MarketSeries.Open.Count - 1; int m30bar = m30.Open.Count - 1; int shift = 0; // breedte vorige bar; double dif = (MarketSeries.Close[dezeBar - 1] - MarketSeries.Open[dezeBar - 1]); double dif1 = Math.Abs(m30.Close[m30bar - 2] - m30.Open[m30bar - 2]); double dif2 = Math.Abs(m30.Close[m30bar - 3] - m30.Open[m30bar - 3]); double dif3 = Math.Abs(m30.Close[m30bar - 4] - m30.Open[m30bar - 4]); double dif4 = Math.Abs(m30.Close[m30bar - 5] - m30.Open[m30bar - 5]); MarketOrderRequest ma; if (dif >= 0) { // onderzoek long if (dif > dif1 && dif > dif2 && dif > dif3 && dif > dif4 && sma20.Result.IsRising()) { Print("open een trade LONG op " + mooieTijd(MarketSeries.OpenTime.LastValue)); ma = new MarketOrderRequest(TradeType.Buy, 1000); ma.Label = _LABEL; ma.StopLossPips = SL; ma.TakeProfitPips = TP; ma.SlippagePips = 1; Trade.Send(ma); } } else { // onderzoek short dif = dif * (-1); if (dif > dif1 && dif > dif2 && dif > dif3 && dif > dif4 && sma20.Result.IsFalling()) { Print("open een trade LONG op " + mooieTijd(MarketSeries.OpenTime.LastValue)); ma = new MarketOrderRequest(TradeType.Sell, 1000); ma.Label = _LABEL; ma.StopLossPips = SL; ma.TakeProfitPips = TP; ma.SlippagePips = 1; Trade.Send(ma); } }
@jeex
Kate
29 Oct 2013, 10:44
Since you try to save last 11 values you can use array instead of list. I guess something like this:
@Kate