Jump to content
Medved Trader Forums

how to test for a particular increase after a buy signal


Recommended Posts

I am new to paintbars and not fluent in C#.  I want to use them to do some simple backtesting.  My plan is to use the advanced editor to define the buy point using various indicators and then check the following candles to determine when the price has changed by a specified amount, say 1 %.  I can't get the later candles to know the buy price.  I think it must involve the "state keeping", but I don't understand what those terms do.  Can someone suggest how to save a variable value so that it can be used for comparison in later candles?

Thanks

Link to post
Share on other sites

Yes, you would want to store the "buy price" in the state object, and then compare against that. Here is an example. 

NOTE: I am using the BuyPrice to both keep track of the buy price as well as determine. if buy has occurred. If BuyPrice is set (not zero), then it has occured, otherwise not.

for the example, am using a simple calculation for determining an entry - when the price hits the day high to buy, when it pulls back from the high 1% to sell. 

Most of the state machinery is default added stuff. I highlighted the 2 lines that were added to it. 

public void MainCalculation()
{
    // if Buy has not yet occurred, then check for a BUY condition:
    if (CurrentState.BuyPrice == 0 && Close >= SymbolData.High)
    {
        // BUY
        CurrentState.BuyPrice = Close;
        
        SetColorAndShape(Color.Green, PBShape.ArrowUp);
        TriggerAlert();
        SetScanResult("BUY");
    }
    else if (CurrentState.BuyPrice > 0 && Close  < (SymbolData.High * 0.99)) // Check if the price dropped to 99% of the high
    {
        // SELL
        CurrentState.BuyPrice = 0;
        SetColorAndShape(Color.Green, PBShape.ArrowDn);
        TriggerAlert();
        SetScanResult("SELL");
    }

}

/// <summary>
/// Is called at start of paintbar calculation, should be used to initialize anything needed for the paintbar
/// </summary>
private void PaintbarInitialize()
{
    CurrentState.BuyPrice = 0;
}

/// <summary>
/// Holds paintbar state - fill with variables needed to be preserved for next paintbar calc
/// </summary>
private struct PaintbarState
{
    public Double BuyPrice;
}

/// <summary>
/// Holds current PB state - use to calc PB, changes to it carry over to next PB calc
/// </summary>
private PaintbarState CurrentState;

/// <summary>
/// Holds saved PB state - internal
/// </summary>
private PaintbarState SavedState;

/// <summary>
/// Is called at start of paintbar calculation, should be used to clear the paintbar state
/// </summary>
private void PaintbarClearState()
{
    CurrentState = new PaintbarState();
}

/// <summary>
/// Saves paintbar state (called internally).
/// </summary>
private void PaintbarSaveState()
{
    SavedState = CurrentState;
}

/// <summary>
/// Restores paintbar state (called internally).
/// </summary>
private void PaintbarRestoreState()
{
    CurrentState = SavedState;
}
Link to post
Share on other sites

Thanks for the quick response.  I have run your code and it seems to work but I don't understand all the details.  How can Close be greater than SymbolData.High?  Is there a list somewhere of the various names of variables available (like SymbolData, close, etc) and to which candles they apply?  Also it seems that after each SELL I could compute the gain or loss, add it to a running total and have a complete backtest.  Comments?

Link to post
Share on other sites

note that I am using >= not just >. That's just in case there are floating point number differences. 

the auto complete in the advanced editor shows various values available

In Simple mode, we show everything available in the dropdown lists. 

stuff in "SymbolData" is NOT for the specific candle. It is the current data as shown in the portfolio.  So SymbolData.high is the high for the current day, even if currently processing a candle 20 days back. So if you need to have the code check high for the day the candle is on, you would have to reference that as part of the "Horizontal Line" indicator

Link to post
Share on other sites

Things are progressing.  I would like to require several conditions to exist before placing a paintbar such as MACDh crossing 0 and CCI >0. I have tried to use the If(Any...) command you describe in Advanced Looping to check for a crossing in an earlier bar.  But when I do, I get compile errors about integers and double.  Are there some declarations I need to make?



 

Error Code:  Compile Error at (38,229): Error# CS1593: Delegate 'System.Func<double,bool>' does not take 2 arguments
Compile Error at (57,229): Error# CS1502: The best overloaded method match for 'MT.Charting.PaintbarBase.IndexedPropertyDouble.this[int]' has some invalid arguments
Compile Error at (76,229): Error# CS1503: Argument 1: cannot convert from 'double' to 'int'
Compile Error at (79,229): Error# CS1061: 'double' does not contain a definition for 'CrossesUp' and no extension method 'CrossesUp' accepting a first argument of type 'double' could be found (are you missing a using directive or an assembly reference?)

Thanks for the help.

Link to post
Share on other sites

Ok first of all you should not have the finishing ; in the if line above. If you have that ;, it would just stop the if there and always execute the bracketed code.

Second: gratz :) You found a bug in MT's C# preprocessing of the Any function.

It was converting the if statement above to:


if ((MACDHIST_Histogram[0] >= 0.0) && CCI_Line.Any(0, 4, (i, x) => { return (CCI_Line[ i ].CrossesUp(-100,0)); }))

and it should have been

if ((MACDHIST_Histogram[0] >= 0.0) && CCI_Line.Any(0, 4, (i, x) => { return (CCI_Line.CrossesUp(-100,0)); }))

and third - there is more wrong with that line. It really should be:

if ((MACDHIST_Histogram[0] >= 0.0) && CCI_Line.Any(0, 4, (i, x) => { return (CCI_Line.CrossesUp(-100,i)); }))

but this will take some more fixin'. Doing that now.

 

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...